// Caller must delete [] dst after use. static void field_text(char** dst, ID3_Frame* frame) { iconv_t cd = iconv_open("UTF8","UTF16BE"); const int bufsize = 1000; char buf[bufsize]; if (NULL != frame) { ID3_Field* field = frame->GetField(ID3FN_TEXT); if (NULL != field) { switch(field->GetEncoding()){ case ID3TE_UTF16: case ID3TE_UTF16BE: // Convert to UTF-8 before returning the data to Go. if ( cd != (iconv_t) -1 ) { char* in = (char*) field->GetRawUnicodeText(); size_t insize = field->Size(); char* bufptr = buf; size_t bufbytes = bufsize; size_t rc = 0; // Initialize iconv state if( iconv(cd, NULL, NULL, &bufptr, &bufbytes) == (size_t) -1 ){ *dst = empty_string(); break; } if ( (rc = iconv(cd, &in, &insize, &bufptr, &bufbytes)) != (size_t) -1 ) { *bufptr = '\0'; *dst = new char[bufsize-bufbytes+1]; memcpy(*dst, buf, bufsize-bufbytes); (*dst)[bufsize-bufbytes] = '\0'; } else { *dst = empty_string(); } } else { *dst = empty_string(); } break; default: // Ascii *dst = new char[field->Size()+1]; (*dst)[0] = '\0'; size_t len = field->Get(*dst, field->Size()+1); (*dst)[field->Size()] = '\0'; } } } iconv_close(cd); }
//following routine courtesy of John George size_t ID3_GetPictureDataOfPicType(ID3_Tag* tag, const char* TempPicPath, ID3_PictureType pictype) { if (NULL == tag) return 0; else { ID3_Frame* frame = NULL; ID3_Tag::Iterator* iter = tag->CreateIterator(); while (NULL != (frame = iter->GetNext() )) { if(frame->GetID() == ID3FID_PICTURE) { if(frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32)pictype) break; } } delete iter; if (frame != NULL) { ID3_Field* myField = frame->GetField(ID3FN_DATA); if (myField != NULL) { myField->ToFile(TempPicPath); return (size_t)myField->Size(); } else return 0; } else return 0; } }
/* LPCTSTR means const char * */ size_t RemoveFrame(ID3_Tag& pTag, ID3_FrameID fID, LPCTSTR sDescription) { size_t nCount = 0; const ID3_Frame * frame = NULL; do { if (!sDescription) { cerr << "*** description is null" << endl; frame = pTag.Find(fID); } else { cerr << "*** description is \"" << sDescription << "\"" << endl; frame = pTag.Find(fID, ID3FN_DESCRIPTION, sDescription); } if (frame) { ID3_Field* fld = frame->GetField(ID3FN_TEXT); String text(fld->GetRawText(), fld->Size()); cerr << "*** delete frame with text \"" << text << "\"" << endl; /* pTag is an ID3_Tag */ delete pTag.RemoveFrame(frame); nCount++; } } while (frame != NULL); return nCount; }
ID3_Frame *ID3_TagImpl::Find(ID3_FrameID id, ID3_FieldID fldID, String data) const { ID3_Frame *frame = NULL; ID3D_NOTICE( "Find: looking for comment with data = " << data.c_str() ); // reset the cursor if it isn't set if (_frames.end() == _cursor) { _cursor = _frames.begin(); ID3D_NOTICE( "Find: resetting cursor" ); } for (int iCount = 0; iCount < 2 && frame == NULL; iCount++) { ID3D_NOTICE( "Find: iCount = " << iCount ); // We want to cycle through the list to find the matching frame. We // should begin from the cursor, search each successive frame, wrapping // if necessary. The enclosing loop and the assignment statments below // ensure that we first begin at the cursor and search to the end of the // list and, if unsuccessful, start from the beginning of the list and // search to the cursor. const_iterator begin = (0 == iCount ? _cursor : _frames.begin()), end = (0 == iCount ? _frames.end() : _cursor); // search from the cursor to the end for (const_iterator cur = begin; cur != end; ++cur) { ID3D_NOTICE( "Find: frame = 0x" << hex << (uint32) *cur << dec ); if ((*cur != NULL) && ((*cur)->GetID() == id) && (*cur)->Contains(fldID)) { ID3_Field* fld = (*cur)->GetField(fldID); if (NULL == fld) { continue; ID3D_NOTICE( "Find: didn't have the right field" ); } String text( NULL == fld->GetRawText() ? "" : fld->GetRawText() , fld->Size()); //PHF ID3D_NOTICE( "Find: text = " << text.c_str() ); if (text == data) { // We've found a valid frame. Set cursor to be the next element frame = *cur; _cursor = ++cur; break; } } } } return frame; }
BString id3::v2::getSyncLyrics(const ID3_TagImpl& tag, String lang, String desc) { // check if a SYLT frame of this language or descriptor exists ID3_Frame* frame = NULL; (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang.c_str())) || (frame = tag.Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc.c_str())) || (frame = tag.Find(ID3FID_SYNCEDLYRICS)); // get the lyrics size ID3_Field* fld = frame->GetField(ID3FN_DATA); return BString(reinterpret_cast<const BString::value_type *>(fld->GetRawBinary()), fld->Size()); }
QPixmap PlaybackControls::getPicture(QString file) { QPixmap field; ID3_Tag mTag(file.toStdString().c_str()); ID3_Frame* myFrame = mTag.Find(ID3FID_PICTURE); if (myFrame) { ID3_Field* myField = myFrame->GetField(ID3FN_DATA); if (myField) { const uchar *test = myField->GetRawBinary(); field.loadFromData(test, myField->Size()); } } return field; }
ID3_Frame *ID3_TagImpl::Find(ID3_FrameID id, ID3_FieldID fldID, WString data) const { ID3_Frame *frame = NULL; // reset the cursor if it isn't set if (_frames.end() == _cursor) { _cursor = _frames.begin(); } for (int iCount = 0; iCount < 2 && frame == NULL; iCount++) { // We want to cycle through the list to find the matching frame. We // should begin from the cursor, search each successive frame, wrapping // if necessary. The enclosing loop and the assignment statments below // ensure that we first begin at the cursor and search to the end of the // list and, if unsuccessful, start from the beginning of the list and // search to the cursor. const_iterator begin = (0 == iCount ? _cursor : _frames.begin()), end = (0 == iCount ? _frames.end() : _cursor); // search from the cursor to the end for (const_iterator cur = begin; cur != end; ++cur) { if ((*cur != NULL) && ((*cur)->GetID() == id) && (*cur)->Contains(fldID)) { ID3_Field* fld = (*cur)->GetField(fldID); if (NULL == fld) { continue; } WString text = toWString(fld->GetRawUnicodeText(), fld->Size()); if (text == data) { // We've found a valid frame. Set cursor to be the next element frame = *cur; _cursor = ++cur; break; } } } } return frame; }
char *ID3_GetString(const ID3_Frame *frame, ID3_FieldID fldName) { char *text = NULL; // if (NULL != frame) ID3_Field* fld; if (NULL != frame && NULL != (fld = frame->GetField(fldName))) { // ID3_Field* fld = frame->GetField(fldName); ID3_TextEnc enc = fld->GetEncoding(); fld->SetEncoding(ID3TE_ISO8859_1); size_t nText = fld->Size(); text = new char[nText + 1]; fld->Get(text, nText + 1); fld->SetEncoding(enc); } return text; }
String id3::v2::getString(const ID3_Frame* frame, ID3_FieldID fldName) { if (!frame) { return ""; } ID3_Field* fp = frame->GetField(fldName); if (!fp) { return ""; } ID3_TextEnc enc = fp->GetEncoding(); fp->SetEncoding(ID3TE_ASCII); String text(fp->GetRawText(), fp->Size()); fp->SetEncoding(enc); return text; }
//following routine courtesy of John George int ID3_GetPictureData(const ID3_Tag *tag, const char *TempPicPath) { if (NULL == tag) return 0; else { ID3_Frame* frame = NULL; frame = tag->Find(ID3FID_PICTURE); if (frame != NULL) { ID3_Field* myField = frame->GetField(ID3FN_DATA); if (myField != NULL) { myField->ToFile(TempPicPath); return (int)myField->Size(); } else return 0; } else return 0; } }
void play_debug_meta(char* filename){ ID3_Tag tag(filename); ID3_Tag::Iterator* iter = tag.CreateIterator(); ID3_Frame* frame = NULL; char buf[1000]; // Iconv conversion descriptor: UTF-16 -> UTF-8 iconv_t cd = iconv_open("UTF8","UTF16BE"); while (NULL != (frame = iter->GetNext())) { char* val = NULL; field_text(&val, frame); printf("Frame: type %d %s %s:\n", frame->GetID(), frame->GetTextID(), frame->GetDescription()); ID3_Frame::Iterator* fieldIter = frame->CreateIterator(); ID3_Field* field = NULL; while (NULL != (field = fieldIter->GetNext())) { printf(" Field: type "); ID3_FieldType type = field->GetType(); switch(type) { case ID3FTY_NONE: printf("none"); break; case ID3FTY_INTEGER: printf("int"); break; case ID3FTY_BINARY: printf("binary"); break; case ID3FTY_TEXTSTRING: field->Get(buf, 1000); printf("text with %d items, encoding ", field->GetNumTextItems()); switch(field->GetEncoding()){ case ID3TE_UTF16: printf("UTF-16"); if ( cd != (iconv_t) -1 ) { char* in = (char*) field->GetRawUnicodeText(); size_t insize = field->Size(); char* bufptr = buf; size_t bufsize = 1000; size_t rc = 0; // Initialize iconv state if( iconv(cd, NULL, NULL, &bufptr, &bufsize) == (size_t) -1 ){ printf("iconv init Failed\n"); } if ( (rc = iconv(cd, &in, &insize, &bufptr, &bufsize)) != (size_t) -1 ) { *bufptr = '\0'; printf(": '%s' (%d chars)\n", buf, rc); } else { printf("<conversion using iconv failed>"); perror("iconv"); } } break; case ID3TE_UTF16BE: printf("UTF-16BE"); printf(": '%s'", buf); break; case ID3TE_UTF8: printf("UTF-8"); printf(": '%s'", buf); break; case ID3TE_NONE: printf("none"); printf(": '%s'", buf); break; case ID3TE_ISO8859_1: printf("ISO-8859-1/ASCII"); printf(": '%s'", buf); break; } break; } printf("\n"); } delete fieldIter; delete [] val; } delete iter; iconv_close(cd); }