diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/id3v2/id3_header_frame.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/id3v2/id3_header_frame.cpp')
-rw-r--r-- | Src/id3v2/id3_header_frame.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/Src/id3v2/id3_header_frame.cpp b/Src/id3v2/id3_header_frame.cpp new file mode 100644 index 00000000..4f7379bc --- /dev/null +++ b/Src/id3v2/id3_header_frame.cpp @@ -0,0 +1,181 @@ +// The authors have released ID3Lib as Public Domain (PD) and claim no copyright, +// patent or other intellectual property protection in this work. This means that +// it may be modified, redistributed and used in commercial and non-commercial +// software and hardware without restrictions. ID3Lib is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +// +// The ID3Lib authors encourage improvements and optimisations to be sent to the +// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved +// submissions may be altered, and will be included and released under these terms. +// +// Mon Nov 23 18:34:01 1998 + + +#include <string.h> +#include <memory.h> +#include "id3_header_frame.h" +#include "id3_error.h" + +bool ID3_FrameAttr::HasDataLength(int version) +{ + if (version == 4) + return !!(flags & ID3FL_DATA_LENGTH_2_4); + else + return 0; +} + +bool ID3_FrameAttr::HasCompression(int version) +{ + if (version == 4) + return !!(flags & ID3FL_COMPRESSION_2_4); + else + return !!(flags & ID3FL_COMPRESSION_2_3); +} + +bool ID3_FrameAttr::HasEncryption(int version) +{ + if (version == 4) + return !!(flags & ID3FL_ENCRYPTION_2_4); + else + return !!(flags & ID3FL_ENCRYPTION_2_3); +} + +bool ID3_FrameAttr::HasGrouping(int version) +{ + if (version == 4) + return !!(flags & ID3FL_GROUPING_2_4); + else + return !!(flags & ID3FL_GROUPING_2_3); +} + +bool ID3_FrameAttr::HasUnsync(int version) +{ + if (version == 4) + return !!(flags & ID3FL_UNSYNC_2_4); + else + return false; +} + +void ID3_FrameAttr::ClearUnSync(int version) +{ + if (version == 4) + flags&= ~ID3FL_UNSYNC_2_4; +} + +void ID3_FrameAttr::SetFlags(luint _flags) +{ + flags = _flags; +} + +void ID3_FrameHeader::SetFrameID (ID3_FrameID id) +{ + frameID = id; +} + +luint ID3_FrameHeader::Size(void) +{ + if (!info) + return 0; + return info->frameIDBytes + info->frameSizeBytes + info->frameFlagsBytes; +} + +// TODO: benski> we should make a return value of 0 mean 'error' +luint ID3_FrameHeader::GetFrameInfo(ID3_FrameAttr &attr, const uchar *buffer, size_t remSize) +{ + luint posn = 0; + luint i = 0, bpos = 4; + + // verify that the text is all between A-Z and 0-9 (for TALB and TIT2, etc) + for (i = 0; i < 4; i++) + { + if (!((buffer[i] >= '0' && buffer[i] <= '9') || (buffer[i] >= 'A' && buffer[i] <= 'Z'))) + { + // TODO: benski> return an error here + // this helps us to get ID3v2.2 PIC frames without + // breaking others since it's not null-terminated! + bpos = i; + } + } + + memcpy(attr.textID, (char *) buffer, (bpos > 0 && bpos <= 4 ? bpos : 4)); + if (bpos == 3) attr.textID[3] = 0; + attr.textID[4] = 0; + + posn += info->frameIDBytes; + + attr.size = 0; + + for (i = 0; i < info->frameSizeBytes; i++) + attr.size |= buffer[posn + i] << ((info->frameSizeBytes - 1 - i) * 8); + + if (version == 4) // 2.4 uses syncsafe sizes + { + // many programs write non-syncsafe sizes anyway (iTunes is the biggest culprit) + // so we'll try to detect it. unfortunately this isn't foolproof + int mask = attr.size & 0x80808080; + if (!quirks.id3v2_4_itunes_bug // make sure we've havn't previously identified that this tag has a problem + && mask == 0) // if none of the 'reserved' bits are set + { + attr.size = int28().setFromFile(attr.size).get(); // convert to syncsafe value + } + else + { + // benski> cut for now. this can't be trusted because it applies on subsequent re-parses but not anything before this + // quirks.id3v2_4_itunes_bug = true; // mark that the tag has a problem + } + // TODO: it'd be nice to look ahead into the buffer and make sure that our calculated size + // lets us land on the start of a new frame + // although that isn't foolproof either (non-standard fields, etc) + } + posn += info->frameSizeBytes; + + luint flags=0; + flags = 0; + + for (i = 0; i < info->frameFlagsBytes; i++) + flags |= buffer[ posn + i ] << ((info->frameFlagsBytes - 1 - i) * 8); + + attr.SetFlags(flags); + + posn += info->frameFlagsBytes; + + return posn; +} + +luint ID3_FrameHeader::Render(uchar *buffer) +{ + luint bytesUsed = 0; + ID3_FrameDef *frameDef = NULL; + char *textID = NULL; + luint i; + + if (frameDef = ID3_FindFrameDef(frameID)) + { + if (info->frameIDBytes < strlen (frameDef->longTextID)) + textID = frameDef->shortTextID; + else + textID = frameDef->longTextID; + } + else + ID3_THROW (ID3E_InvalidFrameID); + + memcpy (&buffer[ bytesUsed ], (uchar *) textID, info->frameIDBytes); + bytesUsed += info->frameIDBytes; + + for (i = 0; i < info->frameSizeBytes; i++) + { + if (version==4) // 2.4 uses syncsafe sizes + buffer[ bytesUsed + i ] = (uchar) ((dataSize >> ((info->frameSizeBytes - i - 1) * 7)) & 0x7F); + else + buffer[ bytesUsed + i ] = (uchar) ((dataSize >> ((info->frameSizeBytes - i - 1) * 8)) & 0xFF); + } + + bytesUsed += info->frameSizeBytes; + + for (i = 0; i < info->frameFlagsBytes; i++) + buffer[ bytesUsed + i ] = (uchar) ((flags >> ((info->frameFlagsBytes - i - 1) * 8)) & 0xFF); + + bytesUsed += info->frameFlagsBytes; + + return bytesUsed; +}
\ No newline at end of file |