1 // $Id: misc_support.cpp,v 1.39 2002/09/19 10:20:45 t1mpy Exp $
2
3 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
4 // Copyright 1999, 2000 Scott Thomas Haug
5 // Copyright 2002 Thijmen Klok (thijmen@id3lib.org)
6
7 // This library is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU Library General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or (at your
10 // option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Library General Public License
18 // along with this library; if not, write to the Free Software Foundation,
19 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21 // The id3lib authors encourage improvements and optimisations to be sent to
22 // the id3lib coordinator. Please see the README file for details on where to
23 // send such submissions. See the AUTHORS file for a list of people who have
24 // contributed to id3lib. See the ChangeLog file for a list of changes to
25 // id3lib. These files are distributed with id3lib at
26 // http://download.sourceforge.net/id3lib/
27
28 //#include <ctype.h>
29 #include <stdio.h>
30
31 #include "misc_support.h"
32 //#include "field.h"
33 #include "id3/utils.h" // has <config.h> "id3/id3lib_streams.h" "id3/globals.h" "id3/id3lib_strings.h"
34
35 //using namespace dami;
36
ID3_GetString(const ID3_Frame * frame,ID3_FieldID fldName)37 char *ID3_GetString(const ID3_Frame *frame, ID3_FieldID fldName)
38 {
39 char *text = NULL;
40 // if (NULL != frame)
41 ID3_Field* fld;
42 if (NULL != frame && NULL != (fld = frame->GetField(fldName)))
43 {
44 // ID3_Field* fld = frame->GetField(fldName);
45 ID3_TextEnc enc = fld->GetEncoding();
46 fld->SetEncoding(ID3TE_ISO8859_1);
47 size_t nText = fld->Size();
48 text = new char[nText + 1];
49 fld->Get(text, nText + 1);
50 fld->SetEncoding(enc);
51 }
52 return text;
53 }
54
ID3_GetString(const ID3_Frame * frame,ID3_FieldID fldName,size_t nIndex)55 char *ID3_GetString(const ID3_Frame *frame, ID3_FieldID fldName, size_t nIndex)
56 {
57 char *text = NULL;
58 if (NULL != frame)
59 {
60 size_t nText = frame->GetField(fldName)->Size();
61 text = new char[nText + 1];
62 frame->GetField(fldName)->Get(text, nText + 1, nIndex);
63 }
64 return text;
65 }
66
ID3_FreeString(char * str)67 void ID3_FreeString(char *str)
68 {
69 if(str != NULL)
70 delete [] str;
71 }
72
ID3_GetArtist(const ID3_Tag * tag)73 char *ID3_GetArtist(const ID3_Tag *tag)
74 {
75 char *sArtist = NULL;
76 if (NULL == tag)
77 {
78 return sArtist;
79 }
80
81 ID3_Frame *frame = NULL;
82 if ((frame = tag->Find(ID3FID_LEADARTIST)) ||
83 (frame = tag->Find(ID3FID_BAND)) ||
84 (frame = tag->Find(ID3FID_CONDUCTOR)) ||
85 (frame = tag->Find(ID3FID_COMPOSER)))
86 {
87 sArtist = ID3_GetString(frame, ID3FN_TEXT);
88 }
89 return sArtist;
90 }
91
ID3_AddArtist(ID3_Tag * tag,const char * text,bool replace)92 ID3_Frame* ID3_AddArtist(ID3_Tag *tag, const char *text, bool replace)
93 {
94 ID3_Frame* frame = NULL;
95 if (NULL != tag && NULL != text && strlen(text) > 0)
96 {
97 if (replace)
98 {
99 ID3_RemoveArtists(tag);
100 }
101 if (replace ||
102 (tag->Find(ID3FID_LEADARTIST) == NULL &&
103 tag->Find(ID3FID_BAND) == NULL &&
104 tag->Find(ID3FID_CONDUCTOR) == NULL &&
105 tag->Find(ID3FID_COMPOSER) == NULL))
106 {
107 frame = new ID3_Frame(ID3FID_LEADARTIST);
108 if (frame)
109 {
110 frame->GetField(ID3FN_TEXT)->Set(text);
111 tag->AttachFrame(frame);
112 }
113 }
114 }
115 return frame;
116 }
117
ID3_RemoveArtists(ID3_Tag * tag)118 size_t ID3_RemoveArtists(ID3_Tag *tag)
119 {
120 size_t num_removed = 0;
121 ID3_Frame *frame = NULL;
122
123 if (NULL == tag)
124 {
125 return num_removed;
126 }
127
128 while ((frame = tag->Find(ID3FID_LEADARTIST)))
129 {
130 frame = tag->RemoveFrame(frame);
131 delete frame;
132 num_removed++;
133 }
134 while ((frame = tag->Find(ID3FID_BAND)))
135 {
136 frame = tag->RemoveFrame(frame);
137 delete frame;
138 num_removed++;
139 }
140 while ((frame = tag->Find(ID3FID_CONDUCTOR)))
141 {
142 frame = tag->RemoveFrame(frame);
143 delete frame;
144 num_removed++;
145 }
146 while ((frame = tag->Find(ID3FID_COMPOSER)))
147 {
148 frame = tag->RemoveFrame(frame);
149 delete frame;
150 num_removed++;
151 }
152
153 return num_removed;
154 }
155
ID3_GetAlbum(const ID3_Tag * tag)156 char *ID3_GetAlbum(const ID3_Tag *tag)
157 {
158 char *sAlbum = NULL;
159 if (NULL == tag)
160 {
161 return sAlbum;
162 }
163
164 ID3_Frame *frame = tag->Find(ID3FID_ALBUM);
165 if (frame != NULL)
166 {
167 sAlbum = ID3_GetString(frame, ID3FN_TEXT);
168 }
169 return sAlbum;
170 }
171
ID3_AddAlbum(ID3_Tag * tag,const char * text,bool replace)172 ID3_Frame* ID3_AddAlbum(ID3_Tag *tag, const char *text, bool replace)
173 {
174 ID3_Frame* frame = NULL;
175 if (NULL != tag && NULL != text && strlen(text) > 0)
176 {
177 if (replace)
178 {
179 ID3_RemoveAlbums(tag);
180 }
181 if (replace || tag->Find(ID3FID_ALBUM) == NULL)
182 {
183 frame = new ID3_Frame(ID3FID_ALBUM);
184 if (frame)
185 {
186 frame->GetField(ID3FN_TEXT)->Set(text);
187 tag->AttachFrame(frame);
188 }
189 }
190 }
191
192 return frame;
193 }
194
ID3_RemoveAlbums(ID3_Tag * tag)195 size_t ID3_RemoveAlbums(ID3_Tag *tag)
196 {
197 size_t num_removed = 0;
198 ID3_Frame *frame = NULL;
199
200 if (NULL == tag)
201 {
202 return num_removed;
203 }
204
205 while ((frame = tag->Find(ID3FID_ALBUM)))
206 {
207 frame = tag->RemoveFrame(frame);
208 delete frame;
209 num_removed++;
210 }
211
212 return num_removed;
213 }
214
ID3_GetTitle(const ID3_Tag * tag)215 char *ID3_GetTitle(const ID3_Tag *tag)
216 {
217 char *sTitle = NULL;
218 if (NULL == tag)
219 {
220 return sTitle;
221 }
222
223 ID3_Frame *frame = tag->Find(ID3FID_TITLE);
224 if (frame != NULL)
225 {
226 sTitle = ID3_GetString(frame, ID3FN_TEXT);
227 }
228 return sTitle;
229 }
230
ID3_AddTitle(ID3_Tag * tag,const char * text,bool replace)231 ID3_Frame* ID3_AddTitle(ID3_Tag *tag, const char *text, bool replace)
232 {
233 ID3_Frame* frame = NULL;
234 if (NULL != tag && NULL != text && strlen(text) > 0)
235 {
236 if (replace)
237 {
238 ID3_RemoveTitles(tag);
239 }
240 if (replace || tag->Find(ID3FID_TITLE) == NULL)
241 {
242 frame = new ID3_Frame(ID3FID_TITLE);
243 if (frame)
244 {
245 frame->GetField(ID3FN_TEXT)->Set(text);
246 tag->AttachFrame(frame);
247 }
248 }
249 }
250
251 return frame;
252 }
253
ID3_RemoveTitles(ID3_Tag * tag)254 size_t ID3_RemoveTitles(ID3_Tag *tag)
255 {
256 size_t num_removed = 0;
257 ID3_Frame *frame = NULL;
258
259 if (NULL == tag)
260 {
261 return num_removed;
262 }
263
264 while ((frame = tag->Find(ID3FID_TITLE)))
265 {
266 frame = tag->RemoveFrame(frame);
267 delete frame;
268 num_removed++;
269 }
270
271 return num_removed;
272 }
273
ID3_GetYear(const ID3_Tag * tag)274 char *ID3_GetYear(const ID3_Tag *tag)
275 {
276 char *sYear = NULL;
277 if (NULL == tag)
278 {
279 return sYear;
280 }
281
282 ID3_Frame *frame = tag->Find(ID3FID_YEAR);
283 if (frame != NULL)
284 {
285 sYear = ID3_GetString(frame, ID3FN_TEXT);
286 }
287 return sYear;
288 }
289
ID3_AddYear(ID3_Tag * tag,const char * text,bool replace)290 ID3_Frame* ID3_AddYear(ID3_Tag *tag, const char *text, bool replace)
291 {
292 ID3_Frame* frame = NULL;
293 if (NULL != tag && NULL != text && strlen(text) > 0)
294 {
295 if (replace)
296 {
297 ID3_RemoveYears(tag);
298 }
299 if (replace || tag->Find(ID3FID_YEAR) == NULL)
300 {
301 frame = new ID3_Frame(ID3FID_YEAR);
302 if (NULL != frame)
303 {
304 frame->GetField(ID3FN_TEXT)->Set(text);
305 tag->AttachFrame(frame);
306 }
307 }
308 }
309
310 return frame;
311 }
312
ID3_RemoveYears(ID3_Tag * tag)313 size_t ID3_RemoveYears(ID3_Tag *tag)
314 {
315 size_t num_removed = 0;
316 ID3_Frame *frame = NULL;
317
318 if (NULL == tag)
319 {
320 return num_removed;
321 }
322
323 while ((frame = tag->Find(ID3FID_YEAR)))
324 {
325 frame = tag->RemoveFrame(frame);
326 delete frame;
327 num_removed++;
328 }
329
330 return num_removed;
331 }
332
ID3_GetComment(const ID3_Tag * tag,const char * desc)333 char *ID3_GetComment(const ID3_Tag *tag, const char* desc)
334 {
335 char *comment = NULL;
336 if (NULL == tag)
337 {
338 return comment;
339 }
340
341 ID3_Frame* frame = NULL;
342 if (desc)
343 {
344 frame = tag->Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, desc);
345 }
346 else
347 {
348 frame = tag->Find(ID3FID_COMMENT);
349 if(frame == tag->Find(ID3FID_COMMENT, ID3FN_DESCRIPTION, STR_V1_COMMENT_DESC))
350 frame = tag->Find(ID3FID_COMMENT);
351 }
352
353 if (frame)
354 comment = ID3_GetString(frame, ID3FN_TEXT);
355 return comment;
356 }
357
ID3_AddComment(ID3_Tag * tag,const char * text,bool replace)358 ID3_Frame* ID3_AddComment(ID3_Tag *tag, const char *text, bool replace)
359 {
360 return ID3_AddComment(tag, text, "", replace);
361 }
362
ID3_AddComment(ID3_Tag * tag,const char * text,const char * desc,bool replace)363 ID3_Frame* ID3_AddComment(ID3_Tag *tag, const char *text,
364 const char *desc, bool replace)
365 {
366 return ID3_AddComment(tag, text, desc, "XXX", replace);
367 }
368
ID3_AddComment(ID3_Tag * tag,const char * text,const char * desc,const char * lang,bool replace)369 ID3_Frame* ID3_AddComment(ID3_Tag *tag, const char *text,
370 const char *desc, const char* lang, bool replace)
371 {
372 ID3_Frame* frame = NULL;
373 if (NULL != tag &&
374 NULL != text &&
375 NULL != desc &&
376 strlen(text) > 0)
377 {
378 bool bAdd = true;
379 if (replace)
380 {
381 ID3_RemoveComments(tag, desc);
382 }
383 else
384 {
385 // See if there is already a comment with this description
386 ID3_Tag::Iterator* iter = tag->CreateIterator();
387 ID3_Frame* frame = NULL;
388 while ((frame = iter->GetNext()) != NULL)
389 {
390 if (frame->GetID() == ID3FID_COMMENT)
391 {
392 char *tmp_desc = ID3_GetString(frame, ID3FN_DESCRIPTION);
393 if (strcmp(tmp_desc, desc) == 0)
394 {
395 bAdd = false;
396 }
397 delete [] tmp_desc;
398 if (!bAdd)
399 {
400 break;
401 }
402 }
403 }
404 delete iter;
405 }
406 if (bAdd)
407 {
408 frame = new ID3_Frame(ID3FID_COMMENT);
409 if (NULL != frame)
410 {
411 frame->GetField(ID3FN_LANGUAGE)->Set(lang);
412 frame->GetField(ID3FN_DESCRIPTION)->Set(desc);
413 frame->GetField(ID3FN_TEXT)->Set(text);
414 tag->AttachFrame(frame);
415 }
416 }
417 }
418 return frame;
419 }
420
421 // Remove all comments with the given description (remove all comments if
422 // desc is NULL)
ID3_RemoveComments(ID3_Tag * tag,const char * desc)423 size_t ID3_RemoveComments(ID3_Tag *tag, const char *desc)
424 {
425 size_t num_removed = 0;
426
427 if (NULL == tag)
428 {
429 return num_removed;
430 }
431
432 ID3_Tag::Iterator* iter = tag->CreateIterator();
433 ID3_Frame* frame = NULL;
434 while ((frame = iter->GetNext()) != NULL)
435 {
436 if (frame->GetID() == ID3FID_COMMENT)
437 {
438 bool remove = false;
439 // A null description means remove all comments
440 if (NULL == desc)
441 {
442 remove = true;
443 }
444 else
445 {
446 // See if the description we have matches the description of the
447 // current comment. If so, set the "remove the comment" flag to true.
448 char *tmp_desc = ID3_GetString(frame, ID3FN_DESCRIPTION);
449 remove = (strcmp(tmp_desc, desc) == 0);
450 delete [] tmp_desc;
451 }
452 if (remove)
453 {
454 frame = tag->RemoveFrame(frame);
455 delete frame;
456 num_removed++;
457 }
458 }
459 }
460 delete iter;
461
462 return num_removed;
463 }
464
ID3_GetTrack(const ID3_Tag * tag)465 char *ID3_GetTrack(const ID3_Tag *tag)
466 {
467 char *sTrack = NULL;
468 if (NULL == tag)
469 {
470 return sTrack;
471 }
472
473 ID3_Frame *frame = tag->Find(ID3FID_TRACKNUM);
474 if (frame != NULL)
475 {
476 sTrack = ID3_GetString(frame, ID3FN_TEXT);
477 }
478 return sTrack;
479 }
480
ID3_GetTrackNum(const ID3_Tag * tag)481 size_t ID3_GetTrackNum(const ID3_Tag *tag)
482 {
483 char *sTrack = ID3_GetTrack(tag);
484 size_t nTrack = 0;
485 if (NULL != sTrack)
486 {
487 nTrack = atoi(sTrack);
488 delete [] sTrack;
489 }
490 return nTrack;
491 }
492
ID3_AddTrack(ID3_Tag * tag,uchar trk,uchar ttl,bool replace)493 ID3_Frame* ID3_AddTrack(ID3_Tag *tag, uchar trk, uchar ttl, bool replace)
494 {
495 ID3_Frame* frame = NULL;
496 if (NULL != tag && trk > 0)
497 {
498 if (replace)
499 {
500 ID3_RemoveTracks(tag);
501 }
502 if (replace || NULL == tag->Find(ID3FID_TRACKNUM))
503 {
504 frame = new ID3_Frame(ID3FID_TRACKNUM);
505 if (frame)
506 {
507 char *sTrack = NULL;
508 if (0 == ttl)
509 {
510 sTrack = new char[4];
511 sprintf(sTrack, "%lu", (luint) trk);
512 }
513 else
514 {
515 sTrack = new char[8];
516 sprintf(sTrack, "%lu/%lu", (luint) trk, (luint) ttl);
517 }
518
519 frame->GetField(ID3FN_TEXT)->Set(sTrack);
520 tag->AttachFrame(frame);
521
522 delete [] sTrack;
523 }
524 }
525 }
526
527 return frame;
528 }
529
530 //following routine courtesy of John George
ID3_GetPictureData(const ID3_Tag * tag,const char * TempPicPath)531 int ID3_GetPictureData(const ID3_Tag *tag, const char *TempPicPath)
532 {
533 if (NULL == tag)
534 return 0;
535 else
536 {
537 ID3_Frame* frame = NULL;
538 frame = tag->Find(ID3FID_PICTURE);
539 if (frame != NULL)
540 {
541 ID3_Field* myField = frame->GetField(ID3FN_DATA);
542 if (myField != NULL)
543 {
544 myField->ToFile(TempPicPath);
545 return (int)myField->Size();
546 }
547 else return 0;
548 }
549 else return 0;
550 }
551 }
552
553 //following routine courtesy of John George
ID3_GetPictureMimeType(const ID3_Tag * tag)554 char* ID3_GetPictureMimeType(const ID3_Tag *tag)
555 {
556 char* sPicMimetype = NULL;
557 if (NULL == tag)
558 return sPicMimetype;
559
560 ID3_Frame* frame = NULL;
561 frame = tag->Find(ID3FID_PICTURE);
562 if (frame != NULL)
563 {
564 sPicMimetype = ID3_GetString(frame, ID3FN_MIMETYPE);
565 }
566 return sPicMimetype;
567 }
568
569 //following routine courtesy of John George
ID3_HasPicture(const ID3_Tag * tag)570 bool ID3_HasPicture(const ID3_Tag* tag)
571 {
572 if (NULL == tag)
573 return false;
574 else
575 {
576 ID3_Frame* frame = tag->Find(ID3FID_PICTURE);
577 if (frame != NULL)
578 {
579 ID3_Field* myField = frame->GetField(ID3FN_DATA);
580 if (myField != NULL)
581 return true;
582 else
583 return false;
584 }
585 else return false;
586 }
587 }
588
589 //following routine courtesy of John George
ID3_AddPicture(ID3_Tag * tag,const char * TempPicPath,const char * MimeType,bool replace)590 ID3_Frame* ID3_AddPicture(ID3_Tag* tag, const char* TempPicPath, const char* MimeType, bool replace)
591 {
592 ID3_Frame* frame = NULL;
593 if (NULL != tag )
594 {
595 if (replace)
596 ID3_RemovePictures(tag);
597 if (replace || NULL == tag->Find(ID3FID_PICTURE))
598 {
599 frame = new ID3_Frame(ID3FID_PICTURE);
600 if (NULL != frame)
601 {
602 frame->GetField(ID3FN_DATA)->FromFile(TempPicPath);
603 frame->GetField(ID3FN_MIMETYPE)->Set(MimeType);
604 tag->AttachFrame(frame);
605 }
606 }
607 }
608 return frame;
609 }
610
611 //following routine courtesy of John George
ID3_RemovePictures(ID3_Tag * tag)612 size_t ID3_RemovePictures(ID3_Tag* tag)
613 {
614 size_t num_removed = 0;
615 ID3_Frame* frame = NULL;
616
617 if (NULL == tag)
618 return num_removed;
619
620 while ((frame = tag->Find(ID3FID_PICTURE)))
621 {
622 frame = tag->RemoveFrame(frame);
623 delete frame;
624 num_removed++;
625 }
626 return num_removed;
627 }
628
629 //following routine courtesy of John George
ID3_RemovePictureType(ID3_Tag * tag,ID3_PictureType pictype)630 size_t ID3_RemovePictureType(ID3_Tag* tag, ID3_PictureType pictype)
631 {
632 size_t bremoved = 0;
633 ID3_Frame* frame = NULL;
634
635 if (NULL == tag)
636 return bremoved;
637
638 ID3_Tag::Iterator* iter = tag->CreateIterator();
639
640 while (NULL != (frame = iter->GetNext()))
641 {
642 if (frame->GetID() == ID3FID_PICTURE)
643 {
644 if (frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32)pictype)
645 break;
646 }
647 }
648 delete iter;
649
650 if (NULL != frame)
651 {
652 frame = tag->RemoveFrame(frame);
653 delete frame;
654 bremoved = 1;
655 }
656 return bremoved;
657 }
658
659 //following routine courtesy of John George
ID3_AddPicture(ID3_Tag * tag,const char * TempPicPath,const char * MimeType,ID3_PictureType pictype,const char * Description,bool replace)660 ID3_Frame* ID3_AddPicture(ID3_Tag *tag, const char *TempPicPath, const char *MimeType, ID3_PictureType pictype, const char* Description, bool replace)
661 {
662 ID3_Frame* frame = NULL;
663 if (NULL != tag )
664 {
665 if (replace)
666 ID3_RemovePictureType(tag, pictype);
667 if (replace || NULL == tag->Find(ID3FID_PICTURE))
668 {
669 frame = new ID3_Frame(ID3FID_PICTURE);
670 if (NULL != frame)
671 {
672 frame->GetField(ID3FN_DATA)->FromFile(TempPicPath);
673 frame->GetField(ID3FN_MIMETYPE)->Set(MimeType);
674 frame->GetField(ID3FN_PICTURETYPE)->Set((uint32)pictype);
675 frame->GetField(ID3FN_DESCRIPTION)->Set(Description);
676 tag->AttachFrame(frame);
677 }
678 }
679 }
680 return frame;
681 }
682
683 //following routine courtesy of John George
ID3_GetPictureDataOfPicType(ID3_Tag * tag,const char * TempPicPath,ID3_PictureType pictype)684 size_t ID3_GetPictureDataOfPicType(ID3_Tag* tag, const char* TempPicPath, ID3_PictureType pictype)
685 {
686 if (NULL == tag)
687 return 0;
688 else
689 {
690 ID3_Frame* frame = NULL;
691 ID3_Tag::Iterator* iter = tag->CreateIterator();
692
693 while (NULL != (frame = iter->GetNext() ))
694 {
695 if(frame->GetID() == ID3FID_PICTURE)
696 {
697 if(frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32)pictype)
698 break;
699 }
700 }
701 delete iter;
702
703 if (frame != NULL)
704 {
705 ID3_Field* myField = frame->GetField(ID3FN_DATA);
706 if (myField != NULL)
707 {
708 myField->ToFile(TempPicPath);
709 return (size_t)myField->Size();
710 }
711 else return 0;
712 }
713 else return 0;
714 }
715 }
716
717 //following routine courtesy of John George
ID3_GetMimeTypeOfPicType(ID3_Tag * tag,ID3_PictureType pictype)718 char* ID3_GetMimeTypeOfPicType(ID3_Tag* tag, ID3_PictureType pictype)
719 {
720 char* sPicMimetype = NULL;
721 if (NULL == tag)
722 return sPicMimetype;
723
724 ID3_Frame* frame = NULL;
725 ID3_Tag::Iterator* iter = tag->CreateIterator();
726
727 while (NULL != (frame = iter->GetNext()))
728 {
729 if(frame->GetID() == ID3FID_PICTURE)
730 {
731 if(frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32)pictype)
732 break;
733 }
734 }
735 delete iter;
736
737 if (frame != NULL)
738 {
739 sPicMimetype = ID3_GetString(frame, ID3FN_MIMETYPE);
740 }
741 return sPicMimetype;
742 }
743
744 //following routine courtesy of John George
ID3_GetDescriptionOfPicType(ID3_Tag * tag,ID3_PictureType pictype)745 char* ID3_GetDescriptionOfPicType(ID3_Tag* tag, ID3_PictureType pictype)
746 {
747 char* sPicDescription = NULL;
748 if (NULL == tag)
749 return sPicDescription;
750
751 ID3_Frame* frame = NULL;
752 ID3_Tag::Iterator* iter = tag->CreateIterator();
753
754 while (NULL != (frame = iter->GetNext()))
755 {
756 if(frame->GetID() == ID3FID_PICTURE)
757 {
758 if(frame->GetField(ID3FN_PICTURETYPE)->Get() == (uint32)pictype)
759 break;
760 }
761 }
762 delete iter;
763
764 if (frame != NULL)
765 {
766 sPicDescription = ID3_GetString(frame, ID3FN_DESCRIPTION);
767 }
768 return sPicDescription;
769 }
770
771
ID3_RemoveTracks(ID3_Tag * tag)772 size_t ID3_RemoveTracks(ID3_Tag* tag)
773 {
774 size_t num_removed = 0;
775 ID3_Frame* frame = NULL;
776
777 if (NULL == tag)
778 {
779 return num_removed;
780 }
781
782 while ((frame = tag->Find(ID3FID_TRACKNUM)))
783 {
784 frame = tag->RemoveFrame(frame);
785 delete frame;
786 num_removed++;
787 }
788
789 return num_removed;
790 }
791
ID3_GetGenre(const ID3_Tag * tag)792 char *ID3_GetGenre(const ID3_Tag *tag)
793 {
794 char *sGenre = NULL;
795 if (NULL == tag)
796 {
797 return sGenre;
798 }
799
800 ID3_Frame *frame = tag->Find(ID3FID_CONTENTTYPE);
801 if (frame != NULL)
802 {
803 sGenre = ID3_GetString(frame, ID3FN_TEXT);
804 }
805
806 return sGenre;
807 }
808
ID3_GetGenreNum(const ID3_Tag * tag)809 size_t ID3_GetGenreNum(const ID3_Tag *tag)
810 {
811 char *sGenre = ID3_GetGenre(tag);
812 size_t ulGenre = 0xFF;
813 if (NULL == sGenre)
814 {
815 return ulGenre;
816 }
817
818 // If the genre string begins with "(ddd)", where "ddd" is a number, then
819 // "ddd" is the genre number---get it
820 if (sGenre[0] == '(')
821 {
822 char *pCur = &sGenre[1];
823 while (isdigit(*pCur))
824 {
825 pCur++;
826 }
827 if (*pCur == ')')
828 {
829 // if the genre number is greater than 255, its invalid.
830 ulGenre = dami::min(0xFF, atoi(&sGenre[1]));
831 }
832 }
833
834 delete [] sGenre;
835 return ulGenre;
836 }
837
838 //following routine courtesy of John George
ID3_AddGenre(ID3_Tag * tag,const char * genre,bool replace)839 ID3_Frame* ID3_AddGenre(ID3_Tag* tag, const char* genre, bool replace)
840 {
841 ID3_Frame* frame = NULL;
842 if (NULL != tag && NULL != genre && strlen(genre) > 0)
843 {
844 if (replace)
845 {
846 ID3_RemoveGenres(tag);
847 }
848 if (replace || NULL == tag->Find(ID3FID_CONTENTTYPE))
849 {
850 frame = new ID3_Frame(ID3FID_CONTENTTYPE);
851 if (NULL != frame)
852 {
853 frame->GetField(ID3FN_TEXT)->Set(genre);
854 tag->AttachFrame(frame);
855 }
856 }
857 }
858
859 return frame;
860 }
861
ID3_AddGenre(ID3_Tag * tag,size_t genreNum,bool replace)862 ID3_Frame* ID3_AddGenre(ID3_Tag *tag, size_t genreNum, bool replace)
863 {
864 if(0xFF != genreNum)
865 {
866 char sGenre[6];
867 sprintf(sGenre, "(%lu)", (luint) genreNum);
868 return(ID3_AddGenre(tag, sGenre, replace));
869 }
870 else
871 {
872 return(NULL);
873 }
874 }
875
ID3_RemoveGenres(ID3_Tag * tag)876 size_t ID3_RemoveGenres(ID3_Tag *tag)
877 {
878 size_t num_removed = 0;
879 ID3_Frame *frame = NULL;
880
881 if (NULL == tag)
882 {
883 return num_removed;
884 }
885
886 while ((frame = tag->Find(ID3FID_CONTENTTYPE)))
887 {
888 frame = tag->RemoveFrame(frame);
889 delete frame;
890 num_removed++;
891 }
892
893 return num_removed;
894 }
895
ID3_GetLyrics(const ID3_Tag * tag)896 char *ID3_GetLyrics(const ID3_Tag *tag)
897 {
898 char *sLyrics = NULL;
899 if (NULL == tag)
900 {
901 return sLyrics;
902 }
903
904 ID3_Frame *frame = tag->Find(ID3FID_UNSYNCEDLYRICS);
905 if (frame != NULL)
906 {
907 sLyrics = ID3_GetString(frame, ID3FN_TEXT);
908 }
909 return sLyrics;
910 }
911
ID3_AddLyrics(ID3_Tag * tag,const char * text,bool replace)912 ID3_Frame* ID3_AddLyrics(ID3_Tag *tag, const char *text, bool replace)
913 {
914 return ID3_AddLyrics(tag, text, "", replace);
915 }
916
ID3_AddLyrics(ID3_Tag * tag,const char * text,const char * desc,bool replace)917 ID3_Frame* ID3_AddLyrics(ID3_Tag *tag, const char *text, const char* desc,
918 bool replace)
919 {
920 return ID3_AddLyrics(tag, text, desc, "XXX", replace);
921 }
922
ID3_AddLyrics(ID3_Tag * tag,const char * text,const char * desc,const char * lang,bool replace)923 ID3_Frame* ID3_AddLyrics(ID3_Tag *tag, const char *text, const char* desc,
924 const char* lang, bool replace)
925 {
926 ID3_Frame* frame = NULL;
927 if (NULL != tag && strlen(text) > 0)
928 {
929 if (replace)
930 {
931 ID3_RemoveLyrics(tag);
932 }
933 if (replace || tag->Find(ID3FID_UNSYNCEDLYRICS) == NULL)
934 {
935 frame = new ID3_Frame(ID3FID_UNSYNCEDLYRICS);
936 if (NULL != frame)
937 {
938 frame->GetField(ID3FN_LANGUAGE)->Set(lang);
939 frame->GetField(ID3FN_DESCRIPTION)->Set(desc);
940 frame->GetField(ID3FN_TEXT)->Set(text);
941 tag->AttachFrame(frame);
942 }
943 }
944 }
945
946 return frame;
947 }
948
ID3_RemoveLyrics(ID3_Tag * tag)949 size_t ID3_RemoveLyrics(ID3_Tag *tag)
950 {
951 size_t num_removed = 0;
952 ID3_Frame *frame = NULL;
953
954 if (NULL == tag)
955 {
956 return num_removed;
957 }
958
959 while ((frame = tag->Find(ID3FID_UNSYNCEDLYRICS)))
960 {
961 frame = tag->RemoveFrame(frame);
962 delete frame;
963 num_removed++;
964 }
965
966 return num_removed;
967 }
968
ID3_GetLyricist(const ID3_Tag * tag)969 char *ID3_GetLyricist(const ID3_Tag *tag)
970 {
971 char *sLyricist = NULL;
972 if (NULL == tag)
973 {
974 return sLyricist;
975 }
976
977 ID3_Frame *frame = tag->Find(ID3FID_LYRICIST);
978 if (frame != NULL)
979 {
980 sLyricist = ID3_GetString(frame, ID3FN_TEXT);
981 }
982 return sLyricist;
983 }
984
ID3_AddLyricist(ID3_Tag * tag,const char * text,bool replace)985 ID3_Frame* ID3_AddLyricist(ID3_Tag *tag, const char *text, bool replace)
986 {
987 ID3_Frame* frame = NULL;
988 if (NULL != tag && NULL != text && strlen(text) > 0)
989 {
990 if (replace)
991 {
992 ID3_RemoveLyricist(tag);
993 }
994 if (replace || (tag->Find(ID3FID_LYRICIST) == NULL))
995 {
996 frame = new ID3_Frame(ID3FID_LYRICIST);
997 if (frame)
998 {
999 frame->GetField(ID3FN_TEXT)->Set(text);
1000 tag->AttachFrame(frame);
1001 }
1002 }
1003 }
1004
1005 return frame;
1006 }
1007
ID3_RemoveLyricist(ID3_Tag * tag)1008 size_t ID3_RemoveLyricist(ID3_Tag *tag)
1009 {
1010 size_t num_removed = 0;
1011 ID3_Frame *frame = NULL;
1012
1013 if (NULL == tag)
1014 {
1015 return num_removed;
1016 }
1017
1018 while ((frame = tag->Find(ID3FID_LYRICIST)))
1019 {
1020 frame = tag->RemoveFrame(frame);
1021 delete frame;
1022 num_removed++;
1023 }
1024
1025 return num_removed;
1026 }
1027
ID3_AddSyncLyrics(ID3_Tag * tag,const uchar * data,size_t datasize,ID3_TimeStampFormat format,bool replace)1028 ID3_Frame* ID3_AddSyncLyrics(ID3_Tag *tag, const uchar *data, size_t datasize,
1029 ID3_TimeStampFormat format, bool replace)
1030 {
1031 return ID3_AddSyncLyrics(tag, data, datasize, format, "", replace);
1032 }
1033
ID3_AddSyncLyrics(ID3_Tag * tag,const uchar * data,size_t datasize,ID3_TimeStampFormat format,const char * desc,bool replace)1034 ID3_Frame* ID3_AddSyncLyrics(ID3_Tag *tag, const uchar *data, size_t datasize,
1035 ID3_TimeStampFormat format, const char *desc,
1036 bool replace)
1037 {
1038 return ID3_AddSyncLyrics(tag, data, datasize, format, desc, "XXX", replace);
1039 }
1040
ID3_AddSyncLyrics(ID3_Tag * tag,const uchar * data,size_t datasize,ID3_TimeStampFormat format,const char * desc,const char * lang,bool replace)1041 ID3_Frame* ID3_AddSyncLyrics(ID3_Tag *tag, const uchar *data, size_t datasize,
1042 ID3_TimeStampFormat format, const char *desc,
1043 const char *lang, bool replace)
1044 {
1045 return ID3_AddSyncLyrics(tag, data, datasize, format, desc, lang,
1046 ID3CT_LYRICS, replace);
1047 }
1048
ID3_AddSyncLyrics(ID3_Tag * tag,const uchar * data,size_t datasize,ID3_TimeStampFormat format,const char * desc,const char * lang,ID3_ContentType type,bool replace)1049 ID3_Frame* ID3_AddSyncLyrics(ID3_Tag *tag, const uchar *data, size_t datasize,
1050 ID3_TimeStampFormat format, const char *desc,
1051 const char *lang, ID3_ContentType type,
1052 bool replace)
1053 {
1054 ID3_Frame* frame = NULL;
1055 // language and descriptor should be mandatory
1056 if ((NULL == lang) || (NULL == desc))
1057 {
1058 return NULL;
1059 }
1060
1061 // check if a SYLT frame of this language or descriptor already exists
1062 ID3_Frame* frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang);
1063 if (!frmExist)
1064 {
1065 frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc);
1066 }
1067
1068 if (NULL != tag && NULL != data)
1069 {
1070 if (replace && frmExist)
1071 {
1072 frmExist = tag->RemoveFrame (frmExist);
1073 delete frmExist;
1074 frmExist = NULL;
1075 }
1076
1077 // if the frame still exist, cannot continue
1078 if (frmExist)
1079 {
1080 return NULL;
1081 }
1082
1083 ID3_Frame* frame = new ID3_Frame(ID3FID_SYNCEDLYRICS);
1084
1085 frame->GetField(ID3FN_LANGUAGE)->Set(lang);
1086 frame->GetField(ID3FN_DESCRIPTION)->Set(desc);
1087 frame->GetField(ID3FN_TIMESTAMPFORMAT)->Set(format);
1088 frame->GetField(ID3FN_CONTENTTYPE)->Set(type);
1089 frame->GetField(ID3FN_DATA)->Set(data, datasize);
1090 tag->AttachFrame(frame);
1091 }
1092
1093 return frame;
1094 }
1095
ID3_GetSyncLyricsInfo(const ID3_Tag * tag,const char * desc,const char * lang,ID3_TimeStampFormat & format,ID3_ContentType & type,size_t & size)1096 ID3_Frame *ID3_GetSyncLyricsInfo(const ID3_Tag *tag, const char *desc,
1097 const char *lang,
1098 ID3_TimeStampFormat& format,
1099 ID3_ContentType& type, size_t& size)
1100 {
1101 // check if a SYLT frame of this language or descriptor exists
1102 ID3_Frame* frmExist = NULL;
1103 if (NULL != lang)
1104 {
1105 // search through language
1106 frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang);
1107 }
1108 else if (NULL != desc)
1109 {
1110 // search through descriptor
1111 frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc);
1112 }
1113 else
1114 {
1115 // both language and description not specified, search the first SYLT frame
1116 frmExist = tag->Find(ID3FID_SYNCEDLYRICS);
1117 }
1118
1119 if (!frmExist)
1120 {
1121 return NULL;
1122 }
1123
1124 // get the lyrics time stamp format
1125 format = static_cast<ID3_TimeStampFormat>(frmExist->GetField(ID3FN_TIMESTAMPFORMAT)->Get ());
1126
1127 // get the lyrics content type
1128 type = static_cast<ID3_ContentType>(frmExist->GetField(ID3FN_CONTENTTYPE)->Get ());
1129
1130 // get the lyrics size
1131 size = frmExist->GetField (ID3FN_DATA)->Size ();
1132
1133 // return the frame pointer for further uses
1134 return frmExist;
1135 }
1136
ID3_GetSyncLyrics(const ID3_Tag * tag,const char * lang,const char * desc,const uchar * & pData,size_t & size)1137 ID3_Frame *ID3_GetSyncLyrics(const ID3_Tag* tag, const char* lang,
1138 const char* desc, const uchar* &pData, size_t& size)
1139 {
1140 // check if a SYLT frame of this language or descriptor exists
1141 ID3_Frame* frmExist = NULL;
1142 if (NULL != lang)
1143 {
1144 // search through language
1145 frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang);
1146 }
1147 else if (NULL != desc)
1148 {
1149 // search through descriptor
1150 frmExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc);
1151 }
1152 else
1153 {
1154 // both language and description not specified, search the first SYLT frame
1155 frmExist = tag->Find(ID3FID_SYNCEDLYRICS);
1156 }
1157
1158 if (NULL == frmExist)
1159 {
1160 return NULL;
1161 }
1162
1163 // get the lyrics size
1164 size = dami::min(size, frmExist->GetField(ID3FN_DATA)->Size());
1165
1166 // get the lyrics data
1167 pData = frmExist->GetField (ID3FN_DATA)->GetRawBinary();
1168
1169 // return the frame pointer for further uses
1170 return frmExist;
1171 }
1172
1173