id3dev 26.01
An ID3 metadata library
Loading...
Searching...
No Matches
id3dev.c
Go to the documentation of this file.
1
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include "id3dev.h"
16#include "id3v2/id3v2.h"
17#include "id3v1/id3v1.h"
18#include "id3v1/id3v1Parser.h"
19#include "id3v2/id3v2Frame.h"
20
26
35ID3 *id3Create(Id3v2Tag *id3v2, Id3v1Tag *id3v1) {
36 ID3 *metadata = malloc(sizeof(ID3));
37
38 metadata->id3v2 = id3v2;
39 metadata->id3v1 = id3v1;
40
41 return metadata;
42}
43
50void id3Destroy(ID3 **toDelete) {
51 if (*toDelete) {
52 id3v2DestroyTag(&((*toDelete)->id3v2));
53 id3v1DestroyTag(&((*toDelete)->id3v1));
54 free(*toDelete);
55 *toDelete = NULL;
56 toDelete = NULL;
57 }
58}
59
68bool id3SetPreferredStandard(uint8_t standard) {
69 switch (standard) {
74 id3PreferredStandard = standard;
75 break;
76
77 default:
78 return false;
79 }
80
81 return true;
82}
83
92}
93
94
103ID3 *id3FromFile(const char *filePath) {
104 return id3Create(id3v2TagFromFile(filePath), id3v1TagFromFile(filePath));
105}
106
114ID3 *id3Copy(const ID3 *toCopy) {
115 if (toCopy == NULL) {
116 return NULL;
117 }
118
119 return id3Create(id3v2CopyTag(toCopy->id3v2), id3v1CopyTag(toCopy->id3v1));
120}
121
130bool id3Compare(const ID3 *metadata1, const ID3 *metadata2) {
131 if (metadata1 == NULL || metadata2 == NULL) {
132 return false;
133 }
134
135 bool v1 = false;
136 bool v2 = false;
137
138 v1 = id3v1CompareTag(metadata1->id3v1, metadata2->id3v1);
139 v2 = id3v2CompareTag(metadata1->id3v2, metadata2->id3v2);
140
141 if (v1 && v2) {
142 return true;
143 }
144
145 if (v1 == false && (v2 == true && metadata1->id3v1 == NULL && metadata2->id3v1 == NULL)) {
146 return true;
147 }
148
149 if (v2 == false && (v1 == true && metadata1->id3v2 == NULL && metadata2->id3v2 == NULL)) {
150 return true;
151 }
152
153 return false;
154}
155
156
168 if (metadata == NULL) {
169 return false;
170 }
171
172 if (metadata->id3v1 == NULL) {
173 return false;
174 }
175
176 Id3v2Tag *newTag = NULL;
177 Id3v2TagHeader *header = NULL;
178 List *frames = NULL;
179 char *str = NULL;
180 int size = 0;
181 int input = 0;
182
184
185 switch (input) {
187 header = id3v2CreateTagHeader(ID3V2_TAG_VERSION_2, 0, 0, NULL);
188 break;
190 header = id3v2CreateTagHeader(ID3V2_TAG_VERSION_3, 0, 0, NULL);
191 break;
193 header = id3v2CreateTagHeader(ID3V2_TAG_VERSION_4, 0, 0, NULL);
194 break;
195 default:
196 return false;
197 }
198
199
201 newTag = id3v2CreateTag(header, frames);
202
203 if (metadata->id3v1->title[0] != 0x00) {
204 if (!id3v2WriteTitle((char *) metadata->id3v1->title, newTag)) {
205 id3v2DestroyTag(&newTag);
206 listFree(frames);
207 return false;
208 }
209 }
210
211
212 if (metadata->id3v1->artist[0] != 0x00) {
213 if (!id3v2WriteArtist((char *) metadata->id3v1->artist, newTag)) {
214 id3v2DestroyTag(&newTag);
215 listFree(frames);
216 return false;
217 }
218 }
219
220
221 if (metadata->id3v1->albumTitle[0] != 0x00) {
222 if (!id3v2WriteAlbum((char *) metadata->id3v1->albumTitle, newTag)) {
223 id3v2DestroyTag(&newTag);
224 listFree(frames);
225 return false;
226 }
227 }
228
229
230 if (metadata->id3v1->year != 0) {
231 size = snprintf(NULL, 0, "%d", metadata->id3v1->year);
232 str = calloc(size + 1, sizeof(char));
233 (void) snprintf(str, size + 1, "%d", metadata->id3v1->year);
234 if (!id3v2WriteYear(str, newTag)) {
235 id3v2DestroyTag(&newTag);
236 listFree(frames);
237 free(str);
238 return false;
239 }
240 free(str);
241 }
242
243
244 if (metadata->id3v1->track != 0) {
245 size = snprintf(NULL, 0, "%d", metadata->id3v1->track);
246 str = calloc(size + 1, sizeof(char));
247 (void) snprintf(str, size + 1, "%d", metadata->id3v1->track);
248
249 if (!id3v2WriteTrack(str, newTag)) {
250 id3v2DestroyTag(&newTag);
251 listFree(frames);
252 free(str);
253 return false;
254 }
255 free(str);
256 }
257
258 if (metadata->id3v1->genre < PSYBIENT_GENRE) {
259 if (!id3v2WriteGenre(id3v1GenreFromTable(metadata->id3v1->genre), newTag)) {
260 id3v2DestroyTag(&newTag);
261 listFree(frames);
262 return false;
263 }
264 }
265
266
267 if (metadata->id3v1->comment[0] != 0x00) {
268 if (!id3v2WriteComment((char *) metadata->id3v1->comment, newTag)) {
269 id3v2DestroyTag(&newTag);
270 listFree(frames);
271 return false;
272 }
273 }
274
275 if (metadata->id3v2 != NULL) {
276 id3v2DestroyTag(&(metadata->id3v2));
277 }
278
279 metadata->id3v2 = newTag;
280
281 return true;
282}
283
284
296 if (metadata == NULL) {
297 return false;
298 }
299
300 if (metadata->id3v2 == NULL) {
301 return false;
302 }
303
304 Id3v1Tag *newTag = NULL;
305 char *title = NULL;
306 char *artist = NULL;
307 char *album = NULL;
308 char *year = NULL;
309 char *track = NULL;
310 char *comment = NULL;
311 char *genre = NULL;
312
313 newTag = id3v1CreateTag(NULL, NULL, NULL, 0, 0, NULL, OTHER_GENRE);
314 title = id3v2ReadTitle(metadata->id3v2);
315 artist = id3v2ReadArtist(metadata->id3v2);
316 album = id3v2ReadAlbum(metadata->id3v2);
317 year = id3v2ReadYear(metadata->id3v2);
318 track = id3v2ReadTrack(metadata->id3v2);
319 comment = id3v2ReadComment(metadata->id3v2);
320 genre = id3v2ReadGenre(metadata->id3v2);
321
322 if (title != NULL) {
323 id3v1WriteTitle(title, newTag);
324 free(title);
325 }
326
327 if (artist != NULL) {
328 id3v1WriteArtist(artist, newTag);
329 free(artist);
330 }
331
332 if (album != NULL) {
333 id3v1WriteAlbum(album, newTag);
334 free(album);
335 }
336
337 if (year != NULL) {
338 id3v1WriteYear((int) strtol(year, NULL, 10), newTag);
339 free(year);
340 }
341
342 if (track != NULL) {
343 int i = 0;
344 int offset0 = 0;
345 int convi = 0;
346 char *dec = NULL;
347 char *end = NULL;
348 bool flag = false;
349
350 while (track[i] != '\0') {
351 if (track[i] >= '0' && track[i] <= '9') {
352 if (!flag && track[i] == '0') {
353 offset0++;
354 } else {
355 flag = true;
356 }
357 } else {
358 break;
359 }
360 i++;
361 }
362
363 dec = calloc(i - offset0 + 1, sizeof(char));
364 memcpy(dec, track + offset0, i - offset0);
365 convi = (int) strtol(dec, &end, 10);
366 id3v1WriteTrack(convi, newTag);
367
368 free(dec);
369 free(track);
370 }
371
372 if (comment != NULL) {
373 id3v1WriteComment(comment, newTag);
374 free(comment);
375 }
376
377 if (genre != NULL) {
378 id3v1WriteGenre(genre[0], newTag);
379 free(genre);
380 }
381
382 if (metadata->id3v1 != NULL) {
383 id3v1DestroyTag(&(metadata->id3v1));
384 }
385
386 metadata->id3v1 = newTag;
387 return true;
388}
389
390// internal -----------------------------------------------------------------
391// corrects the standard preference if the preferred standard is not available
392static int internal_getSafePrefStd(const ID3 *metadata) {
393 int input = 0;
394 int pref = id3GetPreferredStandard();
395
396 if (pref > ID3V1_TAG_VERSION && metadata->id3v2 == NULL) {
397 input = ID3V1_TAG_VERSION;
398 } else if (pref == ID3V1_TAG_VERSION && metadata->id3v1 == NULL) {
399 // assumed because of its wide use
400 input = ID3V2_TAG_VERSION_3;
401 } else {
402 input = pref;
403 }
404
405
406 return input;
407}
408
417char *id3ReadTitle(const ID3 *metadata) {
418 if (metadata == NULL) {
419 return NULL;
420 }
421
422 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
423 return NULL;
424 }
425
426 switch (internal_getSafePrefStd(metadata)) {
428 return id3v1ReadTitle(metadata->id3v1);
432 return id3v2ReadTitle(metadata->id3v2);
433 default:
434 break;
435 }
436
437 return NULL;
438}
439
448char *id3ReadArtist(const ID3 *metadata) {
449 if (metadata == NULL) {
450 return NULL;
451 }
452
453 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
454 return NULL;
455 }
456
457 switch (internal_getSafePrefStd(metadata)) {
459 return id3v1ReadArtist(metadata->id3v1);
463 return id3v2ReadArtist(metadata->id3v2);
464 default:
465 break;
466 }
467
468 return NULL;
469}
470
479char *id3ReadAlbumArtist(const ID3 *metadata) {
480 if (metadata == NULL) {
481 return NULL;
482 }
483
484 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
485 return NULL;
486 }
487
488 switch (internal_getSafePrefStd(metadata)) {
492 return id3v2ReadAlbumArtist(metadata->id3v2);
494 default:
495 break;
496 }
497
498 return NULL;
499}
500
509char *id3ReadAlbum(const ID3 *metadata) {
510 if (metadata == NULL) {
511 return NULL;
512 }
513
514 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
515 return NULL;
516 }
517
518 switch (internal_getSafePrefStd(metadata)) {
520 return id3v1ReadAlbum(metadata->id3v1);
524 return id3v2ReadAlbum(metadata->id3v2);
525 default:
526 break;
527 }
528
529 return NULL;
530}
531
541char *id3ReadYear(const ID3 *metadata) {
542 if (metadata == NULL) {
543 return NULL;
544 }
545
546 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
547 return NULL;
548 }
549
550 switch (internal_getSafePrefStd(metadata)) {
551 case ID3V1_TAG_VERSION: {
552 if (metadata->id3v1 == NULL) {
553 return NULL;
554 }
555
556 char *year = NULL;
557 int size = 0;
558
559 size = snprintf(NULL, 0, "%d", metadata->id3v1->year);
560 year = calloc(size + 1, sizeof(char));
561 (void) snprintf(year, size + 1, "%d", metadata->id3v1->year);
562
563 return year;
564 }
568 return id3v2ReadYear(metadata->id3v2);
569 default:
570 break;
571 }
572
573 return NULL;
574}
575
585char *id3ReadGenre(const ID3 *metadata) {
586 if (metadata == NULL) {
587 return NULL;
588 }
589
590 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
591 return NULL;
592 }
593
594 switch (internal_getSafePrefStd(metadata)) {
595 case ID3V1_TAG_VERSION: {
596 if (metadata->id3v1 == NULL) {
597 return NULL;
598 }
599
600 char *genre = NULL;
601 int size = 0;
602
603 size = (int) strlen(id3v1GenreFromTable(metadata->id3v1->genre));
604 genre = calloc(size + 1, sizeof(char));
605 memcpy(genre, id3v1GenreFromTable(metadata->id3v1->genre), size);
606 return genre;
607 }
611 return id3v2ReadGenre(metadata->id3v2);
612 default:
613 break;
614 }
615
616 return NULL;
617}
618
628char *id3ReadTrack(const ID3 *metadata) {
629 if (metadata == NULL) {
630 return NULL;
631 }
632
633 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
634 return NULL;
635 }
636
637 switch (internal_getSafePrefStd(metadata)) {
638 case ID3V1_TAG_VERSION: {
639 if (metadata->id3v1 == NULL) {
640 return NULL;
641 }
642
643 char *track = NULL;
644 int size = 0;
645
646 size = snprintf(NULL, 0, "%d", metadata->id3v1->track);
647 track = calloc(size + 1, sizeof(char));
648 (void) snprintf(track, size + 1, "%d", metadata->id3v1->track);
649 return track;
650 }
654 return id3v2ReadTrack(metadata->id3v2);
655 default:
656 break;
657 }
658
659 return NULL;
660}
661
670char *id3ReadComposer(const ID3 *metadata) {
671 if (metadata == NULL) {
672 return NULL;
673 }
674
675 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
676 return NULL;
677 }
678
679 switch (internal_getSafePrefStd(metadata)) {
683 return id3v2ReadComposer(metadata->id3v2);
685 default:
686 break;
687 }
688
689 return NULL;
690}
691
700char *id3ReadDisc(const ID3 *metadata) {
701 if (metadata == NULL) {
702 return NULL;
703 }
704
705 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
706 return NULL;
707 }
708
709 switch (internal_getSafePrefStd(metadata)) {
713 return id3v2ReadDisc(metadata->id3v2);
715 default:
716 break;
717 }
718
719 return NULL;
720}
721
730char *id3ReadLyrics(const ID3 *metadata) {
731 if (metadata == NULL) {
732 return NULL;
733 }
734
735 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
736 return NULL;
737 }
738
739 switch (internal_getSafePrefStd(metadata)) {
743 return id3v2ReadLyrics(metadata->id3v2);
745 default:
746 break;
747 }
748
749 return NULL;
750}
751
760char *id3ReadComment(const ID3 *metadata) {
761 if (metadata == NULL) {
762 return NULL;
763 }
764
765 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
766 return NULL;
767 }
768
769 switch (internal_getSafePrefStd(metadata)) {
771 return id3v1ReadComment(metadata->id3v1);
775 return id3v2ReadComment(metadata->id3v2);
776 default:
777 break;
778 }
779
780 return NULL;
781}
782
794uint8_t *id3ReadPicture(uint8_t type, const ID3 *metadata, size_t *dataSize) {
795 if (metadata == NULL) {
796 *dataSize = 0;
797 return NULL;
798 }
799
800 if (metadata->id3v2 == NULL && metadata->id3v1 == NULL) {
801 *dataSize = 0;
802 return NULL;
803 }
804
805 switch (internal_getSafePrefStd(metadata)) {
807 *dataSize = 0;
808 return NULL;
812 return id3v2ReadPicture(type, metadata->id3v2, dataSize);
813 default:
814 break;
815 }
816
817 *dataSize = 0;
818 return NULL;
819}
820
830int id3WriteTitle(const char *title, ID3 *metadata) {
831 if (metadata == NULL || title == NULL) {
832 return false;
833 }
834
835 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
836 return false;
837 }
838
839 switch (internal_getSafePrefStd(metadata)) {
841 return id3v1WriteTitle(title, metadata->id3v1);
845 return id3v2WriteTitle(title, metadata->id3v2);
846 default:
847 break;
848 }
849
850 return false;
851}
852
862int id3WriteArtist(const char *artist, ID3 *metadata) {
863 if (metadata == NULL || artist == NULL) {
864 return false;
865 }
866
867 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
868 return false;
869 }
870
871 switch (internal_getSafePrefStd(metadata)) {
873 return id3v1WriteArtist(artist, metadata->id3v1);
877 return id3v2WriteArtist(artist, metadata->id3v2);
878 default:
879 break;
880 }
881
882 return false;
883}
884
894int id3WriteAlbumArtist(const char *albumArtist, ID3 *metadata) {
895 if (metadata == NULL || albumArtist == NULL) {
896 return false;
897 }
898
899 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
900 return false;
901 }
902
903 switch (internal_getSafePrefStd(metadata)) {
907 return id3v2WriteAlbumArtist(albumArtist, metadata->id3v2);
909 default:
910 break;
911 }
912
913 return false;
914}
915
925int id3WriteAlbum(const char *album, ID3 *metadata) {
926 if (metadata == NULL || album == NULL) {
927 return false;
928 }
929
930 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
931 return false;
932 }
933
934 switch (internal_getSafePrefStd(metadata)) {
936 return id3v1WriteAlbum(album, metadata->id3v1);
940 return id3v2WriteAlbum(album, metadata->id3v2);
941 default:
942 break;
943 }
944
945 return false;
946}
947
958int id3WriteYear(const char *year, ID3 *metadata) {
959 if (metadata == NULL || year == NULL) {
960 return false;
961 }
962
963 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
964 return false;
965 }
966
967 switch (internal_getSafePrefStd(metadata)) {
968 case ID3V1_TAG_VERSION: {
969 int convi = 0;
970 char *end = NULL;
971 convi = (int) strtol(year, &end, 10);
972 return id3v1WriteYear(convi, metadata->id3v1);
973 }
977 return id3v2WriteYear(year, metadata->id3v2);
978 default:
979 break;
980 }
981
982 return false;
983}
984
995int id3WriteGenre(const char *genre, ID3 *metadata) {
996 if (metadata == NULL || genre == NULL) {
997 return false;
998 }
999
1000 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
1001 return false;
1002 }
1003
1004 switch (internal_getSafePrefStd(metadata)) {
1005 case ID3V1_TAG_VERSION: {
1006 uint8_t usableGenre = (uint8_t) genre[0] > PSYBIENT_GENRE ? OTHER_GENRE : (uint8_t) genre[0];
1007 return id3v1WriteGenre(usableGenre, metadata->id3v1);
1008 }
1012 return id3v2WriteGenre(genre, metadata->id3v2);
1013 default:
1014 break;
1015 }
1016
1017 return false;
1018}
1019
1030int id3WriteTrack(const char *track, ID3 *metadata) {
1031 if (metadata == NULL || track == NULL) {
1032 return false;
1033 }
1034
1035 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
1036 return false;
1037 }
1038
1039 switch (internal_getSafePrefStd(metadata)) {
1040 case ID3V1_TAG_VERSION: {
1041 int convi = 0;
1042 char *end = NULL;
1043 convi = (int) strtol(track, &end, 10);
1044
1045 if (convi > UINT8_MAX) {
1046 convi = UINT8_MAX;
1047 } else if (convi < 0) {
1048 convi = 0;
1049 }
1050
1051 return id3v1WriteTrack(convi, metadata->id3v1);
1052 }
1056 return id3v2WriteTrack(track, metadata->id3v2);
1057 default:
1058 break;
1059 }
1060
1061 return false;
1062}
1063
1073int id3WriteDisc(const char *disc, ID3 *metadata) {
1074 if (metadata == NULL || disc == NULL) {
1075 return false;
1076 }
1077
1078 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
1079 return false;
1080 }
1081
1082 switch (internal_getSafePrefStd(metadata)) {
1086 return id3v2WriteDisc(disc, metadata->id3v2);
1087 case ID3V1_TAG_VERSION:
1088 default:
1089 break;
1090 }
1091
1092 return false;
1093}
1094
1104int id3WriteComposer(const char *composer, ID3 *metadata) {
1105 if (metadata == NULL || composer == NULL) {
1106 return false;
1107 }
1108
1109 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
1110 return false;
1111 }
1112
1113 switch (internal_getSafePrefStd(metadata)) {
1117 return id3v2WriteComposer(composer, metadata->id3v2);
1118 case ID3V1_TAG_VERSION:
1119 default:
1120 break;
1121 }
1122
1123 return false;
1124}
1125
1135int id3WriteLyrics(const char *lyrics, ID3 *metadata) {
1136 if (metadata == NULL || lyrics == NULL) {
1137 return false;
1138 }
1139
1140 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
1141 return false;
1142 }
1143
1144 switch (internal_getSafePrefStd(metadata)) {
1148 return id3v2WriteLyrics(lyrics, metadata->id3v2);
1149 case ID3V1_TAG_VERSION:
1150 default:
1151 break;
1152 }
1153
1154 return false;
1155}
1156
1166int id3WriteComment(const char *comment, ID3 *metadata) {
1167 if (metadata == NULL || comment == NULL) {
1168 return false;
1169 }
1170
1171 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
1172 return false;
1173 }
1174
1175 switch (internal_getSafePrefStd(metadata)) {
1176 case ID3V1_TAG_VERSION:
1177 return id3v1WriteComment(comment, metadata->id3v1);
1181 return id3v2WriteComment(comment, metadata->id3v2);
1182 default:
1183 break;
1184 }
1185
1186 return false;
1187}
1188
1201int id3WritePicture(uint8_t *image, size_t imageSize, const char *kind, uint8_t type, ID3 *metadata) {
1202 if (metadata == NULL || image == NULL || kind == NULL) {
1203 return false;
1204 }
1205
1206 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
1207 return false;
1208 }
1209
1210 switch (internal_getSafePrefStd(metadata)) {
1214 return id3v2WritePicture(image, imageSize, kind, type, metadata->id3v2);
1215 case ID3V1_TAG_VERSION:
1216 default:
1217 break;
1218 }
1219
1220 return false;
1221}
1222
1234int id3WritePictureFromFile(const char *filename, const char *kind, uint8_t type, ID3 *metadata) {
1235 if (metadata == NULL || filename == NULL || kind == NULL) {
1236 return false;
1237 }
1238
1239 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
1240 return false;
1241 }
1242
1243 switch (internal_getSafePrefStd(metadata)) {
1247 return id3v2WritePictureFromFile(filename, kind, type, metadata->id3v2);
1248 case ID3V1_TAG_VERSION:
1249 default:
1250 break;
1251 }
1252
1253 return false;
1254}
1255
1271char *id3ToJSON(const ID3 *metadata) {
1272 char *json = NULL;
1273 char *id3v1 = NULL;
1274 char *id3v2 = NULL;
1275 size_t memCount = 3;
1276
1277 if (metadata == NULL) {
1278 json = calloc(memCount, sizeof(char));
1279 memcpy(json, "{}\0", memCount);
1280 return json;
1281 }
1282
1283 id3v1 = id3v1ToJSON(metadata->id3v1);
1284 id3v2 = id3v2TagToJSON(metadata->id3v2);
1285
1286 memCount += snprintf(NULL, 0, "{\"id3v1\":%s,\"id3v2\":%s}", id3v1, id3v2);
1287 json = calloc(memCount, sizeof(char));
1288 (void) snprintf(json, memCount, "{\"ID3v1\":%s,\"ID3v2\":%s}", id3v1, id3v2);
1289
1290 free(id3v1);
1291 free(id3v2);
1292
1293 return json;
1294}
1295
1305int id3WriteToFile(const char *filePath, const ID3 *metadata) {
1306 if (filePath == NULL || metadata == NULL) {
1307 return false;
1308 }
1309
1310 // no point in trying
1311 if (metadata->id3v1 == NULL && metadata->id3v2 == NULL) {
1312 return false;
1313 }
1314
1315
1316 bool v1 = false;
1317 bool v2 = false;
1318
1319 v1 = id3v1WriteTagToFile(filePath, metadata->id3v1);
1320 v2 = id3v2WriteTagToFile(filePath, metadata->id3v2);
1321
1322
1323 if (v1 && v2) {
1324 return true;
1325 }
1326
1327 if (v1 == false && (v2 == true && metadata->id3v1 == NULL)) {
1328 return true;
1329 }
1330
1331 if (v2 == false && (v1 == true && metadata->id3v2 == NULL)) {
1332 return true;
1333 }
1334
1335 return false;
1336}
char * id3ReadDisc(const ID3 *metadata)
Reads the disc number from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:700
ID3 * id3FromFile(const char *filePath)
Reads both ID3v1 and ID3v2 tags from a file into an ID3 metadata structure.
Definition id3dev.c:103
char * id3ReadComposer(const ID3 *metadata)
Reads the composer from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:670
char * id3ToJSON(const ID3 *metadata)
Converts an ID3 metadata structure to a JSON string.
Definition id3dev.c:1271
int id3WriteTitle(const char *title, ID3 *metadata)
Writes a title to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:830
char * id3ReadArtist(const ID3 *metadata)
Reads the artist from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:448
char * id3ReadGenre(const ID3 *metadata)
Reads the genre from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:585
bool id3SetPreferredStandard(uint8_t standard)
Sets the preferred ID3 standard for reading metadata from tag structures.
Definition id3dev.c:68
void id3Destroy(ID3 **toDelete)
Destroys an ID3 metadata structure and frees all associated memory.
Definition id3dev.c:50
int id3WriteComposer(const char *composer, ID3 *metadata)
Writes a composer to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:1104
char * id3ReadAlbum(const ID3 *metadata)
Reads the album from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:509
int id3WriteAlbumArtist(const char *albumArtist, ID3 *metadata)
Writes an album artist to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:894
int id3WriteYear(const char *year, ID3 *metadata)
Writes a year to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:958
char * id3ReadYear(const ID3 *metadata)
Reads the year from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:541
int id3WriteTrack(const char *track, ID3 *metadata)
Writes a track number to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:1030
int id3WritePicture(uint8_t *image, size_t imageSize, const char *kind, uint8_t type, ID3 *metadata)
Writes a picture to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:1201
static uint8_t id3PreferredStandard
default standard for reading ID3 tags from a data structure representation.
Definition id3dev.c:25
bool id3Compare(const ID3 *metadata1, const ID3 *metadata2)
Compares two ID3 metadata structures for equality.
Definition id3dev.c:130
char * id3ReadAlbumArtist(const ID3 *metadata)
Reads the album artist from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:479
bool id3ConvertId3v1ToId3v2(ID3 *metadata)
Converts the ID3v1 tag to an ID3v2 tag within the metadata structure.
Definition id3dev.c:167
int id3WriteArtist(const char *artist, ID3 *metadata)
Writes an artist to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:862
ID3 * id3Copy(const ID3 *toCopy)
Creates a deep copy of an ID3 metadata structure.
Definition id3dev.c:114
ID3 * id3Create(Id3v2Tag *id3v2, Id3v1Tag *id3v1)
Creates a new ID3 metadata structure containing ID3v2 and ID3v1 tags.
Definition id3dev.c:35
int id3WriteDisc(const char *disc, ID3 *metadata)
Writes a disc number to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:1073
uint8_t * id3ReadPicture(uint8_t type, const ID3 *metadata, size_t *dataSize)
Reads a picture of the specified type from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:794
int id3WriteComment(const char *comment, ID3 *metadata)
Writes a comment to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:1166
char * id3ReadLyrics(const ID3 *metadata)
Reads the lyrics from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:730
int id3WritePictureFromFile(const char *filename, const char *kind, uint8_t type, ID3 *metadata)
Writes a picture from a file to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:1234
int id3WriteToFile(const char *filePath, const ID3 *metadata)
Writes both ID3v1 and ID3v2 tags to a file using the given ID3 structure.
Definition id3dev.c:1305
char * id3ReadTrack(const ID3 *metadata)
Reads the track number from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:628
int id3WriteLyrics(const char *lyrics, ID3 *metadata)
Writes lyrics to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:1135
int id3WriteAlbum(const char *album, ID3 *metadata)
Writes an album to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:925
bool id3ConvertId3v2ToId3v1(ID3 *metadata)
Converts the ID3v2 tag to an ID3v1 tag within the metadata structure.
Definition id3dev.c:295
char * id3ReadComment(const ID3 *metadata)
Reads the comment from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:760
char * id3ReadTitle(const ID3 *metadata)
Reads the title from an ID3 metadata structure using the preferred standard.
Definition id3dev.c:417
int id3WriteGenre(const char *genre, ID3 *metadata)
Writes a genre to an ID3 metadata structure using the preferred standard.
Definition id3dev.c:995
uint8_t id3GetPreferredStandard(void)
Returns the currently configured preferred ID3 standard.
Definition id3dev.c:90
Decleations for reading, writing, converting, and comparing ID3v1 and ID3v2 metadata tags.
struct _ID3 ID3
A structure of both ID3v1 and ID3v2 tags.
Id3v1Tag * id3v1CopyTag(Id3v1Tag *toCopy)
Creates a deep copy of an Id3v1Tag structure.
Definition id3v1.c:64
char * id3v1ReadComment(const Id3v1Tag *tag)
Reads the comment member from an Id3v1Tag.
Definition id3v1.c:679
char * id3v1GenreFromTable(Genre val)
Converts a Genre enum value to it's string representation.
Definition id3v1.c:235
int id3v1WriteArtist(const char *artist, Id3v1Tag *tag)
Writes an artist to an Id3v1Tag.
Definition id3v1.c:111
char * id3v1ReadArtist(const Id3v1Tag *tag)
Reads the artist member from an Id3v1Tag.
Definition id3v1.c:645
int id3v1WriteGenre(Genre genre, Id3v1Tag *tag)
Writes a Genre to an Id3v1Tag.
Definition id3v1.c:160
int id3v1WriteTagToFile(const char *filePath, const Id3v1Tag *tag)
Writes/Overwrites an Id3v1Tag to the bottom of a file .
Definition id3v1.c:759
char * id3v1ToJSON(const Id3v1Tag *tag)
Converts an Id3v1Tag to a JSON string representation.
Definition id3v1.c:713
int id3v1WriteComment(const char *comment, Id3v1Tag *tag)
Writes a comment to an Id3v1Tag.
Definition id3v1.c:149
char * id3v1ReadTitle(const Id3v1Tag *tag)
Reads the title member from an Id3v1Tag.
Definition id3v1.c:633
int id3v1WriteAlbum(const char *album, Id3v1Tag *tag)
Writes an album to an Id3v1Tag.
Definition id3v1.c:122
int id3v1WriteTitle(const char *title, Id3v1Tag *tag)
Writes a title to an Id3v1Tag.
Definition id3v1.c:100
Id3v1Tag * id3v1TagFromFile(const char *filePath)
Creates an Id3v1Tag from a provided file path.
Definition id3v1.c:29
int id3v1WriteTrack(int track, Id3v1Tag *tag)
Writes a track number to an Id3v1Tag.
Definition id3v1.c:176
int id3v1WriteYear(int year, Id3v1Tag *tag)
Writes a year to an Id3v1Tag.
Definition id3v1.c:133
bool id3v1CompareTag(const Id3v1Tag *tag1, const Id3v1Tag *tag2)
Compares two Id3v1Tag structures for equality.
Definition id3v1.c:192
char * id3v1ReadAlbum(const Id3v1Tag *tag)
Reads the album member from an Id3v1Tag.
Definition id3v1.c:657
void id3v1DestroyTag(Id3v1Tag **toDelete)
Frees an Id3v1Tag and nullifies the pointer.
Id3v1Tag * id3v1CreateTag(uint8_t *title, uint8_t *artist, uint8_t *albumTitle, int year, int track, uint8_t *comment, Genre genre)
Creates and allocates a new Id3v1Tag structure.
Definition id3v1Parser.c:41
@ OTHER_GENRE
Other Music Genres not Defined.
Definition id3v1Types.h:68
@ PSYBIENT_GENRE
Psybient Audio.
Definition id3v1Types.h:428
#define ID3V1_TAG_VERSION
Major version number for ID3v1 and ID3v1.1 specification (always 1)
Definition id3v1Types.h:34
struct _Id3v1Tag Id3v1Tag
ID3v1/ID3v1.1 tag structure containing all metadata fields.
Declarations of ID3v2 tag operations including reading/writing metadata frames, tag serialization,...
int id3v2WriteLyrics(const char *lyrics, Id3v2Tag *tag)
Writes lyrics to the appropriate unsynchronized lyrics frame in a tag.
Definition id3v2.c:1290
char * id3v2ReadAlbum(Id3v2Tag *tag)
Extracts the album name from an ID3v2 tag.
Definition id3v2.c:483
int id3v2WriteGenre(const char *genre, Id3v2Tag *tag)
Writes the genre/content type to an ID3v2 tag.
Definition id3v2.c:1077
bool id3v2CompareTag(Id3v2Tag *tag1, Id3v2Tag *tag2)
Performs deep structural comparison of two ID3v2 tags for equality.
Definition id3v2.c:89
int id3v2WritePictureFromFile(const char *filename, const char *kind, uint8_t type, Id3v2Tag *tag)
Reads a picture from a file and writes it to the appropriate attached picture frame in a tag.
Definition id3v2.c:1932
char * id3v2ReadGenre(Id3v2Tag *tag)
Extracts the genre/content type from an ID3v2 tag.
Definition id3v2.c:541
int id3v2WriteYear(const char *year, Id3v2Tag *tag)
Writes the year to an ID3v2 tag.
Definition id3v2.c:1051
char * id3v2ReadTrack(Id3v2Tag *tag)
Extracts the track number/position from an ID3v2 tag.
Definition id3v2.c:570
char * id3v2ReadYear(Id3v2Tag *tag)
Extracts the year from an ID3v2 tag.
Definition id3v2.c:512
char * id3v2ReadTitle(Id3v2Tag *tag)
Extracts the title/song name from an ID3v2 tag.
Definition id3v2.c:396
char * id3v2ReadAlbumArtist(Id3v2Tag *tag)
Extracts the album artist/band/orchestra from an ID3v2 tag.
Definition id3v2.c:454
int id3v2WritePicture(uint8_t *image, size_t imageSize, const char *kind, uint8_t type, Id3v2Tag *tag)
Writes a picture to the appropriate attached picture frame in a tag.
Definition id3v2.c:1794
char * id3v2ReadComment(Id3v2Tag *tag)
Extracts the comment text from an ID3v2 tag.
Definition id3v2.c:727
uint8_t * id3v2ReadPicture(uint8_t type, const Id3v2Tag *tag, size_t *dataSize)
Extracts picture/artwork data of a specific type from an ID3v2 tag.
Definition id3v2.c:797
char * id3v2ReadComposer(Id3v2Tag *tag)
Extracts the composer from an ID3v2 tag.
Definition id3v2.c:599
int id3v2WriteAlbumArtist(const char *albumArtist, Id3v2Tag *tag)
Writes the album artist/band/orchestra to an ID3v2 tag.
Definition id3v2.c:999
char * id3v2ReadArtist(Id3v2Tag *tag)
Extracts the lead artist/performer from an ID3v2 tag.
Definition id3v2.c:425
int id3v2WriteDisc(const char *disc, Id3v2Tag *tag)
Writes a disc number to the appropriate disc number frame in a tag.
Definition id3v2.c:1129
char * id3v2ReadDisc(Id3v2Tag *tag)
Extracts the disc number/position from an ID3v2 tag.
Definition id3v2.c:628
int id3v2WriteComposer(const char *composer, Id3v2Tag *tag)
Writes a composer name to the appropriate composer frame in a tag.
Definition id3v2.c:1155
Id3v2Tag * id3v2TagFromFile(const char *filename)
Reads and parses an ID3v2 tag from a file.
Definition id3v2.c:31
int id3v2WriteTagToFile(const char *filename, Id3v2Tag *tag)
Writes an ID3v2 tag to a file, creating, prepending, or replacing as needed.
Definition id3v2.c:2317
Id3v2Tag * id3v2CopyTag(const Id3v2Tag *toCopy)
Creates a deep copy of an ID3v2 tag structure.
Definition id3v2.c:57
int id3v2WriteTitle(const char *title, Id3v2Tag *tag)
Writes the title/song name to an ID3v2 tag.
Definition id3v2.c:947
char * id3v2TagToJSON(Id3v2Tag *tag)
Serializes an ID3v2 tag structure to JSON format.
Definition id3v2.c:2184
int id3v2WriteArtist(const char *artist, Id3v2Tag *tag)
Writes the lead artist/performer to an ID3v2 tag.
Definition id3v2.c:973
int id3v2WriteTrack(const char *track, Id3v2Tag *tag)
Writes the track number/position to an ID3v2 tag.
Definition id3v2.c:1103
int id3v2WriteAlbum(const char *album, Id3v2Tag *tag)
Writes the album name to an ID3v2 tag.
Definition id3v2.c:1025
char * id3v2ReadLyrics(Id3v2Tag *tag)
Extracts unsynchronised lyrics/text transcription from an ID3v2 tag.
Definition id3v2.c:658
int id3v2WriteComment(const char *comment, Id3v2Tag *tag)
Writes a comment to the appropriate comment frame in a tag.
Definition id3v2.c:1553
Function definitions for ID3v2 frame lifecycle, traversal, serialization, and content management.
int id3v2CompareFrame(const void *first, const void *second)
Performs deep comparison of two ID3v2 frame structures.
Definition id3v2Frame.c:241
void * id3v2CopyFrame(const void *toBeCopied)
Creates a deep copy of an ID3v2 frame structure.
Definition id3v2Frame.c:364
char * id3v2PrintFrame(const void *toBePrinted)
Generates a string representation of a frame for debugging.
Definition id3v2Frame.c:341
void id3v2DeleteFrame(void *toBeDeleted)
Frees all memory allocated for an ID3v2 frame structure.
Definition id3v2Frame.c:226
Id3v2Tag * id3v2CreateTag(Id3v2TagHeader *header, List *frames)
Creates and allocates an ID3v2 tag structure.
void id3v2DestroyTag(Id3v2Tag **toDelete)
Frees an ID3v2 tag and all associated resources, nullifying the pointer.
Id3v2TagHeader * id3v2CreateTagHeader(uint8_t majorVersion, uint8_t minorVersion, uint8_t flags, Id3v2ExtendedTagHeader *extendedHeader)
Creates and allocates an ID3v2 tag header structure.
#define ID3V2_TAG_VERSION_3
ID3v2.3 major version number (3)
Definition id3v2Types.h:43
struct _Id3v2Tag Id3v2Tag
Complete ID3v2 tag structure containing header and metadata frames.
#define ID3V2_TAG_VERSION_2
ID3v2.2 major version number (2)
Definition id3v2Types.h:40
#define ID3V2_TAG_VERSION_4
ID3v2.4 major version number (4)
Definition id3v2Types.h:46
struct _Id3v2TagHeader Id3v2TagHeader
ID3v2 tag header containing version and parsing information.
Id3v1Tag * id3v1
An ID3v1 or ID3v1.1 Tag.
Definition id3dev.h:30
Id3v2Tag * id3v2
An ID3v2.2, ID3v2.3, or ID3v2.4 Tag.
Definition id3dev.h:28
int track
Track number (0 if not present, ID3v1.1 only)
Definition id3v1Types.h:451
Genre genre
Genre value (0-191, maps to Genre enum)
Definition id3v1Types.h:457
uint8_t artist[ID3V1_FIELD_SIZE]
Artist name (ID3V1_FIELD_SIZE bytes, null-padded)
Definition id3v1Types.h:442
uint8_t comment[ID3V1_FIELD_SIZE]
Comment text (ID3V1_FIELD_SIZE bytes, null-padded; ID3V1_FIELD_SIZE - 2 bytes if track number present...
Definition id3v1Types.h:454
uint8_t title[ID3V1_FIELD_SIZE]
Song title (ID3V1_FIELD_SIZE bytes, null-padded)
Definition id3v1Types.h:439
int year
Release year (4-digit integer)
Definition id3v1Types.h:448
uint8_t albumTitle[ID3V1_FIELD_SIZE]
Album title (ID3V1_FIELD_SIZE bytes, null-padded)
Definition id3v1Types.h:445