An audio player for macOS 10.8 and newer. https://kode54.net/cog
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

746 lines
24KB

  1. /* _______ ____ __ ___ ___
  2. * \ _ \ \ / \ / \ \ / / ' ' '
  3. * | | \ \ | | || | \/ | . .
  4. * | | | | | | || ||\ /| |
  5. * | | | | | | || || \/ | | ' ' '
  6. * | | | | | | || || | | . .
  7. * | |_/ / \ \__// || | |
  8. * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
  9. * / \
  10. * / . \
  11. * readpsm.c - Code to read an old Protracker / / \ \
  12. * Studio module from an open file. | < / \_
  13. * | \/ /\ /
  14. * By Christopher Snowhill. \_ / > /
  15. * | \ / /
  16. * | ' /
  17. * \__/
  18. */
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <math.h>
  22. #include "dumb.h"
  23. #include "internal/it.h"
  24. static int psm_sample_compare(const void *e1, const void *e2) {
  25. const unsigned char *pa = e1;
  26. const unsigned char *pb = e2;
  27. int a = pa[37] | (pa[38] << 8) | (pa[39] << 16) | (pa[40] << 24);
  28. int b = pb[37] | (pb[38] << 8) | (pb[39] << 16) | (pb[40] << 24);
  29. return a - b;
  30. }
  31. static int it_old_psm_read_samples(IT_SAMPLE **sample, DUMBFILE *f, int *num) {
  32. int n, o, count = *num, true_num, snum, offset, flags, finetune, delta;
  33. unsigned char *buffer;
  34. const unsigned char *sdata;
  35. long sample_bytes;
  36. buffer = malloc(count * 64);
  37. if (!buffer)
  38. goto error;
  39. if (dumbfile_getnc((char *)buffer, count * 64, f) < count * 64)
  40. goto error_fb;
  41. true_num = 0;
  42. for (n = 0; n < count; n++) {
  43. snum = buffer[(n * 64) + 45] | (buffer[(n * 64) + 46] << 8);
  44. if ((snum < 1) || (snum > 255))
  45. goto error_fb;
  46. if (true_num < snum)
  47. true_num = snum;
  48. }
  49. if (true_num > count) {
  50. IT_SAMPLE *meh = realloc(*sample, true_num * sizeof(*meh));
  51. if (!meh)
  52. goto error_fb;
  53. for (n = count; n < true_num; n++) {
  54. meh[n].data = NULL;
  55. }
  56. *sample = meh;
  57. *num = true_num;
  58. }
  59. qsort(buffer, count, 64, &psm_sample_compare);
  60. for (n = 0; n < *num; n++) {
  61. (*sample)[n].flags = 0;
  62. }
  63. for (n = 0; n < count; n++) {
  64. IT_SAMPLE smp;
  65. IT_SAMPLE *s;
  66. snum = buffer[(n * 64) + 45] | (buffer[(n * 64) + 46] << 8);
  67. s = &((*sample)[snum - 1]);
  68. memcpy(smp.filename, buffer + (n * 64), 13);
  69. smp.filename[13] = 0;
  70. memcpy(smp.name, buffer + (n * 64) + 13, 24);
  71. smp.name[24] = 0;
  72. offset = buffer[(n * 64) + 37] | (buffer[(n * 64) + 38] << 8) |
  73. (buffer[(n * 64) + 39] << 16) | (buffer[(n * 64) + 40] << 24);
  74. flags = buffer[(n * 64) + 47];
  75. smp.length = buffer[(n * 64) + 48] | (buffer[(n * 64) + 49] << 8) |
  76. (buffer[(n * 64) + 50] << 16) |
  77. (buffer[(n * 64) + 51] << 24);
  78. smp.loop_start = buffer[(n * 64) + 52] | (buffer[(n * 64) + 53] << 8) |
  79. (buffer[(n * 64) + 54] << 16) |
  80. (buffer[(n * 64) + 55] << 24);
  81. smp.loop_end = buffer[(n * 64) + 56] | (buffer[(n * 64) + 57] << 8) |
  82. (buffer[(n * 64) + 58] << 16) |
  83. (buffer[(n * 64) + 59] << 24);
  84. if (smp.length <= 0)
  85. continue;
  86. finetune = buffer[(n * 64) + 60];
  87. smp.default_volume = buffer[(n * 64) + 61];
  88. smp.C5_speed = buffer[(n * 64) + 62] | (buffer[(n * 64) + 63] << 8);
  89. if (finetune & 15) {
  90. finetune &= 15;
  91. if (finetune >= 8)
  92. finetune -= 16;
  93. // s->C5_speed = (long)((double)s->C5_speed * pow(DUMB_PITCH_BASE,
  94. // finetune*32));
  95. smp.finetune = finetune * 32;
  96. } else
  97. smp.finetune = 0;
  98. smp.flags = IT_SAMPLE_EXISTS;
  99. if (flags & 0x41)
  100. continue;
  101. if (flags & 0x20)
  102. smp.flags |= IT_SAMPLE_PINGPONG_LOOP;
  103. if (flags & 4)
  104. smp.flags |= IT_SAMPLE_16BIT;
  105. if (flags & 0x80) {
  106. smp.flags |= IT_SAMPLE_LOOP;
  107. if ((unsigned int)smp.loop_end > (unsigned int)smp.length)
  108. smp.loop_end = smp.length;
  109. else if ((unsigned int)smp.loop_start >= (unsigned int)smp.loop_end)
  110. smp.flags &= ~IT_SAMPLE_LOOP;
  111. else
  112. smp.length = smp.loop_end;
  113. }
  114. smp.global_volume = 64;
  115. smp.vibrato_speed = 0;
  116. smp.vibrato_depth = 0;
  117. smp.vibrato_rate = 0;
  118. smp.vibrato_waveform = IT_VIBRATO_SINE;
  119. smp.max_resampling_quality = -1;
  120. sample_bytes = smp.length * ((flags & 4) ? 2 : 1);
  121. smp.data = malloc(sample_bytes);
  122. if (!smp.data)
  123. goto error_fb;
  124. sdata = (const unsigned char *)smp.data;
  125. if (dumbfile_seek(f, offset, DFS_SEEK_SET) ||
  126. dumbfile_getnc(smp.data, sample_bytes, f) < sample_bytes)
  127. goto error_fd;
  128. if (flags & 0x10) {
  129. if (flags & 8) {
  130. if (flags & 4) {
  131. for (o = 0; o < smp.length; o++)
  132. ((short *)smp.data)[o] =
  133. (sdata[o * 2] | (sdata[(o * 2) + 1] << 8)) ^ 0x8000;
  134. } else {
  135. for (o = 0; o < smp.length; o++)
  136. ((signed char *)smp.data)[o] = sdata[o] ^ 0x80;
  137. }
  138. } else {
  139. if (flags & 4) {
  140. for (o = 0; o < smp.length; o++)
  141. ((short *)smp.data)[o] =
  142. sdata[o * 2] | (sdata[(o * 2) + 1] << 8);
  143. } else {
  144. memcpy(smp.data, sdata, smp.length);
  145. }
  146. }
  147. } else {
  148. delta = 0;
  149. if (flags & 8) {
  150. /* unsigned delta? mehhh, does anything even use this? */
  151. if (flags & 4) {
  152. for (o = 0; o < smp.length; o++) {
  153. delta +=
  154. (short)(sdata[o * 2] | (sdata[(o * 2) + 1] << 8));
  155. ((short *)smp.data)[o] = delta ^ 0x8000;
  156. }
  157. } else {
  158. for (o = 0; o < smp.length; o++) {
  159. delta += (signed char)sdata[o];
  160. ((signed char *)smp.data)[o] = delta ^ 0x80;
  161. }
  162. }
  163. } else {
  164. if (flags & 4) {
  165. for (o = 0; o < smp.length; o++) {
  166. delta += (signed short)(sdata[o * 2] |
  167. (sdata[(o * 2) + 1] << 8));
  168. ((signed short *)smp.data)[o] = delta;
  169. }
  170. } else {
  171. for (o = 0; o < smp.length; o++) {
  172. delta += (signed char)sdata[o];
  173. ((signed char *)smp.data)[o] = delta;
  174. }
  175. }
  176. }
  177. }
  178. if (s->data)
  179. free(s->data);
  180. *s = smp;
  181. }
  182. free(buffer);
  183. return 0;
  184. error_fd:
  185. free((void *)sdata);
  186. error_fb:
  187. free(buffer);
  188. error:
  189. return -1;
  190. }
  191. static int it_old_psm_read_patterns(IT_PATTERN *pattern, DUMBFILE *f, int num,
  192. int size, int pchans) {
  193. int n, offset, psize, rows, chans, row, flags, channel;
  194. unsigned char *buffer, *ptr, *end;
  195. IT_ENTRY *entry;
  196. buffer = malloc(size);
  197. if (!buffer)
  198. goto error;
  199. if (dumbfile_getnc((char *)buffer, size, f) < size)
  200. goto error_fb;
  201. offset = 0;
  202. for (n = 0; n < num; n++) {
  203. IT_PATTERN *p = &pattern[n];
  204. if (offset >= size)
  205. goto error_fb;
  206. ptr = buffer + offset;
  207. psize = ptr[0] | (ptr[1] << 8);
  208. rows = ptr[2];
  209. chans = ptr[3];
  210. if (!rows || !chans) {
  211. p->n_rows = 1;
  212. p->n_entries = 0;
  213. continue;
  214. }
  215. psize = (psize + 15) & ~15;
  216. if (offset + psize > size)
  217. goto error_fb;
  218. end = ptr + psize;
  219. ptr += 4;
  220. p->n_rows = rows;
  221. p->n_entries = rows;
  222. row = 0;
  223. while ((row < rows) && (ptr < end)) {
  224. flags = *ptr++;
  225. if (!flags) {
  226. row++;
  227. continue;
  228. }
  229. if (flags & 0xE0) {
  230. p->n_entries++;
  231. if (flags & 0x80)
  232. ptr += 2;
  233. if (flags & 0x40)
  234. ptr++;
  235. if (flags & 0x20) {
  236. if (*ptr == 40)
  237. ptr += 4;
  238. else
  239. ptr += 2;
  240. }
  241. }
  242. }
  243. entry = malloc(p->n_entries * sizeof(*p->entry));
  244. if (!entry)
  245. goto error_fb;
  246. p->entry = entry;
  247. ptr = buffer + offset + 4;
  248. row = 0;
  249. while ((row < rows) && (ptr < end)) {
  250. flags = *ptr++;
  251. if (!flags) {
  252. IT_SET_END_ROW(entry);
  253. entry++;
  254. row++;
  255. continue;
  256. }
  257. if (flags & 0xE0) {
  258. entry->mask = 0;
  259. entry->channel = channel = flags & 0x1F;
  260. if (channel >= chans) {
  261. // channel = 0;
  262. // goto error_fb;
  263. }
  264. if (flags & 0x80) {
  265. if ((*ptr < 60) && (channel < pchans)) {
  266. entry->mask |= IT_ENTRY_NOTE;
  267. entry->note = *ptr + 35;
  268. }
  269. ptr++;
  270. if (*ptr) {
  271. entry->mask |= IT_ENTRY_INSTRUMENT;
  272. entry->instrument = *ptr;
  273. }
  274. ptr++;
  275. }
  276. if (flags & 0x40) {
  277. if (*ptr <= 64) {
  278. entry->mask |= IT_ENTRY_VOLPAN;
  279. entry->volpan = *ptr;
  280. }
  281. ptr++;
  282. }
  283. if (flags & 0x20) {
  284. entry->mask |= IT_ENTRY_EFFECT;
  285. switch (*ptr) {
  286. case 1:
  287. entry->effect = IT_XM_FINE_VOLSLIDE_UP;
  288. entry->effectvalue = ptr[1];
  289. break;
  290. case 2:
  291. entry->effect = IT_VOLUME_SLIDE;
  292. entry->effectvalue = (ptr[1] << 4) & 0xF0;
  293. break;
  294. case 3:
  295. entry->effect = IT_XM_FINE_VOLSLIDE_DOWN;
  296. entry->effectvalue = ptr[1];
  297. break;
  298. case 4:
  299. entry->effect = IT_VOLUME_SLIDE;
  300. entry->effectvalue = ptr[1] & 0xF;
  301. break;
  302. case 10:
  303. entry->effect = IT_PORTAMENTO_UP;
  304. entry->effectvalue = EFFECT_VALUE(0xF, ptr[1]);
  305. break;
  306. case 11:
  307. entry->effect = IT_PORTAMENTO_UP;
  308. entry->effectvalue = ptr[1];
  309. break;
  310. case 12:
  311. entry->effect = IT_PORTAMENTO_DOWN;
  312. entry->effectvalue = EFFECT_VALUE(ptr[1], 0xF);
  313. break;
  314. case 13:
  315. entry->effect = IT_PORTAMENTO_DOWN;
  316. entry->effectvalue = ptr[1];
  317. break;
  318. case 14:
  319. entry->effect = IT_TONE_PORTAMENTO;
  320. entry->effectvalue = ptr[1];
  321. break;
  322. case 15:
  323. entry->effect = IT_S;
  324. entry->effectvalue = EFFECT_VALUE(
  325. IT_S_SET_GLISSANDO_CONTROL, ptr[1] & 15);
  326. break;
  327. case 16:
  328. entry->effect = IT_VOLSLIDE_TONEPORTA;
  329. entry->effectvalue = ptr[1] << 4;
  330. break;
  331. case 17:
  332. entry->effect = IT_VOLSLIDE_TONEPORTA;
  333. entry->effectvalue = ptr[1] & 0xF;
  334. break;
  335. case 20:
  336. entry->effect = IT_VIBRATO;
  337. entry->effectvalue = ptr[1];
  338. break;
  339. case 21:
  340. entry->effect = IT_S;
  341. entry->effectvalue = EFFECT_VALUE(
  342. IT_S_SET_VIBRATO_WAVEFORM, ptr[1] & 11);
  343. break;
  344. case 22:
  345. entry->effect = IT_VOLSLIDE_VIBRATO;
  346. entry->effectvalue = ptr[1] << 4;
  347. break;
  348. case 23:
  349. entry->effect = IT_VOLSLIDE_VIBRATO;
  350. entry->effectvalue = ptr[1] & 0xF;
  351. break;
  352. case 30:
  353. entry->effect = IT_TREMOLO;
  354. entry->effectvalue = ptr[1];
  355. break;
  356. case 31:
  357. entry->effect = IT_S;
  358. entry->effectvalue = EFFECT_VALUE(
  359. IT_S_SET_TREMOLO_WAVEFORM, ptr[1] & 11);
  360. break;
  361. case 40:
  362. entry->effect = IT_SET_SAMPLE_OFFSET;
  363. entry->effectvalue = ptr[2];
  364. ptr += 2;
  365. break;
  366. case 41:
  367. entry->effect = IT_XM_RETRIGGER_NOTE;
  368. entry->effectvalue = ptr[1];
  369. break;
  370. case 42:
  371. entry->effect = IT_S;
  372. entry->effectvalue =
  373. EFFECT_VALUE(IT_S_DELAYED_NOTE_CUT, ptr[1] & 0xF);
  374. break;
  375. case 43:
  376. entry->effect = IT_S;
  377. entry->effectvalue =
  378. EFFECT_VALUE(IT_S_NOTE_DELAY, ptr[1] & 0xF);
  379. break;
  380. case 50:
  381. entry->effect = IT_JUMP_TO_ORDER;
  382. entry->effectvalue = ptr[1];
  383. break;
  384. case 51:
  385. entry->effect = IT_BREAK_TO_ROW;
  386. entry->effectvalue = ptr[1];
  387. break;
  388. case 52:
  389. entry->effect = IT_S;
  390. entry->effectvalue =
  391. EFFECT_VALUE(IT_S_PATTERN_LOOP, ptr[1] & 0xF);
  392. break;
  393. case 53:
  394. entry->effect = IT_S;
  395. entry->effectvalue =
  396. EFFECT_VALUE(IT_S_PATTERN_DELAY, ptr[1] & 0xF);
  397. break;
  398. case 60:
  399. entry->effect = IT_SET_SPEED;
  400. entry->effectvalue = ptr[1];
  401. break;
  402. case 61:
  403. entry->effect = IT_SET_SONG_TEMPO;
  404. entry->effectvalue = ptr[1];
  405. break;
  406. case 70:
  407. entry->effect = IT_ARPEGGIO;
  408. entry->effectvalue = ptr[1];
  409. break;
  410. case 71:
  411. entry->effect = IT_S;
  412. entry->effectvalue =
  413. EFFECT_VALUE(IT_S_FINETUNE, ptr[1] & 0xF);
  414. break;
  415. case 72:
  416. /* "balance" ... panning? */
  417. entry->effect = IT_SET_PANNING;
  418. entry->effectvalue =
  419. ((ptr[1] - ((ptr[1] & 8) >> 3)) << 5) / 7;
  420. break;
  421. default:
  422. entry->mask &= ~IT_ENTRY_EFFECT;
  423. }
  424. ptr += 2;
  425. }
  426. if (entry->mask)
  427. entry++;
  428. }
  429. }
  430. p->n_entries = (int)(entry - p->entry);
  431. offset += psize;
  432. }
  433. free(buffer);
  434. return 0;
  435. error_fb:
  436. free(buffer);
  437. error:
  438. return -1;
  439. }
  440. #define PSM_COMPONENT_ORDERS 0
  441. #define PSM_COMPONENT_PANPOS 1
  442. #define PSM_COMPONENT_PATTERNS 2
  443. #define PSM_COMPONENT_SAMPLE_HEADERS 3
  444. #define PSM_COMPONENT_COMMENTS 4
  445. typedef struct PSM_COMPONENT {
  446. unsigned char type;
  447. long offset;
  448. } PSM_COMPONENT;
  449. static int psm_component_compare(const void *e1, const void *e2) {
  450. return (int)(((const PSM_COMPONENT *)e1)->offset -
  451. ((const PSM_COMPONENT *)e2)->offset);
  452. }
  453. static DUMB_IT_SIGDATA *it_old_psm_load_sigdata(DUMBFILE *f) {
  454. DUMB_IT_SIGDATA *sigdata;
  455. PSM_COMPONENT *component;
  456. int n_components = 0;
  457. int n, flags, version, pver, n_orders, n_channels, total_pattern_size;
  458. if (dumbfile_mgetl(f) != DUMB_ID('P', 'S', 'M', 254))
  459. goto error;
  460. sigdata = malloc(sizeof(*sigdata));
  461. if (!sigdata)
  462. goto error;
  463. if (dumbfile_getnc((char *)sigdata->name, 60, f) < 60 ||
  464. sigdata->name[59] != 0x1A)
  465. goto error_sd;
  466. sigdata->name[59] = 0;
  467. flags = dumbfile_getc(f);
  468. version = dumbfile_getc(f);
  469. pver = dumbfile_getc(f);
  470. sigdata->speed = dumbfile_getc(f);
  471. sigdata->tempo = dumbfile_getc(f);
  472. sigdata->mixing_volume = dumbfile_getc(f);
  473. sigdata->n_orders = dumbfile_igetw(f);
  474. n_orders = dumbfile_igetw(f);
  475. sigdata->n_patterns = dumbfile_igetw(f);
  476. sigdata->n_samples = dumbfile_igetw(f);
  477. sigdata->n_pchannels = dumbfile_igetw(f);
  478. n_channels = dumbfile_igetw(f);
  479. if (dumbfile_error(f) || (flags & 1) || (version != 1 && version != 0x10) ||
  480. (pver) || (sigdata->n_orders <= 0) || (sigdata->n_orders > 255) ||
  481. (n_orders > 255) || (n_orders < sigdata->n_orders) ||
  482. (sigdata->n_patterns > 255) || (sigdata->n_samples > 255) ||
  483. (sigdata->n_pchannels > DUMB_IT_N_CHANNELS) ||
  484. (sigdata->n_pchannels > n_channels) ||
  485. (n_channels > DUMB_IT_N_CHANNELS))
  486. goto error_sd;
  487. sigdata->flags = IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX;
  488. sigdata->global_volume = 128;
  489. sigdata->pan_separation = 128;
  490. sigdata->song_message = NULL;
  491. sigdata->order = NULL;
  492. sigdata->instrument = NULL;
  493. sigdata->sample = NULL;
  494. sigdata->pattern = NULL;
  495. sigdata->midi = NULL;
  496. sigdata->checkpoint = NULL;
  497. sigdata->n_instruments = 0;
  498. sigdata->restart_position = 0;
  499. sigdata->order = malloc(sigdata->n_orders);
  500. if (!sigdata->order)
  501. goto error_usd;
  502. if (sigdata->n_samples) {
  503. sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
  504. if (!sigdata->sample)
  505. goto error_usd;
  506. for (n = 0; n < sigdata->n_samples; n++)
  507. sigdata->sample[n].data = NULL;
  508. }
  509. if (sigdata->n_patterns) {
  510. sigdata->pattern =
  511. malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
  512. if (!sigdata->pattern)
  513. goto error_usd;
  514. for (n = 0; n < sigdata->n_patterns; n++)
  515. sigdata->pattern[n].entry = NULL;
  516. }
  517. component = malloc(5 * sizeof(*component));
  518. if (!component)
  519. goto error_usd;
  520. for (n = 0; n < 5; n++) {
  521. component[n_components].offset = dumbfile_igetl(f);
  522. if (component[n_components].offset) {
  523. component[n_components].type = n;
  524. n_components++;
  525. }
  526. }
  527. if (!n_components)
  528. goto error_fc;
  529. total_pattern_size = (int)dumbfile_igetl(f);
  530. if (!total_pattern_size)
  531. goto error_fc;
  532. qsort(component, n_components, sizeof(PSM_COMPONENT),
  533. &psm_component_compare);
  534. memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);
  535. for (n = 0; n < DUMB_IT_N_CHANNELS; n += 4) {
  536. int sep = 32 * dumb_it_default_panning_separation / 100;
  537. sigdata->channel_pan[n] = 32 - sep;
  538. sigdata->channel_pan[n + 1] = 32 + sep;
  539. sigdata->channel_pan[n + 2] = 32 + sep;
  540. sigdata->channel_pan[n + 3] = 32 - sep;
  541. }
  542. for (n = 0; n < n_components; n++) {
  543. int o;
  544. if (dumbfile_seek(f, component[n].offset, DFS_SEEK_SET))
  545. goto error_fc;
  546. switch (component[n].type) {
  547. case PSM_COMPONENT_ORDERS:
  548. if (dumbfile_getnc((char *)sigdata->order, sigdata->n_orders, f) <
  549. sigdata->n_orders)
  550. goto error_fc;
  551. if (n_orders > sigdata->n_orders)
  552. if (dumbfile_skip(f, n_orders - sigdata->n_orders))
  553. goto error_fc;
  554. if (dumbfile_igetw(f))
  555. goto error_fc;
  556. break;
  557. case PSM_COMPONENT_PANPOS:
  558. if (dumbfile_getnc((char *)sigdata->channel_pan,
  559. sigdata->n_pchannels, f) < sigdata->n_pchannels)
  560. goto error_fc;
  561. for (o = 0; o < sigdata->n_pchannels; o++) {
  562. sigdata->channel_pan[o] -= (sigdata->channel_pan[o] & 8) >> 3;
  563. sigdata->channel_pan[o] =
  564. ((int)sigdata->channel_pan[o] << 5) / 7;
  565. }
  566. break;
  567. case PSM_COMPONENT_PATTERNS:
  568. if (it_old_psm_read_patterns(
  569. sigdata->pattern, f, sigdata->n_patterns,
  570. total_pattern_size, sigdata->n_pchannels))
  571. goto error_fc;
  572. break;
  573. case PSM_COMPONENT_SAMPLE_HEADERS:
  574. if (it_old_psm_read_samples(&sigdata->sample, f,
  575. &sigdata->n_samples))
  576. goto error_fc;
  577. break;
  578. case PSM_COMPONENT_COMMENTS:
  579. if (dumbfile_mgetl(f) == DUMB_ID('T', 'E', 'X', 'T')) {
  580. o = dumbfile_igetw(f);
  581. if (o > 0) {
  582. sigdata->song_message = malloc(o + 1);
  583. if (dumbfile_getnc((char *)sigdata->song_message, o, f) < o)
  584. goto error_fc;
  585. sigdata->song_message[o] = 0;
  586. }
  587. }
  588. break;
  589. }
  590. }
  591. if (_dumb_it_fix_invalid_orders(sigdata) < 0)
  592. goto error_fc;
  593. free(component);
  594. return sigdata;
  595. error_fc:
  596. free(component);
  597. error_usd:
  598. _dumb_it_unload_sigdata(sigdata);
  599. return NULL;
  600. error_sd:
  601. free(sigdata);
  602. error:
  603. return NULL;
  604. }
  605. DUH *dumb_read_old_psm_quick(DUMBFILE *f) {
  606. sigdata_t *sigdata;
  607. DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
  608. sigdata = it_old_psm_load_sigdata(f);
  609. if (!sigdata)
  610. return NULL;
  611. {
  612. const char *tag[2][2];
  613. tag[0][0] = "TITLE";
  614. tag[0][1] = (const char *)(((DUMB_IT_SIGDATA *)sigdata)->name);
  615. tag[1][0] = "FORMAT";
  616. tag[1][1] = "PSM (old)";
  617. return make_duh(-1, 2, (const char *const(*)[2])tag, 1, &descptr,
  618. &sigdata);
  619. }
  620. }