id3lib  3.8.3
misc_support.cpp
Go to the documentation of this file.
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 
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();
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 
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 
67 void ID3_FreeString(char *str)
68 {
69  if(str != NULL)
70  delete [] str;
71 }
72 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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);
350  frame = tag->Find(ID3FID_COMMENT);
351  }
352 
353  if (frame)
354  comment = ID3_GetString(frame, ID3FN_TEXT);
355  return comment;
356 }
357 
358 ID3_Frame* ID3_AddComment(ID3_Tag *tag, const char *text, bool replace)
359 {
360  return ID3_AddComment(tag, text, "", replace);
361 }
362 
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 
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)
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 
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 
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 
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
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
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
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
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
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
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
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
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
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
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 
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 
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 
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
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 
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 
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 
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 
912 ID3_Frame* ID3_AddLyrics(ID3_Tag *tag, const char *text, bool replace)
913 {
914  return ID3_AddLyrics(tag, text, "", replace);
915 }
916 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
The representative class of an ID3v2 field.
Definition: field.h:37
virtual uint32 Get() const =0
Returns the value of the integer field.
virtual size_t Size() const =0
Returns the size of a field.
virtual ID3_TextEnc GetEncoding() const =0
virtual void ToFile(const char *sInfo) const =0
virtual bool SetEncoding(ID3_TextEnc enc)=0
The representative class of an id3v2 frame.
virtual ID3_Frame * GetNext()=0
The representative class of an id3 tag.
Definition: tag.h:42
bool AttachFrame(ID3_Frame *)
Attaches a frame to the tag; the tag takes responsibility for releasing the frame's memory when tag g...
Definition: tag.cpp:521
ID3_Frame * Find(ID3_FrameID) const
Finds frame with given frame id, fld id, and integer data.
Definition: tag.cpp:836
Iterator * CreateIterator()
Definition: tag.cpp:1115
ID3_Frame * RemoveFrame(const ID3_Frame *)
Removes a frame from the tag.
Definition: tag.cpp:547
#define NULL
Definition: globals.h:743
ID3_FieldID
Enumeration of the different types of fields in a frame.
Definition: globals.h:198
@ ID3FN_MIMETYPE
Mimetype field.
Definition: globals.h:212
@ ID3FN_DESCRIPTION
Description field.
Definition: globals.h:204
@ ID3FN_TIMESTAMPFORMAT
SYLT Timestamp Format.
Definition: globals.h:221
@ ID3FN_LANGUAGE
Language field.
Definition: globals.h:209
@ ID3FN_TEXT
Text field.
Definition: globals.h:201
@ ID3FN_DATA
Data field.
Definition: globals.h:203
@ ID3FN_PICTURETYPE
Picture type field.
Definition: globals.h:210
@ ID3FN_CONTENTTYPE
SYLT content type.
Definition: globals.h:222
ID3_TextEnc
Enumeration of the types of text encodings: ascii or unicode.
Definition: globals.h:138
@ ID3TE_ISO8859_1
Definition: globals.h:140
ID3_ContentType
Definition: globals.h:382
@ ID3CT_LYRICS
Definition: globals.h:384
long unsigned int luint
Definition: globals.h:115
#define STR_V1_COMMENT_DESC
String used for the description field of a comment tag converted from an id3v1 tag to an id3v2 tag.
Definition: globals.h:111
unsigned char uchar
Definition: globals.h:114
@ ID3FID_LEADARTIST
Lead performer(s)/Soloist(s)
Definition: globals.h:292
@ ID3FID_CONTENTTYPE
Content type.
Definition: globals.h:263
@ ID3FID_COMPOSER
Composer.
Definition: globals.h:262
@ ID3FID_LYRICIST
Lyricist/Text writer.
Definition: globals.h:274
@ ID3FID_BAND
Band/orchestra/accompaniment.
Definition: globals.h:293
@ ID3FID_ALBUM
Album/Movie/Show title.
Definition: globals.h:260
@ ID3FID_COMMENT
Comments.
Definition: globals.h:235
@ ID3FID_CONDUCTOR
Conductor/performer refinement.
Definition: globals.h:294
@ ID3FID_YEAR
Year.
Definition: globals.h:311
@ ID3FID_PICTURE
Attached picture.
Definition: globals.h:233
@ ID3FID_TRACKNUM
Track number/Position in set.
Definition: globals.h:299
@ ID3FID_UNSYNCEDLYRICS
Unsynchronized lyric/text transcription.
Definition: globals.h:314
@ ID3FID_TITLE
Title/songname/content description.
Definition: globals.h:278
@ ID3FID_SYNCEDLYRICS
Synchronized lyric/text.
Definition: globals.h:258
ID3_PictureType
Definition: globals.h:393
ID3_TimeStampFormat
Definition: globals.h:418
size_t ID3_GetTrackNum(const ID3_Tag *tag)
size_t ID3_GetGenreNum(const ID3_Tag *tag)
char * ID3_GetArtist(const ID3_Tag *tag)
size_t ID3_RemovePictures(ID3_Tag *tag)
char * ID3_GetMimeTypeOfPicType(ID3_Tag *tag, ID3_PictureType pictype)
ID3_Frame * ID3_AddComment(ID3_Tag *tag, const char *text, bool replace)
int ID3_GetPictureData(const ID3_Tag *tag, const char *TempPicPath)
bool ID3_HasPicture(const ID3_Tag *tag)
char * ID3_GetTitle(const ID3_Tag *tag)
char * ID3_GetLyrics(const ID3_Tag *tag)
char * ID3_GetTrack(const ID3_Tag *tag)
ID3_Frame * ID3_AddYear(ID3_Tag *tag, const char *text, bool replace)
size_t ID3_GetPictureDataOfPicType(ID3_Tag *tag, const char *TempPicPath, ID3_PictureType pictype)
void ID3_FreeString(char *str)
ID3_Frame * ID3_GetSyncLyricsInfo(const ID3_Tag *tag, const char *desc, const char *lang, ID3_TimeStampFormat &format, ID3_ContentType &type, size_t &size)
ID3_Frame * ID3_AddLyricist(ID3_Tag *tag, const char *text, bool replace)
char * ID3_GetPictureMimeType(const ID3_Tag *tag)
ID3_Frame * ID3_AddPicture(ID3_Tag *tag, const char *TempPicPath, const char *MimeType, bool replace)
ID3_Frame * ID3_AddTrack(ID3_Tag *tag, uchar trk, uchar ttl, bool replace)
char * ID3_GetAlbum(const ID3_Tag *tag)
size_t ID3_RemoveGenres(ID3_Tag *tag)
size_t ID3_RemoveComments(ID3_Tag *tag, const char *desc)
char * ID3_GetLyricist(const ID3_Tag *tag)
ID3_Frame * ID3_AddAlbum(ID3_Tag *tag, const char *text, bool replace)
ID3_Frame * ID3_AddArtist(ID3_Tag *tag, const char *text, bool replace)
char * ID3_GetDescriptionOfPicType(ID3_Tag *tag, ID3_PictureType pictype)
size_t ID3_RemoveAlbums(ID3_Tag *tag)
ID3_Frame * ID3_AddLyrics(ID3_Tag *tag, const char *text, bool replace)
ID3_Frame * ID3_AddGenre(ID3_Tag *tag, const char *genre, bool replace)
char * ID3_GetYear(const ID3_Tag *tag)
ID3_Frame * ID3_AddTitle(ID3_Tag *tag, const char *text, bool replace)
char * ID3_GetComment(const ID3_Tag *tag, const char *desc)
size_t ID3_RemoveLyricist(ID3_Tag *tag)
size_t ID3_RemoveYears(ID3_Tag *tag)
size_t ID3_RemoveTitles(ID3_Tag *tag)
size_t ID3_RemoveLyrics(ID3_Tag *tag)
ID3_Frame * ID3_AddSyncLyrics(ID3_Tag *tag, const uchar *data, size_t datasize, ID3_TimeStampFormat format, bool replace)
size_t ID3_RemoveTracks(ID3_Tag *tag)
size_t ID3_RemovePictureType(ID3_Tag *tag, ID3_PictureType pictype)
ID3_Frame * ID3_GetSyncLyrics(const ID3_Tag *tag, const char *lang, const char *desc, const uchar *&pData, size_t &size)
char * ID3_GetString(const ID3_Frame *frame, ID3_FieldID fldName)
size_t ID3_RemoveArtists(ID3_Tag *tag)
char * ID3_GetGenre(const ID3_Tag *tag)
const T & min(const T &a, const T &b)
Definition: utils.h:51