📄 id3tag.c
字号:
p = 0; // no saved bytes XAR_SeekFile(song_info, n, 0); } res = XAR_ReadFile(song_info, buffer + p, cnt, IO_READ_CACHE); // fill rest of buffer load_pos = n; if(!res) return E_READ_FAILURE; } // set string leading byte address song_info->strings[song_info->strtop] = 0 ; // to indicate that no characters were added so far //song_info->infos[song_info->n_infos].pstring = song_info->strings + song_info->strtop; song_info->infos[song_info->n_infos].string_offset = song_info->strtop; frID = (buffer[pos - load_pos] << 16) + (buffer[pos - load_pos + 1] << 8) + buffer[pos - load_pos + 2]; if(id32rev!=2) frID = (frID << 8) + buffer[pos - load_pos + 3]; frflags = (buffer[pos - load_pos + 8] << 8) + buffer[pos-load_pos + 9]; processing_switch = ID32_READ_DATA; switch(id32rev) { case 2: id_frtop = (buffer[pos - load_pos + 3] << 16) + (buffer[pos - load_pos + 4] << 8) + buffer[pos - load_pos + 5]; if(!id_frtop) { processing_switch = ID32_TERMINATE; break; } id_data = pos+6; id_frtop += id_data; switch(frID) // revision 2 { case TXT_TAL: song_info->infos[song_info->n_infos].info_type = ALBUM_TITLE; break; case TXT_TT2: song_info->infos[song_info->n_infos].info_type = SONG_TITLE; break; case TXT_TP1: song_info->infos[song_info->n_infos].info_type = ARTIST; break; case TXT_COM: if(comment) processing_switch = ID32_FRAME_SKIP; else song_info->infos[song_info->n_infos].info_type = COMMENT; break; case TXT_TYE: song_info->infos[song_info->n_infos].info_type = YEAR; break; case TXT_TCO: song_info->infos[song_info->n_infos].info_type = GENRE; break; case TXT_TRK: song_info->infos[song_info->n_infos].info_type = TRACK_NO; break; default: processing_switch = ID32_FRAME_SKIP; } break; case 3: case 4: if(id32rev == 3) id_frtop = (buffer[pos - load_pos + 4] << 24) + (buffer[pos - load_pos + 5] << 16) + (buffer[pos - load_pos + 6] << 8) + buffer[pos - load_pos + 7]; else id_frtop = (buffer[pos - load_pos + 4] << 21) + (buffer[pos - load_pos + 5] << 14) + (buffer[pos - load_pos + 6] << 7) + buffer[pos - load_pos + 7]; if(!id_frtop) { processing_switch = ID32_TERMINATE; break; } id_data = pos+10; id_frtop += id_data; frflags = (buffer[pos - load_pos + 8] << 8) + buffer[pos - load_pos + 9]; switch(frID) { case TXT_TALB: song_info->infos[song_info->n_infos].info_type = ALBUM_TITLE; break; case TXT_TIT2: song_info->infos[song_info->n_infos].info_type = SONG_TITLE; break; case TXT_TPE1: song_info->infos[song_info->n_infos].info_type = ARTIST; break; case TXT_COMM: if(comment) processing_switch = ID32_FRAME_SKIP; else song_info->infos[song_info->n_infos].info_type = COMMENT; break; case TXT_TYER: song_info->infos[song_info->n_infos].info_type = YEAR; break; case TXT_TCON: song_info->infos[song_info->n_infos].info_type = GENRE; break; case TXT_TRCK: song_info->infos[song_info->n_infos].info_type = TRACK_NO; break; default: processing_switch = ID32_FRAME_SKIP; break; } break; default: return E_UNEXPECTED; } break; case ID32_READ_DATA: if((song_info->n_infos >= XSONG_INFO_TAGS) || (song_info->strtop >= MAX_STRINGS_SIZE - 2)) { processing_switch = ID32_TERMINATE; break; } if(id_frtop > v2_length) { processing_switch = ID32_TERMINATE; break; } if(id_frtop > (load_pos + ID3_BUFFER_LENGTH)) { n = pos & (~3); // new load_pos p = wmin(n + ID3_BUFFER_LENGTH, v2_length); cnt = p - n; if(cnt <= 0) { processing_switch = ID32_TERMINATE; break; } // how many bytes should be prepared in buffer if((n-load_pos)<ID3_BUFFER_LENGTH) // check if data follow continuously { p = ID3_BUFFER_LENGTH - (n - load_pos); // count of present bytes to keep memcpy(buffer, buffer + (n - load_pos), p ); cnt -= p ; } else // not continuous jump ( frame is big ) { p = 0; // no saved bytes XAR_SeekFile(song_info, n, 0); } res = XAR_ReadFile(song_info, buffer + p, cnt, IO_READ_CACHE); // fill rest of buffer load_pos = n; if(!res) return E_READ_FAILURE; } // frame data should be in buffer, at least full buffer if(id32rev != 2) { if(id32rev==3) { cmp_enc = 128+64; gr_iden = 0x20; } else { cmp_enc = 8+4; gr_iden = 0x40; if(frflags & 1) // check length indicator id_data += 4; } if(frflags & cmp_enc) // test encryption & compression { processing_switch = ID32_FRAME_SKIP; goto id32_skipfr; } if(frflags & gr_iden) // test group identity { id_data += 1; } } // start parsing string id32_encoding = (t_TextEncoding)buffer[id_data - load_pos]; id_data++; /* All ID3v2 tags are stored as UTF-8 Pascal strings, keep track of the ** original encoding type used in the file. */ song_info->infos[song_info->n_infos].enc_of_src = id32_encoding; song_info->infos[song_info->n_infos].tag_version = 2; if(id_data>=id_frtop) // ignore frame when contains only encoding byte { processing_switch = ID32_FRAME_SKIP; goto id32_skipfr; } switch(id32_encoding) { case TEXT_ENCODING_ISO_8859_1: /* ISO-8859-1, terminated with 0x00. */ utf8_conv = 1; asc_loop: chcnt = cnt0 = 0; p = 1; if(song_info->infos[song_info->n_infos].info_type != COMMENT) goto id3_unic_skip2; for(i=0;i<3;i++) { if(!buffer[id_data-load_pos+i]) cnt0++; if((buffer[id_data-load_pos+i]>96) &&(buffer[id_data-load_pos+i]<123) && ((id_data - load_pos + i) < ID3_BUFFER_LENGTH) && (id_data + i < id_frtop )) { chcnt++; } } if(((cnt0==3)||(chcnt == 3))&& (!buffer[id_data-load_pos+i])) { id_data += 4; // skip language descriptor } chcnt = 0; id3_unic_skip2: while(p && ((id_data - load_pos) < ID3_BUFFER_LENGTH) && (id_data < id_frtop)) { word = buffer[id_data - load_pos]; if(utf8_conv) { p = write_utf8(song_info,word); } else { p = write_byte(song_info,word); // it is already UTF-8 byte } chcnt += p; id_data++; } if(chcnt>0) { /* JS fix 11.9.2007 - first check COMM presence before ptr is increased */ if(song_info->infos[song_info->n_infos].info_type == COMMENT) comment = 1; song_info->n_infos++; } processing_switch = ID32_FRAME_SKIP; // continue with next frame break; case TEXT_ENCODING_UTF_16: /* UTF-16 encoded Unicode with BOM, terminated with 0x00. */ case TEXT_ENCODING_UTF_16BE: /* UTF-16BE encoded Unicode without BOM, terminated with 0x00. */ id_be = 1; chcnt = cnt0 = 0; p = 1; if(song_info->infos[song_info->n_infos].info_type != COMMENT) goto id3_unic_skip; for(i=0;i<3;i++) { if(!buffer[id_data-load_pos+i]) cnt0++; if((buffer[id_data-load_pos+i]>96) &&(buffer[id_data-load_pos+i]<123) && ((id_data - load_pos + i) < ID3_BUFFER_LENGTH) && (id_data + i < id_frtop )) { chcnt++; } } if((chcnt == 3)||(cnt0==3)) { chcnt = 0; for(i=0;i<3;i++) { // chcnt += write_byte(song_info,buffer[id_data-load_pos+i]); } id_data += 5; // skip language descriptor //if( chcnt < 3) // goto id3_nodata; } else { chcnt = 0; }id3_unic_skip: while(p && ((id_data - load_pos) < ID3_BUFFER_LENGTH) && (id_data < id_frtop)) { word = (buffer[id_data-load_pos]<<8) + buffer[id_data-load_pos+1]; switch(word) { //case 0: // id_data += 2; // break; case 0xFEFF: id_be = 1; id_data += 2; break; case 0xFFFE: id_be = 0; id_data += 2; break; default: if(!id_be) // format word to BE { word = ((word&0xff)<<8) + ((word&0xff00)>>8); } if((id32rev==4)&&((word&0xFC00)==0xD800)) { id_data +=4 ; // skip surrogate pair } else { p = write_utf8(song_info,word); chcnt += p; id_data += 2; } } } if(chcnt>0) { /* JS fix 11.9.2007 - first check COMM presence before ptr is increased */ if(song_info->infos[song_info->n_infos].info_type == COMMENT) comment = 1; song_info->n_infos++; }//id3_nodata: processing_switch = ID32_FRAME_SKIP; // continue with next frame break; case TEXT_ENCODING_UTF_8: /* UTF-8 encoded Unicode, terminated with 0x00. */ utf8_conv = 0; goto asc_loop; default: processing_switch = ID32_FRAME_SKIP; goto id32_skipfr; } id32_skipfr: break; case ID32_FRAME_SKIP: pos = id_frtop; if(pos<v2_length) processing_switch = ID32_FIND_FRAME; else processing_switch = ID32_TERMINATE; break; case ID32_TERMINATE: return S_OK; default: return E_UNEXPECTED; } } // while } __inline int hdr_to_frps2(frame_params *fr_ps){ layer *hdr = &fr_ps->header; /* (or pass in as arg?) */ fr_ps->stereo = (char) ((hdr->mode == MPG_MD_MONO) ? 1 : 2 ); return 0; /* all is well */}static __inline void decode_packed_info(unsigned int packed_info, layer *hdr){ int b0,b1,b2,b3; b0 = packed_info >> 19;#if SUPPORT_MPEG2_5 b0 ^= 2; /* invert bit so 1 => MPEG 2.5 */ b0 = b0 & ~(b0>>1); /* clear non-LSF flag if MPEG 2.5 */#endif b1 = (packed_info >> 17) & 3; // rlay b2 = 1 ^ (( packed_info >> 16) & 1); // protection_bit b3 = (packed_info >> 12) & 15; // bitrate_index#ifdef __BIG_ENDIAN ((int *)hdr)[0] = b3 | (b2<<8) | (b1<<16) | (b0<<24);#else ((int *)hdr)[0] = b0 | (b1<<8) | (b2<<16) | (b3<<24);#endif b0 = (packed_info >> 10) & 3; // sampling_frequency b1 = (packed_info >> 9) & 1; // padding_bit b2 = (packed_info >> 6) & 3; // mode b3 = (packed_info >> 4) & 3; // mode extension#ifdef __BIG_ENDIAN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -