123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- // 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 ([email protected]). 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;
- }
|