Exemplo n.º 1
0
luint ID3_Tag::Render( uchar *buffer )
{
	luint	bytesUsed	= 0;

	if	( buffer )
	{
		ID3_Elem		*cur	= frameList;
		ID3_TagHeader	header;

		SetVersion ( ID3_TAGVERSION, ID3_TAGREVISION );

		header.SetVersion ( m_nVersion, m_nRevision );
		bytesUsed += header.Size();

		// set up the encryption and grouping IDs

		// ...

		while( cur )
		{
			// PL
			// Check that frame has a valid FrameID
			if( ( cur->frame->GetID() <= 0 ) || (cur->frame->GetID() > ID3FID_CRYPTOREG ))
			{
//				TRACE( "Invalide FrameID\n" );
				cur = cur->next;
				continue;
			}
			// End PL

			if	( cur->frame )
			{
				cur->frame->compression = m_bCompression;
				cur->frame->SetVersion ( m_nVersion, m_nRevision );
				bytesUsed += cur->frame->Render ( &buffer[ bytesUsed ] );
			}

			cur = cur->next;
		}

		if	( m_bSyncOn )
		{
			uchar	*tempz;
			luint	newTagSize;

			newTagSize = GetUnSyncSize ( &buffer[ header.Size() ], bytesUsed - header.Size() );

			if	( newTagSize > 0 && ( newTagSize + header.Size() ) > bytesUsed )
			{
#ifdef _DEBUG
//				ASSERT( newTagSize < MAX_ALLOC ); // PL
#endif
				if	( tempz = new uchar[ newTagSize ] )
				{
					UnSync ( tempz, newTagSize, &buffer[ header.Size() ], bytesUsed - header.Size() );
					header.SetFlags ( ID3HF_UNSYNC );

					memcpy ( &buffer[ header.Size() ], tempz, newTagSize );
					bytesUsed = newTagSize + header.Size();
					delete[] tempz;
				}
				else
					ID3_THROW ( ID3E_NoMemory );
			}
		}

		// zero the remainder of the buffer so that our
		// padding bytes are zero
		for	( luint i = 0; i < PaddingSize ( bytesUsed ); i++ )
			buffer[ bytesUsed + i ] = 0;

		bytesUsed += PaddingSize ( bytesUsed );

		header.SetDataSize ( bytesUsed - header.Size() );
		header.Render ( buffer );
	}
	else
		ID3_THROW ( ID3E_NoBuffer );

	// set the flag which says that the tag hasn't changed
	m_bHasChanged = false;

	return bytesUsed;
}
Exemplo n.º 2
0
void ID3v2_Parse(const void* Ptr,size_t Len,pin* Pin,filepos_t Offset)
{
	const uint8_t* Data = (const uint8_t*)Ptr;

	
	size_t Size = ID3v2_Query(Ptr,Len);

	uint8_t* Data_org=(const uint8_t*)Ptr;
	Data_org+=Size;

	


	
//	RETAILMSG(1, (TEXT(" ^^^^11111111111111111111^^^^^^^^ID3v2_Parse  = %x , %x, %x  \r\n"), Size,&Size,Data));


	if (Size>0 && Pin)
	{
		int HeadFlag = Data[5];
		int Ver = Data[3];
		if (Ver >= 2 && Ver <= 4 && Size<=Len)
		{
			uint8_t* Tmp = NULL;

			// jump after header
			Data += 10;
			Size -= 10;
			
			if (Ver<4 && (HeadFlag & FLAG_UNSYNC))
			{
				// undo unsync coding
				Tmp = malloc(Size);
				if (Tmp)
				{
					Size = UnSync(Tmp,Data,Size);
					Data = Tmp;
				}
				else
					return;
			}

			if ((HeadFlag & FLAG_EXTENDED) && Size>=4)
			{
				// skip extended header
				size_t n = (Ver>=4)?Read7Bit(Data,4):Read8Bit(Data,4);
				Data += 4+n;
				Size -= 4+n;
			}

			while (Data_org > Data )
			{
				// parse frame
				uint8_t* Tmp = NULL;
				uint8_t* Tmp2 = NULL;
				const uint8_t* p;

				bool_t NeedDecompress = 0;
				bool_t NeedUnSync = 0;
				int Id = 0;
				int Len = 0;
				int Len2 = 0;
				int Flag = 0;
				const int* Info;

			

				if( Size <= 0 ||  Data[0]==0)
					break;

				switch (Ver)
				{
				case 2:
				    if (Size >= 6)
					{
						Id = FOURCC(Data[0],Data[1],Data[2],' ');
						Len = Read8Bit(Data+3,3);
						Data += 6;
						Size -= 6;
					}
					break;
				case 3:
				    if (Size >= 10)
					{
						Id = FOURCC(Data[0],Data[1],Data[2],Data[3]);
						Len = Read8Bit(Data+4,4);
						Flag = Read8Bit(Data+8,2);
						Data += 10;
						Size -= 10;

						if (Flag & FLAG3_UNKNOWN)
							Id = 0;

						if ((Flag & FLAG3_COMPRESSION) && Size>=4)
						{
							NeedDecompress = 1;
							Len2 = Read8Bit(Data,4);
							Data += 4;
							Size -= 4;
						}

						if ((Flag & FLAG3_GROUPID) && Size>=1)
						{
							Data++;
							Size--;
						}
					}
					break;
				case 4:
				    if (Size >= 10)
					{
						Id = FOURCC(Data[0],Data[1],Data[2],Data[3]);
						Len = Read8Bit(Data+4,4);
						Flag = Read8Bit(Data+8,2);
						Data += 10;
						Size -= 10;

						if (Flag & FLAG4_UNKNOWN)
							Id = 0;
						if ((Flag & FLAG4_GROUPID) && Size>=1)
						{
							Data++;
							Size--;
						}
						if ((Flag & FLAG4_DATALENGTH) && Size>=4)
						{
							Len2 = Read8Bit(Data,4);
							Data += 4;
							Size -= 4;
						}
						if (Flag & FLAG4_COMPRESSION)
							NeedDecompress = 1;

						if (Flag & FLAG4_UNSYNC)
							NeedUnSync = 1;
					}
					break;
				}

				p = Data;
				Data += Len;
				Size -= Len;

				if (Id && Size>=0)
					for (Info=FrameInfo;Info[0];Info+=3)
						if (Info[0]==Id)
						{
							int n;
							tchar_t Value[512];

							if (NeedUnSync)
							{
								Tmp = malloc(Len);
								if (!Tmp)
									break;
								Len = UnSync(Tmp,p,Len);
								p = Tmp;
							}

							if (NeedDecompress && Len2>0)
							{
								unsigned long n = Len2;
								Tmp2 = malloc(Len2);
								if (!Tmp2 || uncompress(Tmp2,&n,p,Len)!=Z_OK)
									break;
								Len = n;
								p = Tmp2;
							}

							switch (Info[2])
							{
							case FIELD_STRING:
								if (Len>1)
								{
									ReadStrEncode(p+1,Len-1,p[0],Value,TSIZEOF(Value));
									AddFieldStr(Pin,Info[1],Value);
								}
								break;
							case FIELD_COMMENT:
								if (Len>5)
									for (n=4;n<Len;++n)
										if (p[n]==0)
										{
											ReadStrEncode(p+n+1,Len-n-1,p[0],Value,TSIZEOF(Value));
											AddFieldStr(Pin,Info[1],Value);
											break;
										}
								break;
							case FIELD_APIC:
								if (Len>5)
								{
									int Encode = *(p++);
									--Len;

									if (Ver==2)
									{
										tcscpy_s(Value,TSIZEOF(Value),T("image/"));
										GetAsciiToken(Value+tcslen(Value),TSIZEOF(Value)-tcslen(Value),(const char*)p,3);
										Len -= 3;
										p += 3;

										if (tcsicmp(Value,T("image/jpg"))==0)
											tcscpy_s(Value,TSIZEOF(Value),T("image/jpeg"));
									}
									else
									{
										n = ReadStrEncode(p,Len,Encode,Value,TSIZEOF(Value));
										Len -= n;
										p += n;
									}
								
									++p;
									--Len;

									n = ReadStrEncode(p,Len,Encode,NULL,0); // skip description
									Len -= n;
									p += n;

									AddFieldAttachment(Pin,COMMENT_COVER,(p-(const uint8_t*)Ptr)+Offset,Len,Value);
								}
								break;
							}
							break;
						}

				free(Tmp);
				free(Tmp2);
			}

			free(Tmp);
		}
	}
}