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