📄 sd2.c
字号:
write_short (rsrc.rsrc_data, rsrc.map_offset + 23, 0) ; } ; /* Resource type offset. */ rsrc.type_offset = rsrc.map_offset + 30 ; write_short (rsrc.rsrc_data, rsrc.map_offset + 24, rsrc.type_offset - rsrc.map_offset - 2) ; /* Type index max. */ rsrc.type_count = 2 ; write_short (rsrc.rsrc_data, rsrc.map_offset + 28, rsrc.type_count - 1) ; rsrc.item_offset = rsrc.type_offset + rsrc.type_count * 8 ; rsrc.str_count = ARRAY_LEN (str_rsrc) ; rsrc.string_offset = rsrc.item_offset + (rsrc.str_count + 1) * 12 - rsrc.map_offset ; write_short (rsrc.rsrc_data, rsrc.map_offset + 26, rsrc.string_offset) ; /* Write 'STR ' resource type. */ rsrc.str_count = 3 ; write_int (rsrc.rsrc_data, rsrc.type_offset, STR_MARKER) ; write_short (rsrc.rsrc_data, rsrc.type_offset + 4, rsrc.str_count - 1) ; write_short (rsrc.rsrc_data, rsrc.type_offset + 6, 0x12) ; /* Write 'sdML' resource type. */ write_int (rsrc.rsrc_data, rsrc.type_offset + 8, sdML_MARKER) ; write_short (rsrc.rsrc_data, rsrc.type_offset + 12, 0) ; write_short (rsrc.rsrc_data, rsrc.type_offset + 14, 0x36) ; str_offset = rsrc.map_offset + rsrc.string_offset ; next_str = 0 ; data_offset = rsrc.data_offset ; for (k = 0 ; k < ARRAY_LEN (str_rsrc) ; k++) { write_str (rsrc.rsrc_data, str_offset, str_rsrc [k].name, strlen (str_rsrc [k].name)) ; write_short (rsrc.rsrc_data, rsrc.item_offset + k * 12, str_rsrc [k].id) ; write_short (rsrc.rsrc_data, rsrc.item_offset + k * 12 + 2, next_str) ; str_offset += strlen (str_rsrc [k].name) ; next_str += strlen (str_rsrc [k].name) ; write_int (rsrc.rsrc_data, rsrc.item_offset + k * 12 + 4, data_offset - rsrc.data_offset) ; write_int (rsrc.rsrc_data, data_offset, str_rsrc [k].value_len) ; write_str (rsrc.rsrc_data, data_offset + 4, str_rsrc [k].value, str_rsrc [k].value_len) ; data_offset += 4 + str_rsrc [k].value_len ; } ; /* Finally, calculate and set map length. */ rsrc.map_length = str_offset - rsrc.map_offset ; write_int (rsrc.rsrc_data, 12, rsrc.map_length) ; write_int (rsrc.rsrc_data, rsrc.map_offset + 12, rsrc.map_length) ; rsrc.rsrc_len = rsrc.map_offset + rsrc.map_length ; psf_fwrite (rsrc.rsrc_data, rsrc.rsrc_len, 1, psf) ; if (psf->error) return psf->error ; return 0 ;} /* sd2_write_rsrc_fork *//*------------------------------------------------------------------------------*/static inline intread_char (const unsigned char * data, int offset){ return data [offset] ;} /* read_char */static inline intread_short (const unsigned char * data, int offset){ return (data [offset] << 8) + data [offset + 1] ;} /* read_char */static inline intread_int (const unsigned char * data, int offset){ return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;} /* read_char */static voidread_str (const unsigned char * data, int offset, char * buffer, int buffer_len){ int k ; memset (buffer, 0, buffer_len) ; for (k = 0 ; k < buffer_len - 1 ; k++) { if (isprint (data [offset + k]) == 0) return ; buffer [k] = data [offset + k] ; } ; return ;} /* read_str */static intsd2_parse_rsrc_fork (SF_PRIVATE *psf){ SD2_RSRC rsrc ; int k, marker, error = 0 ; memset (&rsrc, 0, sizeof (rsrc)) ; rsrc.rsrc_len = psf_get_filelen (psf) ; psf_log_printf (psf, "Resource length : %d (0x%04X)\n", rsrc.rsrc_len, rsrc.rsrc_len) ; if (rsrc.rsrc_len > SIGNED_SIZEOF (psf->header)) rsrc.rsrc_data = calloc (1, rsrc.rsrc_len) ; else rsrc.rsrc_data = psf->header ; /* Read in the whole lot. */ psf_fread (rsrc.rsrc_data, rsrc.rsrc_len, 1, psf) ; /* Reset the header storage because we have changed to the rsrcdes. */ psf->headindex = psf->headend = rsrc.rsrc_len ; rsrc.data_offset = read_int (rsrc.rsrc_data, 0) ; rsrc.map_offset = read_int (rsrc.rsrc_data, 4) ; rsrc.data_length = read_int (rsrc.rsrc_data, 8) ; rsrc.map_length = read_int (rsrc.rsrc_data, 12) ; psf_log_printf (psf, " data offset : 0x%04X\n map offset : 0x%04X\n" " data length : 0x%04X\n map length : 0x%04X\n", rsrc.data_offset, rsrc.map_offset, rsrc.data_length, rsrc.map_length) ; if (rsrc.data_offset > rsrc.rsrc_len) { psf_log_printf (psf, "Error : rsrc.data_offset > len\n") ; error = SFE_SD2_BAD_DATA_OFFSET ; goto parse_rsrc_fork_cleanup ; } ; if (rsrc.map_offset > rsrc.rsrc_len) { psf_log_printf (psf, "Error : rsrc.map_offset > len\n") ; error = SFE_SD2_BAD_MAP_OFFSET ; goto parse_rsrc_fork_cleanup ; } ; if (rsrc.data_length > rsrc.rsrc_len) { psf_log_printf (psf, "Error : rsrc.data_length > len\n") ; error = SFE_SD2_BAD_DATA_LENGTH ; goto parse_rsrc_fork_cleanup ; } ; if (rsrc.map_length > rsrc.rsrc_len) { psf_log_printf (psf, "Error : rsrc.map_length > len\n") ; error = SFE_SD2_BAD_MAP_LENGTH ; goto parse_rsrc_fork_cleanup ; } ; if (rsrc.data_offset + rsrc.data_length != rsrc.map_offset || rsrc.map_offset + rsrc.map_length != rsrc.rsrc_len) { psf_log_printf (psf, "Error : This does not look like a MacOSX resource fork.\n") ; error = SFE_SD2_BAD_RSRC ; goto parse_rsrc_fork_cleanup ; } ; rsrc.string_offset = rsrc.map_offset + read_short (rsrc.rsrc_data, rsrc.map_offset + 26) ; if (rsrc.string_offset > rsrc.rsrc_len) { psf_log_printf (psf, "Bad string offset (%d).\n", rsrc.string_offset) ; error = SFE_SD2_BAD_RSRC ; goto parse_rsrc_fork_cleanup ; } ; rsrc.type_offset = rsrc.map_offset + 30 ; rsrc.type_count = read_short (rsrc.rsrc_data, rsrc.map_offset + 28) + 1 ; if (rsrc.type_count < 1) { psf_log_printf (psf, "Bad type count.\n") ; error = SFE_SD2_BAD_RSRC ; goto parse_rsrc_fork_cleanup ; } ; rsrc.item_offset = rsrc.type_offset + rsrc.type_count * 8 ; if (rsrc.item_offset < 0 || rsrc.item_offset > rsrc.rsrc_len) { psf_log_printf (psf, "Bad item offset (%d).\n", rsrc.item_offset) ; error = SFE_SD2_BAD_RSRC ; goto parse_rsrc_fork_cleanup ; } ; rsrc.str_index = -1 ; for (k = 0 ; k < rsrc.type_count ; k ++) { marker = read_int (rsrc.rsrc_data, rsrc.type_offset + k * 8) ; if (marker == STR_MARKER) { rsrc.str_index = k ; rsrc.str_count = read_short (rsrc.rsrc_data, rsrc.type_offset + k * 8 + 4) + 1 ; error = parse_str_rsrc (psf, &rsrc) ; goto parse_rsrc_fork_cleanup ; } ; } ; psf_log_printf (psf, "No 'STR ' resource.\n") ; error = SFE_SD2_BAD_RSRC ;parse_rsrc_fork_cleanup : if ((void *) rsrc.rsrc_data < (void *) psf || (void *) rsrc.rsrc_data > (void *) (psf + 1)) free (rsrc.rsrc_data) ; return error ;} /* sd2_parse_rsrc_fork */static intparse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc){ char name [32], value [32] ; int k, str_offset, data_offset, data_len, rsrc_id ; psf_log_printf (psf, "Finding parameters :\n") ; str_offset = rsrc->string_offset ; for (k = 0 ; k < rsrc->str_count ; k++) { int slen ; slen = read_char (rsrc->rsrc_data, str_offset) ; read_str (rsrc->rsrc_data, str_offset + 1, name, SF_MIN (SIGNED_SIZEOF (name), slen + 1)) ; str_offset += slen + 1 ; rsrc_id = read_short (rsrc->rsrc_data, rsrc->item_offset + k * 12) ; data_offset = rsrc->data_offset + read_int (rsrc->rsrc_data, rsrc->item_offset + k * 12 + 4) ; if (data_offset < 0 || data_offset > rsrc->rsrc_len) { psf_log_printf (psf, "Bad data offset (%d)\n", data_offset) ; return SFE_SD2_BAD_DATA_OFFSET ; } ; data_len = read_int (rsrc->rsrc_data, data_offset) ; if (data_len < 0 || data_len > rsrc->rsrc_len) { psf_log_printf (psf, "Bad data length (%d).\n", data_len) ; return SFE_SD2_BAD_RSRC ; } ; slen = read_char (rsrc->rsrc_data, data_offset + 4) ; read_str (rsrc->rsrc_data, data_offset + 5, value, SF_MIN (SIGNED_SIZEOF (value), slen + 1)) ; psf_log_printf (psf, " %-12s 0x%04x %4d %2d %2d '%s'\n", name, data_offset, rsrc_id, data_len, slen, value) ; if (strcmp (name, "sample-size") == 0 && rsrc->sample_size == 0) rsrc->sample_size = strtol (value, NULL, 10) ; else if (strcmp (name, "sample-rate") == 0 && rsrc->sample_rate == 0) rsrc->sample_rate = strtol (value, NULL, 10) ; else if (strcmp (name, "channels") == 0 && rsrc->channels == 0) rsrc->channels = strtol (value, NULL, 10) ; } ; if (rsrc->sample_rate < 0) { psf_log_printf (psf, "Bad sample rate (%d)\n", rsrc->sample_rate) ; return SFE_SD2_BAD_RSRC ; } ; if (rsrc->channels < 0) { psf_log_printf (psf, "Bad channel count (%d)\n", rsrc->channels) ; return SFE_SD2_BAD_RSRC ; } ; psf->sf.samplerate = rsrc->sample_rate ; psf->sf.channels = rsrc->channels ; psf->bytewidth = rsrc->sample_size ; switch (rsrc->sample_size) { case 1 : psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_S8 ; break ; case 2 : psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_16 ; break ; case 3 : psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_24 ; break ; default : psf_log_printf (psf, "Bad sample size (%d)\n", rsrc->sample_size) ; return SFE_SD2_BAD_SAMPLE_SIZE ; } ; psf_log_printf (psf, "ok\n") ; return 0 ;} /* parse_str_rsrc *//*** Do not edit or modify anything in this comment block.** The arch-tag line is a file identity tag for the GNU Arch** revision control system.**** arch-tag: 1ee183e5-6b9f-4c2c-bd0a-24f35595cefc*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -