sd2.c
上传用户:shw771010
上传日期:2022-01-05
资源大小:991k
文件大小:19k
源码类别:

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. ** Copyright (C) 2004 Paavo Jumppanen
  4. **
  5. ** This program is free software; you can redistribute it and/or modify
  6. ** it under the terms of the GNU Lesser General Public License as published by
  7. ** the Free Software Foundation; either version 2.1 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ** GNU Lesser General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU Lesser General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. /*
  20. ** The sd2 support implemented in this file was partially sponsored
  21. ** (financially) by Paavo Jumppanen.
  22. */
  23. /*
  24. ** Documentation on the Mac resource fork was obtained here :
  25. ** http://developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html
  26. */
  27. #include "sfconfig.h"
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <ctype.h>
  32. #include "sndfile.h"
  33. #include "sfendian.h"
  34. #include "common.h"
  35. /*------------------------------------------------------------------------------
  36.  * Markers.
  37. */
  38. #define Sd2f_MARKER MAKE_MARKER ('S', 'd', '2', 'f')
  39. #define Sd2a_MARKER MAKE_MARKER ('S', 'd', '2', 'a')
  40. #define ALCH_MARKER MAKE_MARKER ('A', 'L', 'C', 'H')
  41. #define lsf1_MARKER MAKE_MARKER ('l', 's', 'f', '1')
  42. #define STR_MARKER MAKE_MARKER ('S', 'T', 'R', ' ')
  43. #define sdML_MARKER MAKE_MARKER ('s', 'd', 'M', 'L')
  44. enum
  45. { RSRC_STR = 111,
  46. RSRC_BIN
  47. } ;
  48. typedef struct
  49. { unsigned char * rsrc_data ;
  50. int rsrc_len ;
  51. int need_to_free_rsrc_data ;
  52. int data_offset, data_length ;
  53. int map_offset, map_length ;
  54. int type_count, type_offset ;
  55. int item_offset ;
  56. int str_index, str_count ;
  57. int string_offset ;
  58. /* All the above just to get these three. */
  59. int sample_size, sample_rate, channels ;
  60. } SD2_RSRC ;
  61. typedef struct
  62. { int type ;
  63. int id ;
  64. char name [32] ;
  65. char value [32] ;
  66. int value_len ;
  67. } STR_RSRC ;
  68. /*------------------------------------------------------------------------------
  69.  * Private static functions.
  70. */
  71. static int sd2_close (SF_PRIVATE *psf) ;
  72. static int sd2_parse_rsrc_fork (SF_PRIVATE *psf) ;
  73. static int parse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc) ;
  74. static int sd2_write_rsrc_fork (SF_PRIVATE *psf, int calc_length) ;
  75. /*------------------------------------------------------------------------------
  76. ** Public functions.
  77. */
  78. int
  79. sd2_open (SF_PRIVATE *psf)
  80. { int subformat, error = 0, valid ;
  81. /* SD2 is always big endian. */
  82. psf->endian = SF_ENDIAN_BIG ;
  83. if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->rsrclength > 0))
  84. { psf_use_rsrc (psf, SF_TRUE) ;
  85. valid = psf_file_valid (psf) ;
  86. psf_use_rsrc (psf, SF_FALSE) ;
  87. if (! valid)
  88. { psf_log_printf (psf, "sd2_open : psf->rsrc.filedes < 0n") ;
  89. return SFE_SD2_BAD_RSRC ;
  90. } ;
  91. error = sd2_parse_rsrc_fork (psf) ;
  92. if (error)
  93. goto error_cleanup ;
  94. } ;
  95. if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_SD2)
  96. { error = SFE_BAD_OPEN_FORMAT ;
  97. goto error_cleanup ;
  98. } ;
  99. subformat = SF_CODEC (psf->sf.format) ;
  100. psf->dataoffset = 0 ;
  101. /* Only open and write the resource in RDWR mode is its current length is zero. */
  102. if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->rsrclength == 0))
  103. { psf->rsrc.mode = psf->file.mode ;
  104. psf_open_rsrc (psf) ;
  105. error = sd2_write_rsrc_fork (psf, SF_FALSE) ;
  106. if (error)
  107. goto error_cleanup ;
  108. /* Not needed. */
  109. psf->write_header = NULL ;
  110. } ;
  111. psf->container_close = sd2_close ;
  112. psf->blockwidth = psf->bytewidth * psf->sf.channels ;
  113. switch (subformat)
  114. { case SF_FORMAT_PCM_S8 : /* 8-bit linear PCM. */
  115. case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
  116. case SF_FORMAT_PCM_24 : /* 24-bit linear PCM */
  117. error = pcm_init (psf) ;
  118. break ;
  119. default :
  120. error = SFE_UNIMPLEMENTED ;
  121. break ;
  122. } ;
  123. psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
  124. error_cleanup:
  125. /* Close the resource fork regardless. We won't need it again. */
  126. psf_close_rsrc (psf) ;
  127. return error ;
  128. } /* sd2_open */
  129. /*------------------------------------------------------------------------------
  130. */
  131. static int
  132. sd2_close (SF_PRIVATE *psf)
  133. {
  134. if (psf->file.mode == SFM_WRITE)
  135. { /*  Now we know for certain the audio_length of the file we can re-write
  136. ** correct values for the FORM, 8SVX and BODY chunks.
  137. */
  138. } ;
  139. return 0 ;
  140. } /* sd2_close */
  141. /*------------------------------------------------------------------------------
  142. */
  143. static inline void
  144. write_char (unsigned char * data, int offset, char value)
  145. { data [offset] = value ;
  146. } /* write_char */
  147. static inline void
  148. write_short (unsigned char * data, int offset, short value)
  149. { data [offset] = value >> 8 ;
  150. data [offset + 1] = value ;
  151. } /* write_char */
  152. static inline void
  153. write_int (unsigned char * data, int offset, int value)
  154. { data [offset] = value >> 24 ;
  155. data [offset + 1] = value >> 16 ;
  156. data [offset + 2] = value >> 8 ;
  157. data [offset + 3] = value ;
  158. } /* write_int */
  159. static inline void
  160. write_marker (unsigned char * data, int offset, int value)
  161. {
  162. if (CPU_IS_BIG_ENDIAN)
  163. { data [offset] = value >> 24 ;
  164. data [offset + 1] = value >> 16 ;
  165. data [offset + 2] = value >> 8 ;
  166. data [offset + 3] = value ;
  167. }
  168. else
  169. { data [offset] = value ;
  170. data [offset + 1] = value >> 8 ;
  171. data [offset + 2] = value >> 16 ;
  172. data [offset + 3] = value >> 24 ;
  173. } ;
  174. } /* write_marker */
  175. static void
  176. write_str (unsigned char * data, int offset, const char * buffer, int buffer_len)
  177. { memcpy (data + offset, buffer, buffer_len) ;
  178. } /* write_str */
  179. static int
  180. sd2_write_rsrc_fork (SF_PRIVATE *psf, int UNUSED (calc_length))
  181. { SD2_RSRC rsrc ;
  182. STR_RSRC str_rsrc [] =
  183. { { RSRC_STR, 1000, "_sample-size", "", 0 },
  184. { RSRC_STR, 1001, "_sample-rate", "", 0 },
  185. { RSRC_STR, 1002, "_channels", "", 0 },
  186. { RSRC_BIN, 1000, "_Markers", "", 8 }
  187. } ;
  188. int k, str_offset, data_offset, next_str ;
  189. psf_use_rsrc (psf, SF_TRUE) ;
  190. memset (&rsrc, 0, sizeof (rsrc)) ;
  191. rsrc.sample_rate = psf->sf.samplerate ;
  192. rsrc.sample_size = psf->bytewidth ;
  193. rsrc.channels = psf->sf.channels ;
  194. rsrc.rsrc_data = psf->header ;
  195. rsrc.rsrc_len = sizeof (psf->header) ;
  196. memset (rsrc.rsrc_data, 0xea, rsrc.rsrc_len) ;
  197. snprintf (str_rsrc [0].value, sizeof (str_rsrc [0].value), "_%d", rsrc.sample_size) ;
  198. snprintf (str_rsrc [1].value, sizeof (str_rsrc [1].value), "_%d.000000", rsrc.sample_rate) ;
  199. snprintf (str_rsrc [2].value, sizeof (str_rsrc [2].value), "_%d", rsrc.channels) ;
  200. for (k = 0 ; k < ARRAY_LEN (str_rsrc) ; k++)
  201. { if (str_rsrc [k].value_len == 0)
  202. { str_rsrc [k].value_len = strlen (str_rsrc [k].value) ;
  203. str_rsrc [k].value [0] = str_rsrc [k].value_len - 1 ;
  204. } ;
  205. /* Turn name string into a pascal string. */
  206. str_rsrc [k].name [0] = strlen (str_rsrc [k].name) - 1 ;
  207. } ;
  208. rsrc.data_offset = 0x100 ;
  209. /*
  210. ** Calculate data length :
  211. ** length of strings, plus the length of the sdML chunk.
  212. */
  213. rsrc.data_length = 0 ;
  214. for (k = 0 ; k < ARRAY_LEN (str_rsrc) ; k++)
  215. rsrc.data_length += str_rsrc [k].value_len + 4 ;
  216. rsrc.map_offset = rsrc.data_offset + rsrc.data_length ;
  217. /* Very start of resource fork. */
  218. write_int (rsrc.rsrc_data, 0, rsrc.data_offset) ;
  219. write_int (rsrc.rsrc_data, 4, rsrc.map_offset) ;
  220. write_int (rsrc.rsrc_data, 8, rsrc.data_length) ;
  221. write_char (rsrc.rsrc_data, 0x30, strlen (psf->file.name.c)) ;
  222. write_str (rsrc.rsrc_data, 0x31, psf->file.name.c, strlen (psf->file.name.c)) ;
  223. write_short (rsrc.rsrc_data, 0x50, 0) ;
  224. write_marker (rsrc.rsrc_data, 0x52, Sd2f_MARKER) ;
  225. write_marker (rsrc.rsrc_data, 0x56, lsf1_MARKER) ;
  226. /* Very start of resource map. */
  227. write_int (rsrc.rsrc_data, rsrc.map_offset + 0, rsrc.data_offset) ;
  228. write_int (rsrc.rsrc_data, rsrc.map_offset + 4, rsrc.map_offset) ;
  229. write_int (rsrc.rsrc_data, rsrc.map_offset + 8, rsrc.data_length) ;
  230. /* These I don't currently understand. */
  231. if (1)
  232. { write_char (rsrc.rsrc_data, rsrc.map_offset+ 16, 1) ;
  233. /* Next resource map. */
  234. write_int (rsrc.rsrc_data, rsrc.map_offset + 17, 0x12345678) ;
  235. /* File ref number. */
  236. write_short (rsrc.rsrc_data, rsrc.map_offset + 21, 0xabcd) ;
  237. /* Fork attributes. */
  238. write_short (rsrc.rsrc_data, rsrc.map_offset + 23, 0) ;
  239. } ;
  240. /* Resource type offset. */
  241. rsrc.type_offset = rsrc.map_offset + 30 ;
  242. write_short (rsrc.rsrc_data, rsrc.map_offset + 24, rsrc.type_offset - rsrc.map_offset - 2) ;
  243. /* Type index max. */
  244. rsrc.type_count = 2 ;
  245. write_short (rsrc.rsrc_data, rsrc.map_offset + 28, rsrc.type_count - 1) ;
  246. rsrc.item_offset = rsrc.type_offset + rsrc.type_count * 8 ;
  247. rsrc.str_count = ARRAY_LEN (str_rsrc) ;
  248. rsrc.string_offset = rsrc.item_offset + (rsrc.str_count + 1) * 12 - rsrc.map_offset ;
  249. write_short (rsrc.rsrc_data, rsrc.map_offset + 26, rsrc.string_offset) ;
  250. /* Write 'STR ' resource type. */
  251. rsrc.str_count = 3 ;
  252. write_marker (rsrc.rsrc_data, rsrc.type_offset, STR_MARKER) ;
  253. write_short (rsrc.rsrc_data, rsrc.type_offset + 4, rsrc.str_count - 1) ;
  254. write_short (rsrc.rsrc_data, rsrc.type_offset + 6, 0x12) ;
  255. /* Write 'sdML' resource type. */
  256. write_marker (rsrc.rsrc_data, rsrc.type_offset + 8, sdML_MARKER) ;
  257. write_short (rsrc.rsrc_data, rsrc.type_offset + 12, 0) ;
  258. write_short (rsrc.rsrc_data, rsrc.type_offset + 14, 0x36) ;
  259. str_offset = rsrc.map_offset + rsrc.string_offset ;
  260. next_str = 0 ;
  261. data_offset = rsrc.data_offset ;
  262. for (k = 0 ; k < ARRAY_LEN (str_rsrc) ; k++)
  263. { write_str (rsrc.rsrc_data, str_offset, str_rsrc [k].name, strlen (str_rsrc [k].name)) ;
  264. write_short (rsrc.rsrc_data, rsrc.item_offset + k * 12, str_rsrc [k].id) ;
  265. write_short (rsrc.rsrc_data, rsrc.item_offset + k * 12 + 2, next_str) ;
  266. str_offset += strlen (str_rsrc [k].name) ;
  267. next_str += strlen (str_rsrc [k].name) ;
  268. write_int (rsrc.rsrc_data, rsrc.item_offset + k * 12 + 4, data_offset - rsrc.data_offset) ;
  269. write_int (rsrc.rsrc_data, data_offset, str_rsrc [k].value_len) ;
  270. write_str (rsrc.rsrc_data, data_offset + 4, str_rsrc [k].value, str_rsrc [k].value_len) ;
  271. data_offset += 4 + str_rsrc [k].value_len ;
  272. } ;
  273. /* Finally, calculate and set map length. */
  274. rsrc.map_length = str_offset - rsrc.map_offset ;
  275. write_int (rsrc.rsrc_data, 12, rsrc.map_length) ;
  276. write_int (rsrc.rsrc_data, rsrc.map_offset + 12, rsrc.map_length) ;
  277. rsrc.rsrc_len = rsrc.map_offset + rsrc.map_length ;
  278. psf_fwrite (rsrc.rsrc_data, rsrc.rsrc_len, 1, psf) ;
  279. psf_use_rsrc (psf, SF_FALSE) ;
  280. if (psf->error)
  281. return psf->error ;
  282. return 0 ;
  283. } /* sd2_write_rsrc_fork */
  284. /*------------------------------------------------------------------------------
  285. */
  286. static inline int
  287. read_char (const unsigned char * data, int offset)
  288. { return data [offset] ;
  289. } /* read_char */
  290. static inline int
  291. read_short (const unsigned char * data, int offset)
  292. { return (data [offset] << 8) + data [offset + 1] ;
  293. } /* read_short */
  294. static inline int
  295. read_int (const unsigned char * data, int offset)
  296. { return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;
  297. } /* read_int */
  298. static inline int
  299. read_marker (const unsigned char * data, int offset)
  300. {
  301. if (CPU_IS_BIG_ENDIAN)
  302. return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;
  303. else if (CPU_IS_LITTLE_ENDIAN)
  304. return data [offset] + (data [offset + 1] << 8) + (data [offset + 2] << 16) + (data [offset + 3] << 24) ;
  305. else
  306. return 0x666 ;
  307. } /* read_marker */
  308. static void
  309. read_str (const unsigned char * data, int offset, char * buffer, int buffer_len)
  310. { int k ;
  311. memset (buffer, 0, buffer_len) ;
  312. for (k = 0 ; k < buffer_len - 1 ; k++)
  313. { if (psf_isprint (data [offset + k]) == 0)
  314. return ;
  315. buffer [k] = data [offset + k] ;
  316. } ;
  317. return ;
  318. } /* read_str */
  319. static int
  320. sd2_parse_rsrc_fork (SF_PRIVATE *psf)
  321. { SD2_RSRC rsrc ;
  322. int k, marker, error = 0 ;
  323. psf_use_rsrc (psf, SF_TRUE) ;
  324. memset (&rsrc, 0, sizeof (rsrc)) ;
  325. rsrc.rsrc_len = psf_get_filelen (psf) ;
  326. psf_log_printf (psf, "Resource length : %d (0x%04X)n", rsrc.rsrc_len, rsrc.rsrc_len) ;
  327. if (rsrc.rsrc_len > SIGNED_SIZEOF (psf->header))
  328. { rsrc.rsrc_data = calloc (1, rsrc.rsrc_len) ;
  329. rsrc.need_to_free_rsrc_data = SF_TRUE ;
  330. }
  331. else
  332. rsrc.rsrc_data = psf->header ;
  333. /* Read in the whole lot. */
  334. psf_fread (rsrc.rsrc_data, rsrc.rsrc_len, 1, psf) ;
  335. /* Reset the header storage because we have changed to the rsrcdes. */
  336. psf->headindex = psf->headend = rsrc.rsrc_len ;
  337. rsrc.data_offset = read_int (rsrc.rsrc_data, 0) ;
  338. rsrc.map_offset = read_int (rsrc.rsrc_data, 4) ;
  339. rsrc.data_length = read_int (rsrc.rsrc_data, 8) ;
  340. rsrc.map_length = read_int (rsrc.rsrc_data, 12) ;
  341. if (rsrc.data_offset == 0x51607 && rsrc.map_offset == 0x20000)
  342. { psf_log_printf (psf, "Trying offset of 0x52 bytes.n") ;
  343. rsrc.data_offset = read_int (rsrc.rsrc_data, 0x52 + 0) + 0x52 ;
  344. rsrc.map_offset = read_int (rsrc.rsrc_data, 0x52 + 4) + 0x52 ;
  345. rsrc.data_length = read_int (rsrc.rsrc_data, 0x52 + 8) ;
  346. rsrc.map_length = read_int (rsrc.rsrc_data, 0x52 + 12) ;
  347. } ;
  348. psf_log_printf (psf, "  data offset : 0x%04Xn  map  offset : 0x%04Xn"
  349. "  data length : 0x%04Xn  map  length : 0x%04Xn",
  350. rsrc.data_offset, rsrc.map_offset, rsrc.data_length, rsrc.map_length) ;
  351. if (rsrc.data_offset > rsrc.rsrc_len)
  352. { psf_log_printf (psf, "Error : rsrc.data_offset (%d, 0x%x) > lenn", rsrc.data_offset, rsrc.data_offset) ;
  353. error = SFE_SD2_BAD_DATA_OFFSET ;
  354. goto parse_rsrc_fork_cleanup ;
  355. } ;
  356. if (rsrc.map_offset > rsrc.rsrc_len)
  357. { psf_log_printf (psf, "Error : rsrc.map_offset > lenn") ;
  358. error = SFE_SD2_BAD_MAP_OFFSET ;
  359. goto parse_rsrc_fork_cleanup ;
  360. } ;
  361. if (rsrc.data_length > rsrc.rsrc_len)
  362. { psf_log_printf (psf, "Error : rsrc.data_length > lenn") ;
  363. error = SFE_SD2_BAD_DATA_LENGTH ;
  364. goto parse_rsrc_fork_cleanup ;
  365. } ;
  366. if (rsrc.map_length > rsrc.rsrc_len)
  367. { psf_log_printf (psf, "Error : rsrc.map_length > lenn") ;
  368. error = SFE_SD2_BAD_MAP_LENGTH ;
  369. goto parse_rsrc_fork_cleanup ;
  370. } ;
  371. if (rsrc.data_offset + rsrc.data_length != rsrc.map_offset || rsrc.map_offset + rsrc.map_length != rsrc.rsrc_len)
  372. { psf_log_printf (psf, "Error : This does not look like a MacOSX resource fork.n") ;
  373. error = SFE_SD2_BAD_RSRC ;
  374. goto parse_rsrc_fork_cleanup ;
  375. } ;
  376. if (rsrc.map_offset + 28 >= rsrc.rsrc_len)
  377. { psf_log_printf (psf, "Bad map offset (%d + 28 > %d).n", rsrc.map_offset, rsrc.rsrc_len) ;
  378. error = SFE_SD2_BAD_RSRC ;
  379. goto parse_rsrc_fork_cleanup ;
  380. } ;
  381. rsrc.string_offset = rsrc.map_offset + read_short (rsrc.rsrc_data, rsrc.map_offset + 26) ;
  382. if (rsrc.string_offset > rsrc.rsrc_len)
  383. { psf_log_printf (psf, "Bad string offset (%d).n", rsrc.string_offset) ;
  384. error = SFE_SD2_BAD_RSRC ;
  385. goto parse_rsrc_fork_cleanup ;
  386. } ;
  387. rsrc.type_offset = rsrc.map_offset + 30 ;
  388. rsrc.type_count = read_short (rsrc.rsrc_data, rsrc.map_offset + 28) + 1 ;
  389. if (rsrc.type_count < 1)
  390. { psf_log_printf (psf, "Bad type count.n") ;
  391. error = SFE_SD2_BAD_RSRC ;
  392. goto parse_rsrc_fork_cleanup ;
  393. } ;
  394. rsrc.item_offset = rsrc.type_offset + rsrc.type_count * 8 ;
  395. if (rsrc.item_offset < 0 || rsrc.item_offset > rsrc.rsrc_len)
  396. { psf_log_printf (psf, "Bad item offset (%d).n", rsrc.item_offset) ;
  397. error = SFE_SD2_BAD_RSRC ;
  398. goto parse_rsrc_fork_cleanup ;
  399. } ;
  400. rsrc.str_index = -1 ;
  401. for (k = 0 ; k < rsrc.type_count ; k ++)
  402. { marker = read_marker (rsrc.rsrc_data, rsrc.type_offset + k * 8) ;
  403. if (marker == STR_MARKER)
  404. { rsrc.str_index = k ;
  405. rsrc.str_count = read_short (rsrc.rsrc_data, rsrc.type_offset + k * 8 + 4) + 1 ;
  406. error = parse_str_rsrc (psf, &rsrc) ;
  407. goto parse_rsrc_fork_cleanup ;
  408. } ;
  409. } ;
  410. psf_log_printf (psf, "No 'STR ' resource.n") ;
  411. error = SFE_SD2_BAD_RSRC ;
  412. parse_rsrc_fork_cleanup :
  413. psf_use_rsrc (psf, SF_FALSE) ;
  414. if (rsrc.need_to_free_rsrc_data)
  415. free (rsrc.rsrc_data) ;
  416. return error ;
  417. } /* sd2_parse_rsrc_fork */
  418. static int
  419. parse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc)
  420. { char name [32], value [32] ;
  421. int k, str_offset, rsrc_id, data_offset = 0, data_len = 0 ;
  422. psf_log_printf (psf, "Finding parameters :n") ;
  423. str_offset = rsrc->string_offset ;
  424. psf_log_printf (psf, "  Offset    RsrcId    dlen    slen    Valuen") ;
  425. for (k = 0 ; data_offset + data_len < rsrc->rsrc_len ; k++)
  426. { int slen ;
  427. slen = read_char (rsrc->rsrc_data, str_offset) ;
  428. read_str (rsrc->rsrc_data, str_offset + 1, name, SF_MIN (SIGNED_SIZEOF (name), slen + 1)) ;
  429. str_offset += slen + 1 ;
  430. rsrc_id = read_short (rsrc->rsrc_data, rsrc->item_offset + k * 12) ;
  431. data_offset = rsrc->data_offset + read_int (rsrc->rsrc_data, rsrc->item_offset + k * 12 + 4) ;
  432. if (data_offset < 0 || data_offset > rsrc->rsrc_len)
  433. { psf_log_printf (psf, "Exiting parser on data offset of %d.n", data_offset) ;
  434. break ;
  435. } ;
  436. data_len = read_int (rsrc->rsrc_data, data_offset) ;
  437. if (data_len < 0 || data_len > rsrc->rsrc_len)
  438. { psf_log_printf (psf, "Exiting parser on data length of %d.n", data_len) ;
  439. break ;
  440. } ;
  441. slen = read_char (rsrc->rsrc_data, data_offset + 4) ;
  442. read_str (rsrc->rsrc_data, data_offset + 5, value, SF_MIN (SIGNED_SIZEOF (value), slen + 1)) ;
  443. psf_log_printf (psf, "  0x%04x     %4d     %4d     %3d    '%s'n", data_offset, rsrc_id, data_len, slen, value) ;
  444. if (rsrc_id == 1000 && rsrc->sample_size == 0)
  445. rsrc->sample_size = strtol (value, NULL, 10) ;
  446. else if (rsrc_id == 1001 && rsrc->sample_rate == 0)
  447. rsrc->sample_rate = strtol (value, NULL, 10) ;
  448. else if (rsrc_id == 1002 && rsrc->channels == 0)
  449. rsrc->channels = strtol (value, NULL, 10) ;
  450. } ;
  451. psf_log_printf (psf, "Found Parameters :n") ;
  452. psf_log_printf (psf, "  sample-size : %dn", rsrc->sample_size) ;
  453. psf_log_printf (psf, "  sample-rate : %dn", rsrc->sample_rate) ;
  454. psf_log_printf (psf, "  channels    : %dn", rsrc->channels) ;
  455. if (rsrc->sample_rate <= 4 && rsrc->sample_size > 4)
  456. { int temp ;
  457. psf_log_printf (psf, "Geez!! Looks like sample rate and sample size got switched.nCorrecting this screw up.n") ;
  458. temp = rsrc->sample_rate ;
  459. rsrc->sample_rate = rsrc->sample_size ;
  460. rsrc->sample_size = temp ;
  461. } ;
  462. if (rsrc->sample_rate < 0)
  463. { psf_log_printf (psf, "Bad sample rate (%d)n", rsrc->sample_rate) ;
  464. return SFE_SD2_BAD_RSRC ;
  465. } ;
  466. if (rsrc->channels < 0)
  467. { psf_log_printf (psf, "Bad channel count (%d)n", rsrc->channels) ;
  468. return SFE_SD2_BAD_RSRC ;
  469. } ;
  470. psf->sf.samplerate = rsrc->sample_rate ;
  471. psf->sf.channels = rsrc->channels ;
  472. psf->bytewidth = rsrc->sample_size ;
  473. switch (rsrc->sample_size)
  474. { case 1 :
  475. psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_S8 ;
  476. break ;
  477. case 2 :
  478. psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_16 ;
  479. break ;
  480. case 3 :
  481. psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_24 ;
  482. break ;
  483. default :
  484. psf_log_printf (psf, "Bad sample size (%d)n", rsrc->sample_size) ;
  485. return SFE_SD2_BAD_SAMPLE_SIZE ;
  486. } ;
  487. psf_log_printf (psf, "okn") ;
  488. return 0 ;
  489. } /* parse_str_rsrc */