id3dev 26.01 An ID3 metadata library

Loading...
Searching...
No Matches
id3v2TagIdentity.c
Go to the documentation of this file.
1
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include "id3v2/id3v2TagIdentity.h"
16#include "id3dependencies/ByteStream/include/byteStream.h"
17#include "id3dependencies/ByteStream/include/byteInt.h"
18
29 Id3v2TagHeader *id3v2CreateTagHeader(uint8_t majorVersion, uint8_t minorVersion, uint8_t flags,
30 Id3v2ExtendedTagHeader *extendedHeader) {
31 Id3v2TagHeader *header = malloc(sizeof(Id3v2TagHeader));
32
33 header->majorVersion = majorVersion;
34 header->minorVersion = minorVersion;
35 header->flags = flags;
36 header->extendedHeader = extendedHeader;
37
38 return header;
39}
40
47 void id3v2DestroyTagHeader(Id3v2TagHeader **toDelete) {
48 if (*toDelete) {
49 id3v2DestroyExtendedTagHeader(&((*toDelete)->extendedHeader));
50 free(*toDelete);
51 *toDelete = NULL;
52 toDelete = NULL;
53 }
54}
55
63 bool id3v2WriteUnsynchronisationIndicator(Id3v2TagHeader *header, bool bit) {
64 if (!header) {
65 return 0;
66 }
67
68 //set bit 8
69 header->flags = setBit(header->flags, 7, bit);
70 return 1;
71}
72
81 bool id3v2WriteCompressionIndicator(Id3v2TagHeader *header, bool bit) {
82 if (!header) {
83 return 0;
84 }
85
86 if (header->majorVersion == ID3V2_TAG_VERSION_2) {
87 header->flags = setBit(header->flags, 6, bit);
88 return 1;
89 }
90
91 return 0;
92}
93
102 bool id3v2WriteExtendedHeaderIndicator(Id3v2TagHeader *header, bool bit) {
103 if (!header) {
104 return 0;
105 }
106
107 //set bit 7 or do nothing
108 switch (header->majorVersion) {
109 case ID3V2_TAG_VERSION_3:
110 case ID3V2_TAG_VERSION_4:
111 header->flags = setBit(header->flags, 6, bit);
112 return 1;
113 default:
114 break;
115 }
116
117 return 0;
118}
119
128 bool id3v2WriteExperimentalIndicator(Id3v2TagHeader *header, bool bit) {
129 if (!header) {
130 return 0;
131 }
132
133 //set bit 6 or do nothing
134 switch (header->majorVersion) {
135 case ID3V2_TAG_VERSION_3:
136 case ID3V2_TAG_VERSION_4:
137 header->flags = setBit(header->flags, 5, bit);
138 return 1;
139 default:
140 break;
141 }
142
143 return 0;
144}
145
154 bool id3v2WriteFooterIndicator(Id3v2TagHeader *header, bool bit) {
155 if (!header) {
156 return 0;
157 }
158
159 switch (header->majorVersion) {
160 case ID3V2_TAG_VERSION_4:
161 header->flags = setBit(header->flags, 4, bit);
162 return 1;
163 default:
164 break;
165 }
166
167 return 0;
168}
169
176 int id3v2ReadUnsynchronisationIndicator(Id3v2TagHeader *header) {
177 if (!header) {
178 return -1;
179 }
180
181 return readBit(header->flags, 7);
182}
183
190 int id3v2ReadCompressionIndicator(Id3v2TagHeader *header) {
191 if (!header) {
192 return -1;
193 }
194
195 if (header->majorVersion != ID3V2_TAG_VERSION_2) {
196 return -1;
197 }
198
199 return readBit(header->flags, 6);
200}
201
209 int id3v2ReadExtendedHeaderIndicator(Id3v2TagHeader *header) {
210 if (!header) {
211 return -1;
212 }
213
214 switch (header->majorVersion) {
215 case ID3V2_TAG_VERSION_3:
216 case ID3V2_TAG_VERSION_4:
217 return readBit(header->flags, 6);
218 default:
219 break;
220 }
221
222 return -1;
223}
224
233 int id3v2ReadExperimentalIndicator(Id3v2TagHeader *header) {
234 if (!header) {
235 return -1;
236 }
237
238 switch (header->majorVersion) {
239 case ID3V2_TAG_VERSION_3:
240 case ID3V2_TAG_VERSION_4:
241 return readBit(header->flags, 5);
242 default:
243 break;
244 }
245
246 return -1;
247}
248
256 int id3v2ReadFooterIndicator(Id3v2TagHeader *header) {
257 if (!header) {
258 return -1;
259 }
260
261 if (header->majorVersion != ID3V2_TAG_VERSION_4) {
262 return -1;
263 }
264
265 return readBit(header->flags, 4);
266}
267
280 Id3v2ExtendedTagHeader *id3v2CreateExtendedTagHeader(uint32_t padding, uint32_t crc, bool update, bool tagRestrictions,
281 uint8_t restrictions) {
282 Id3v2ExtendedTagHeader *extendedHeader = malloc(sizeof(Id3v2ExtendedTagHeader));
283
284 memset(extendedHeader, 0, sizeof(Id3v2ExtendedTagHeader));
285
286 extendedHeader->padding = padding;
287 extendedHeader->crc = crc;
288 extendedHeader->update = update;
289 extendedHeader->tagRestrictions = tagRestrictions;
290 extendedHeader->restrictions = restrictions;
291
292 return extendedHeader;
293}
294
301 void id3v2DestroyExtendedTagHeader(Id3v2ExtendedTagHeader **toDelete) {
302 //error address free
303 if (*toDelete) {
304 free(*toDelete);
305 *toDelete = NULL;
306 toDelete = NULL;
307 }
308}
309
319 bool id3v2WriteTagSizeRestriction(Id3v2TagHeader *header, uint8_t bits) {
320 //0b00, 0b01, 0b10, 0b11 making the max option 0x03
321 if (!header || bits > 0x03) {
322 return false;
323 }
324
325 if (header->majorVersion != ID3V2_TAG_VERSION_4) {
326 return false;
327 }
328
329 if (!header->extendedHeader) {
330 Id3v2ExtendedTagHeader *extendedHeader = id3v2CreateExtendedTagHeader(0, 0, 0, 0, 0);
331 header->extendedHeader = extendedHeader;
332 }
333
334 // I don't care it will get set every time
335 header->extendedHeader->tagRestrictions = true;
336
337 header->extendedHeader->restrictions = setBit(header->extendedHeader->restrictions, 6, readBit(bits, 0));
338 header->extendedHeader->restrictions = setBit(header->extendedHeader->restrictions, 7, readBit(bits, 1));
339
340 return true;
341}
342
353 bool id3v2WriteTextEncodingRestriction(Id3v2TagHeader *header, bool bit) {
354 if (!header) {
355 return false;
356 }
357
358 if (header->majorVersion != ID3V2_TAG_VERSION_4) {
359 return false;
360 }
361
362 if (!header->extendedHeader) {
363 Id3v2ExtendedTagHeader *extendedHeader = id3v2CreateExtendedTagHeader(0, 0, 0, 0, 0);
364 header->extendedHeader = extendedHeader;
365 }
366
367 //will set as true every time
368 header->extendedHeader->tagRestrictions = true;
369
370 header->extendedHeader->restrictions = setBit(header->extendedHeader->restrictions, 5, bit);
371
372 return true;
373}
374
385 bool id3v2WriteTextFieldsSizeRestriction(Id3v2TagHeader *header, uint8_t bits) {
386 //0b00, 0b01, 0b10, 0b11 making the max option 0x03
387 if (!header || bits > 0x03) {
388 return false;
389 }
390
391 if (header->majorVersion != ID3V2_TAG_VERSION_4) {
392 return false;
393 }
394
395 if (!header->extendedHeader) {
396 Id3v2ExtendedTagHeader *extendedHeader = id3v2CreateExtendedTagHeader(0, 0, 0, 0, 0);
397 header->extendedHeader = extendedHeader;
398 }
399
400 // I don't care it will get set every time
401 header->extendedHeader->tagRestrictions = true;
402
403 header->extendedHeader->restrictions = setBit(header->extendedHeader->restrictions, 4, readBit(bits, 1));
404 header->extendedHeader->restrictions = setBit(header->extendedHeader->restrictions, 3, readBit(bits, 0));
405
406 return true;
407}
408
419 bool id3v2WriteImageEncodingRestriction(Id3v2TagHeader *header, bool bit) {
420 if (!header) {
421 return false;
422 }
423
424 if (header->majorVersion != ID3V2_TAG_VERSION_4) {
425 return false;
426 }
427
428 if (!header->extendedHeader) {
429 Id3v2ExtendedTagHeader *extendedHeader = id3v2CreateExtendedTagHeader(0, 0, 0, 0, 0);
430 header->extendedHeader = extendedHeader;
431 }
432
433 //will set as true every time
434 header->extendedHeader->tagRestrictions = true;
435
436 header->extendedHeader->restrictions = setBit(header->extendedHeader->restrictions, 2, bit);
437
438 return true; //avoid warning
439}
440
451 bool id3v2WriteImageSizeRestriction(Id3v2TagHeader *header, uint8_t bits) {
452 //0b00, 0b01, 0b10, 0b11 making the max option 0x03
453 if (!header || bits > 0x03) {
454 return false;
455 }
456
457 if (header->majorVersion != ID3V2_TAG_VERSION_4) {
458 return false;
459 }
460
461 if (!header->extendedHeader) {
462 Id3v2ExtendedTagHeader *extendedHeader = id3v2CreateExtendedTagHeader(0, 0, 0, 0, 0);
463 header->extendedHeader = extendedHeader;
464 }
465
466 // I don't care it will get set every time
467 header->extendedHeader->tagRestrictions = true;
468
469 header->extendedHeader->restrictions = setBit(header->extendedHeader->restrictions, 1, readBit(bits, 1));
470 header->extendedHeader->restrictions = setBit(header->extendedHeader->restrictions, 0, readBit(bits, 0));
471
472 return true;
473}
474
483 int id3v2ReadTagSizeRestriction(Id3v2TagHeader *header) {
484 if (!header) {
485 return -1;
486 }
487
488 if (!header->extendedHeader) {
489 return -1;
490 }
491
492 //build an int from bits
493 int lsb = 0;
494 int msb = 0;
495
496 msb = readBit(header->extendedHeader->restrictions, 7);
497 lsb = readBit(header->extendedHeader->restrictions, 6);
498
499 //combine into an int
500 return (msb << 1) | lsb;
501}
502
510 int id3v2ReadTextEncodingRestriction(Id3v2TagHeader *header) {
511 if (!header) {
512 return -1;
513 }
514
515 if (!header->extendedHeader) {
516 return -1;
517 }
518
519 return readBit(header->extendedHeader->restrictions, 5);
520}
521
530 int id3v2ReadTextFieldsSizeRestriction(Id3v2TagHeader *header) {
531 if (!header) {
532 return -1;
533 }
534
535 if (!header->extendedHeader) {
536 return -1;
537 }
538
539 //build an int from bits
540 int lsb = 0;
541 int msb = 0;
542
543 msb = readBit(header->extendedHeader->restrictions, 4);
544 lsb = readBit(header->extendedHeader->restrictions, 3);
545
546 //combine into an int
547 return (msb << 1) | lsb;
548}
549
558 int id3v2ReadImageEncodingRestriction(Id3v2TagHeader *header) {
559 if (!header) {
560 return -1;
561 }
562
563 if (!header->extendedHeader) {
564 return -1;
565 }
566
567 return readBit(header->extendedHeader->restrictions, 2);
568}
569
578 int id3v2ReadImageSizeRestriction(Id3v2TagHeader *header) {
579 if (!header) {
580 return -1;
581 }
582
583 if (!header->extendedHeader) {
584 return -1;
585 }
586
587 //build an int from bits
588 int lsb = 0;
589 int msb = 0;
590
591 lsb = readBit(header->extendedHeader->restrictions, 0);
592 msb = readBit(header->extendedHeader->restrictions, 1);
593
594 return (msb << 1) | lsb;
595}
596
606 bool id3v2ClearTagRestrictions(Id3v2TagHeader *header) {
607 if (!header) {
608 return 0;
609 }
610
611 if (!header->extendedHeader) {
612 return 0;
613 }
614
615 header->extendedHeader->tagRestrictions = false;
616 header->extendedHeader->restrictions = 0;
617
618 return 1;
619}
620
630 Id3v2Tag *id3v2CreateTag(Id3v2TagHeader *header, List *frames) {
631 Id3v2Tag *tag = malloc(sizeof(Id3v2Tag));
632
633 tag->frames = frames;
634 tag->header = header;
635
636 return tag;
637}
638
646 void id3v2DestroyTag(Id3v2Tag **toDelete) {
647 if (*toDelete) {
648 id3v2DestroyTagHeader(&(*toDelete)->header);
649 listFree((*toDelete)->frames);
650 free(*toDelete);
651 *toDelete = NULL;
652 toDelete = NULL;
653 }
654}
655
676uint8_t *id3v2ExtendedTagHeaderSerialize(Id3v2ExtendedTagHeader *ext, uint8_t version, size_t *outl) {
677 ByteStream *stream = NULL;
678 uint8_t *out = NULL;
679 int buildSize = 0;
680 unsigned char *tmp = NULL;
681 unsigned char crcb[5] = {0, 0, 0, 0, 0};
682
683 if (ext == NULL) {
684 *outl = 0;
685 return NULL;
686 }
687
688 switch (version) {
689 case ID3V2_TAG_VERSION_3:
690
691 // size
692 buildSize = 10 + ((ext->crc) ? 4 : 0);
693
694 stream = byteStreamCreate(NULL, buildSize);
695
696 tmp = (unsigned char *) itob(buildSize);
697 byteStreamWrite(stream, tmp, 4);
698 free(tmp);
699
700 // flag
701 byteStreamWriteBit(stream, (ext->crc > 0) ? 1 : 0, 7);
702 byteStreamSeek(stream, 2, SEEK_CUR);
703
704 // crc
705 tmp = u32tob(ext->padding);
706 byteStreamWrite(stream, tmp, 4);
707 free(tmp);
708
709 if (ext->crc) {
710 tmp = u32tob(ext->crc);
711 byteStreamWrite(stream, tmp, 4);
712 free(tmp);
713 }
714
715 break;
716
717 case ID3V2_TAG_VERSION_4:
718
719 buildSize = 6 + ((ext->crc) ? 5 : 0) + ((ext->tagRestrictions) ? 1 : 0);
720
721 stream = byteStreamCreate(NULL, buildSize);
722
723
724 // ext size
725 tmp = u32tob(buildSize);
726 byteStreamWrite(stream, tmp, 4);
727 free(tmp);
728
729 // flag bytes
730 tmp = (unsigned char *) itob(buildSize - 6);
731 byteStreamWrite(stream, &tmp[3], 1);
732 free(tmp);
733
734 // flags
735 byteStreamWriteBit(stream, ext->update, 6);
736 byteStreamWriteBit(stream, (ext->crc > 0) ? 1 : 0, 5);
737 byteStreamWriteBit(stream, ext->tagRestrictions, 4);
738 byteStreamSeek(stream, 1, SEEK_CUR);
739
740 // crc
741 if (ext->crc) {
742 int offset = 0;
743 int toWrite = 0;
744 tmp = sttob(byteSyncintEncode(ext->crc));
745
746 while (offset < sizeof(size_t) && tmp[offset] == 0) {
747 offset++;
748 }
749
750 // c4c is 5 bytes if the 0s are there they must be kept
751 if (offset > 3) {
752 offset = 3;
753 }
754
755 toWrite = ((int) (sizeof(size_t) - offset) > 5) ? 5 : (int) (sizeof(size_t) - offset);
756 memcpy(crcb, tmp + offset, toWrite);
757
758 byteStreamSeek(stream, 6, SEEK_SET);
759 byteStreamWrite(stream, crcb, 5);
760 free(tmp);
761 }
762
763 if (ext->tagRestrictions) {
764 byteStreamWrite(stream, &ext->restrictions, 1);
765 }
766
767 break;
768
769 // no support or it does not exist
770 case ID3V2_TAG_VERSION_2:
771 default:
772 *outl = 0;
773 return NULL;
774 }
775
776 byteStreamRewind(stream);
777 out = calloc(stream->bufferSize, sizeof(uint8_t));
778 *outl = stream->bufferSize;
779 byteStreamRead(stream, out, stream->bufferSize);
780 byteStreamDestroy(stream);
781
782 return out;
783}
784
804 char *id3v2ExtendedTagHeaderToJSON(const Id3v2ExtendedTagHeader *ext, uint8_t version) {
805 char *json = NULL;
806 size_t memCount = 3;
807
808 if (ext == NULL) {
809 json = calloc(memCount, sizeof(char));
810 memcpy(json, "{}\0", memCount);
811 return json;
812 }
813
814 switch (version) {
815 case ID3V2_TAG_VERSION_3:
816
817 memCount += snprintf(NULL, 0,
818 "{\"padding\":%"PRIu32",\"crc\":%"PRIu32"}",
819 ext->padding,
820 ext->crc);
821
822 json = calloc(memCount + 1, sizeof(char)); // NOLINT(clang-analyzer-unix.Malloc)
823
824 (void) snprintf(json, memCount,
825 "{\"padding\":%"PRIu32",\"crc\":%"PRIu32"}",
826 ext->padding,
827 ext->crc);
828
829 break;
830 case ID3V2_TAG_VERSION_4:
831
832 memCount += snprintf(NULL, 0,
833 "{\"padding\":%"PRIu32",\"crc\":%"PRIu32
834 ",\"update\":%s,\"tagRestrictions\":%s,\"restrictions\":%d}",
835 ext->padding,
836 ext->crc,
837 ext->update ? "true" : "false",
838 ext->tagRestrictions ? "true" : "false",
839 ext->restrictions);
840
841 json = calloc(memCount + 1, sizeof(char)); // NOLINT(clang-analyzer-unix.Malloc)
842
843 (void) snprintf(json, memCount,
844 "{\"padding\":%"PRIu32",\"crc\":%"PRIu32
845 ",\"update\":%s,\"tagRestrictions\":%s,\"restrictions\":%d}",
846 ext->padding,
847 ext->crc,
848 ext->update ? "true" : "false",
849 ext->tagRestrictions ? "true" : "false",
850 ext->restrictions);
851
852 break;
853
854 // no support
855 case ID3V2_TAG_VERSION_2:
856 default:
857 json = malloc(sizeof(char) * memCount); // NOLINT(clang-analyzer-unix.Malloc)
858 memcpy(json, "{}\0", memCount);
859 break;
860 }
861
862
863 return json;
864}
865
883uint8_t *id3v2TagHeaderSerialize(Id3v2TagHeader *header, uint32_t uintSize, size_t *outl) {
884 ByteStream *stream = NULL;
885 uint8_t *out = NULL;
886 unsigned char *tmp = NULL;
887
888 if (header == NULL) {
889 *outl = 0;
890 return NULL;
891 }
892
893 // no support
894 if (header->majorVersion > ID3V2_TAG_VERSION_4) {
895 *outl = 0;
896 return NULL;
897 }
898
899 stream = byteStreamCreate(NULL, 10);
900
901 byteStreamWrite(stream, (uint8_t *) "ID3", ID3V2_TAG_ID_SIZE);
902
903 byteStreamWrite(stream, &header->majorVersion, 1);
904 byteStreamWrite(stream, &header->minorVersion, 1);
905
906
907 switch ((int) header->majorVersion) {
908 case ID3V2_TAG_VERSION_2:
909
910 byteStreamWriteBit(stream, (bool) id3v2ReadUnsynchronisationIndicator(header), 7);
911 byteStreamWriteBit(stream, (bool) id3v2ReadCompressionIndicator(header), 6);
912
913 break;
914 case ID3V2_TAG_VERSION_3:
915
916 byteStreamWriteBit(stream, (bool) id3v2ReadUnsynchronisationIndicator(header), 7);
917 byteStreamWriteBit(stream, (bool) id3v2ReadExtendedHeaderIndicator(header), 6);
918 byteStreamWriteBit(stream, (bool) id3v2ReadExperimentalIndicator(header), 5);
919
920 break;
921 case ID3V2_TAG_VERSION_4:
922
923 byteStreamWriteBit(stream, (bool) id3v2ReadUnsynchronisationIndicator(header), 7);
924 byteStreamWriteBit(stream, (bool) id3v2ReadExtendedHeaderIndicator(header), 6);
925 byteStreamWriteBit(stream, (bool) id3v2ReadExperimentalIndicator(header), 5);
926 byteStreamWriteBit(stream, (bool) id3v2ReadFooterIndicator(header), 4);
927
928 break;
929 // dummy break as header version is already checked to be less than 4
930 default:
931 break;
932 }
933
934 byteStreamSeek(stream, 1, SEEK_CUR);
935
936 tmp = u32tob(byteSyncintEncode(uintSize));
937 byteStreamWrite(stream, tmp, sizeof(uint32_t));
938 free(tmp);
939
940 if (id3v2ReadExtendedHeaderIndicator(header)) {
941 size_t extSize = 0;
942 uint8_t *ext = id3v2ExtendedTagHeaderSerialize(header->extendedHeader, header->majorVersion, &extSize);
943
944 if (ext != NULL) {
945 byteStreamResize(stream, stream->bufferSize + extSize);
946 byteStreamWrite(stream, ext, extSize);
947 free(ext);
948 }
949 }
950
951 byteStreamRewind(stream);
952 *outl = stream->bufferSize;
953 out = calloc(stream->bufferSize, sizeof(uint8_t));
954 byteStreamRead(stream, out, stream->bufferSize);
955 byteStreamDestroy(stream);
956 return out;
957}
958
980 char *id3v2TagHeaderToJSON(const Id3v2TagHeader *header) {
981 char *json = NULL;
982 size_t memCount = 3;
983 char *extJson = NULL;
984
985 if (header == NULL) {
986 json = calloc(memCount, sizeof(char));
987 memcpy(json, "{}\0", memCount);
988 return json;
989 }
990
991 switch (header->majorVersion) {
992 case ID3V2_TAG_VERSION_2:
993
994 memCount += snprintf(NULL, 0,
995 "{\"major\":%d,\"minor\":%d,\"flags\":%d}",
996 header->majorVersion,
997 header->minorVersion,
998 header->flags);
999
1000 json = calloc(memCount + 1, sizeof(char));
1001
1002 (void) snprintf(json, memCount,
1003 "{\"major\":%d,\"minor\":%d,\"flags\":%d}",
1004 header->majorVersion,
1005 header->minorVersion,
1006 header->flags);
1007
1008 break;
1009 case ID3V2_TAG_VERSION_3:
1010
1011 extJson = id3v2ExtendedTagHeaderToJSON(header->extendedHeader, ID3V2_TAG_VERSION_3);
1012
1013 memCount += snprintf(NULL, 0,
1014 "{\"major\":%d,\"minor\":%d,\"flags\":%d,\"extended\":%s}",
1015 header->majorVersion,
1016 header->minorVersion,
1017 header->flags,
1018 extJson);
1019
1020 json = calloc(memCount + 1, sizeof(char));
1021
1022
1023 (void) snprintf(json, memCount,
1024 "{\"major\":%d,\"minor\":%d,\"flags\":%d,\"extended\":%s}",
1025 header->majorVersion,
1026 header->minorVersion,
1027 header->flags,
1028 extJson);
1029
1030
1031 free(extJson);
1032 break;
1033 case ID3V2_TAG_VERSION_4:
1034 extJson = id3v2ExtendedTagHeaderToJSON(header->extendedHeader, ID3V2_TAG_VERSION_4);
1035
1036 memCount += snprintf(NULL, 0,
1037 "{\"major\":%d,\"minor\":%d,\"flags\":%d,\"extended\":%s}",
1038 header->majorVersion,
1039 header->minorVersion,
1040 header->flags,
1041 extJson);
1042
1043 json = calloc(memCount + 1, sizeof(char));
1044
1045
1046 (void) snprintf(json, memCount,
1047 "{\"major\":%d,\"minor\":%d,\"flags\":%d,\"extended\":%s}",
1048 header->majorVersion,
1049 header->minorVersion,
1050 header->flags,
1051 extJson);
1052
1053
1054 free(extJson);
1055 break;
1056
1057 // no support
1058 default:
1059 json = malloc(sizeof(char) * memCount);
1060 memcpy(json, "{}\0", memCount);
1061 break;
1062 }
1063
1064 return json;
1065}
id3v2TagHeaderToJSON
char * id3v2TagHeaderToJSON(const Id3v2TagHeader *header)
Converts an ID3v2 tag header structure to JSON string representation.
Definition id3v2TagIdentity.c:980
id3v2CreateTag
Id3v2Tag * id3v2CreateTag(Id3v2TagHeader *header, List *frames)
Creates and allocates an ID3v2 tag structure.
Definition id3v2TagIdentity.c:630
id3v2ReadImageSizeRestriction
int id3v2ReadImageSizeRestriction(Id3v2TagHeader *header)
Reads the image size restriction from an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:578
id3v2DestroyTag
void id3v2DestroyTag(Id3v2Tag **toDelete)
Frees an ID3v2 tag and all associated resources, nullifying the pointer.
Definition id3v2TagIdentity.c:646
id3v2WriteUnsynchronisationIndicator
bool id3v2WriteUnsynchronisationIndicator(Id3v2TagHeader *header, bool bit)
Sets or clears the unsynchronisation flag in the tag header.
Definition id3v2TagIdentity.c:63
id3v2ReadFooterIndicator
int id3v2ReadFooterIndicator(Id3v2TagHeader *header)
Reads the footer presence flag from an ID3v2.4 tag header.
Definition id3v2TagIdentity.c:256
id3v2ReadTextFieldsSizeRestriction
int id3v2ReadTextFieldsSizeRestriction(Id3v2TagHeader *header)
Reads the text fields size restriction from an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:530
id3v2CreateExtendedTagHeader
Id3v2ExtendedTagHeader * id3v2CreateExtendedTagHeader(uint32_t padding, uint32_t crc, bool update, bool tagRestrictions, uint8_t restrictions)
Creates and allocates an ID3v2 extended tag header structure.
Definition id3v2TagIdentity.c:280
id3v2ReadImageEncodingRestriction
int id3v2ReadImageEncodingRestriction(Id3v2TagHeader *header)
Reads the image encoding restriction from an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:558
id3v2ReadUnsynchronisationIndicator
int id3v2ReadUnsynchronisationIndicator(Id3v2TagHeader *header)
Reads the unsynchronisation flag from a tag header.
Definition id3v2TagIdentity.c:176
id3v2WriteExtendedHeaderIndicator
bool id3v2WriteExtendedHeaderIndicator(Id3v2TagHeader *header, bool bit)
Sets or clears the extended header flag in ID3v2.3/ID3v2.4 tag headers.
Definition id3v2TagIdentity.c:102
id3v2ReadExperimentalIndicator
int id3v2ReadExperimentalIndicator(Id3v2TagHeader *header)
Reads the experimental indicator flag from an ID3v2.3/ID3v2.4 tag header.
Definition id3v2TagIdentity.c:233
id3v2DestroyTagHeader
void id3v2DestroyTagHeader(Id3v2TagHeader **toDelete)
Frees an ID3v2 tag header and nullifies the pointer.
Definition id3v2TagIdentity.c:47
id3v2ExtendedTagHeaderSerialize
uint8_t * id3v2ExtendedTagHeaderSerialize(Id3v2ExtendedTagHeader *ext, uint8_t version, size_t *outl)
Serializes an ID3v2 extended tag header into a byte stream.
Definition id3v2TagIdentity.c:676
id3v2WriteFooterIndicator
bool id3v2WriteFooterIndicator(Id3v2TagHeader *header, bool bit)
Sets or clears the footer presence flag in ID3v2.4 tag headers.
Definition id3v2TagIdentity.c:154
id3v2WriteCompressionIndicator
bool id3v2WriteCompressionIndicator(Id3v2TagHeader *header, bool bit)
Sets or clears the compression flag in ID3v2.2 tag headers.
Definition id3v2TagIdentity.c:81
id3v2WriteTextEncodingRestriction
bool id3v2WriteTextEncodingRestriction(Id3v2TagHeader *header, bool bit)
Sets the text encoding restriction in an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:353
id3v2DestroyExtendedTagHeader
void id3v2DestroyExtendedTagHeader(Id3v2ExtendedTagHeader **toDelete)
Frees an ID3v2 extended tag header and nullifies the pointer.
Definition id3v2TagIdentity.c:301
id3v2CreateTagHeader
Id3v2TagHeader * id3v2CreateTagHeader(uint8_t majorVersion, uint8_t minorVersion, uint8_t flags, Id3v2ExtendedTagHeader *extendedHeader)
Creates and allocates an ID3v2 tag header structure.
Definition id3v2TagIdentity.c:29
id3v2WriteExperimentalIndicator
bool id3v2WriteExperimentalIndicator(Id3v2TagHeader *header, bool bit)
Sets or clears the experimental indicator flag in ID3v2.3/ID3v2.4 tag headers.
Definition id3v2TagIdentity.c:128
id3v2ReadExtendedHeaderIndicator
int id3v2ReadExtendedHeaderIndicator(Id3v2TagHeader *header)
Reads the extended header flag from an ID3v2.3/ID3v2.4 tag header.
Definition id3v2TagIdentity.c:209
id3v2WriteImageSizeRestriction
bool id3v2WriteImageSizeRestriction(Id3v2TagHeader *header, uint8_t bits)
Sets the image size restriction in an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:451
id3v2ReadTextEncodingRestriction
int id3v2ReadTextEncodingRestriction(Id3v2TagHeader *header)
Reads the text encoding restriction from an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:510
id3v2TagHeaderSerialize
uint8_t * id3v2TagHeaderSerialize(Id3v2TagHeader *header, uint32_t uintSize, size_t *outl)
Serializes an ID3v2 tag header into a byte stream.
Definition id3v2TagIdentity.c:883
id3v2ReadCompressionIndicator
int id3v2ReadCompressionIndicator(Id3v2TagHeader *header)
Reads the compression flag from an ID3v2.2 tag header.
Definition id3v2TagIdentity.c:190
id3v2ExtendedTagHeaderToJSON
char * id3v2ExtendedTagHeaderToJSON(const Id3v2ExtendedTagHeader *ext, uint8_t version)
Converts an ID3v2 extended tag header structure to JSON string representation.
Definition id3v2TagIdentity.c:804
id3v2WriteImageEncodingRestriction
bool id3v2WriteImageEncodingRestriction(Id3v2TagHeader *header, bool bit)
Sets the image encoding restriction in an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:419
id3v2WriteTagSizeRestriction
bool id3v2WriteTagSizeRestriction(Id3v2TagHeader *header, uint8_t bits)
Sets the tag size restriction in an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:319
id3v2ReadTagSizeRestriction
int id3v2ReadTagSizeRestriction(Id3v2TagHeader *header)
Reads the tag size restriction from an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:483
id3v2ClearTagRestrictions
bool id3v2ClearTagRestrictions(Id3v2TagHeader *header)
Clears all tag restrictions from an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:606
id3v2WriteTextFieldsSizeRestriction
bool id3v2WriteTextFieldsSizeRestriction(Id3v2TagHeader *header, uint8_t bits)
Sets the text encoding restriction in an ID3v2.4 extended header.
Definition id3v2TagIdentity.c:385
id3v2TagIdentity.h
Function definitions of ID3v2 tag header and tag structure creation, manipulation,...
ID3V2_TAG_VERSION_3
#define ID3V2_TAG_VERSION_3
ID3v2.3 major version number (3)
Definition id3v2Types.h:43
Id3v2Tag
struct _Id3v2Tag Id3v2Tag
Complete ID3v2 tag structure containing header and metadata frames.
ID3V2_TAG_VERSION_2
#define ID3V2_TAG_VERSION_2
ID3v2.2 major version number (2)
Definition id3v2Types.h:40
Id3v2ExtendedTagHeader
struct _Id3v2ExtendedTagHeader Id3v2ExtendedTagHeader
Optional ID3v2 extended header containing supplementary tag metadata.
ID3V2_TAG_ID_SIZE
#define ID3V2_TAG_ID_SIZE
Size in bytes of the ID3v2 tag identifier "ID3" or "3DI" (3 bytes)
Definition id3v2Types.h:31
ID3V2_TAG_VERSION_4
#define ID3V2_TAG_VERSION_4
ID3v2.4 major version number (4)
Definition id3v2Types.h:46
Id3v2TagHeader
struct _Id3v2TagHeader Id3v2TagHeader
ID3v2 tag header containing version and parsing information.
_Id3v2ExtendedTagHeader::restrictions
uint8_t restrictions
Bitfield defining tag restrictions in format ppqrrstt (ID3v2.4 only).
Definition id3v2Types.h:102
_Id3v2ExtendedTagHeader::crc
uint32_t crc
CRC-32 checksum of the tag's audio data for integrity verification.
Definition id3v2Types.h:89
_Id3v2ExtendedTagHeader::padding
uint32_t padding
Size of the extended header as either a 32-bit integer or syncsafe integer depending on version.
Definition id3v2Types.h:86
_Id3v2ExtendedTagHeader::update
bool update
Indicates this tag is an update to a previous tag (ID3v2.4 only)
Definition id3v2Types.h:92
_Id3v2ExtendedTagHeader::tagRestrictions
bool tagRestrictions
Indicates whether tag restrictions are applied.
Definition id3v2Types.h:95
_Id3v2TagHeader::minorVersion
uint8_t minorVersion
Minor version/revision number.
Definition id3v2Types.h:116
_Id3v2TagHeader::extendedHeader
Id3v2ExtendedTagHeader * extendedHeader
Pointer to optional extended header structure. NULL if extended header flag not set.
Definition id3v2Types.h:125
_Id3v2TagHeader::majorVersion
uint8_t majorVersion
Major version number (2, 3, or 4 for ID3v2.2, ID3v2.3, ID3v2.4)
Definition id3v2Types.h:113
_Id3v2TagHeader::flags
uint8_t flags
Bitfield in format abcd0000 defining extra format and feature options of a tag.
Definition id3v2Types.h:122
_Id3v2Tag::frames
List * frames
Linked list of Id3v2Frame structures containing all tag metadata.
Definition id3v2Types.h:299
_Id3v2Tag::header
Id3v2TagHeader * header
Tag header with version, flags, and optional extended header.
Definition id3v2Types.h:296