C#/.NET 中 APIC 的 ID3v2 标签问题
ID3v2 tag issue with APIC in C#/.NET
我正在编写自己的 ID3v2 标签 reader,但 APIC 标签似乎有问题。每当它读取它时,它会说它是 2,038,335 字节大,而实际上它是 511,281 字节大。我不知道为什么,我觉得这与这条线有关:
int size = ( data[ i ] << 24 ) | ( data[ ++i ] << 16 ) | ( data[ ++i ] << 8 ) | ( data[ ++i ] << 0 ) - 1;
但是这条线适用于我测试过的所有其他标签。也可能是我遗漏了 ID3v2 标签标准中的某些内容或完全不同的内容。这是一段代码,用于存储图像供以后使用:
List<byte> temp = new List<byte>();
for( int i = 1; i < frame.Length; i++ ) {
if(frame[i] == 0x00 ) {
break;
} else {
temp.Add( frame[ i ] );
}
}
string strVer = Encoding.Default.GetString( temp.ToArray() );
if ( strVer.StartsWith( "image/" ) ) {
List<byte> image = new List<byte>();
for(int i = temp.Count + 1 + frame[ temp.Count + 2 ]; i < frame.Length; i++ ) {
image.Add( frame[ i ] );
}
tagInfo[ tag ] = image.ToArray();
}
tagInfo[ tag ] = frame;
我用于测试的文件是 "Resistence by Aero Chord",带有 2000x2000 像素的图像。
这是生成相同大小的脚本:
using System;
using System.IO;
using System.Text;
using System.Threading;
class Program {
static void Main( string[] args ) {
int tagSize = 0;
byte[] fileData = byte[] fileData = { 0x41, 0x50, 0x49, 0x43, 0x00, 0x1f, 0x1a, 0x3f };
for ( int i = 0; i < fileData.Length - 3; i++ ) {
string tag = Encoding.Default.GetString( new byte[] { fileData[ i ], fileData[ i + 1 ], fileData[ i + 2 ], fileData[ i + 3 ] } );
if ( tag.Equals( "APIC" ) ) {
i += 4;
tagSize = ( fileData[ i ] << 24 ) | ( fileData[ ++i ] << 16 ) | ( fileData[ ++i ] << 8 ) | ( fileData[ ++i ] << 0 ) - 1;
break;
}
}
Console.Write( $"Tag stated size: {tagSize} bytes." );
Thread.Sleep( 60000 );
}
}
预期:511,281 字节
结果:2,038,334 字节
使用文件中嵌入的图像和文件中的 APIC 标签。
来自standard:
The ID3 tag size is encoded with four bytes where the first bit (bit 7) is set to zero in every byte, making a total of 28 bits. The zeroed bits are ignored, so a 257 bytes long tag is represented as [=13=] 00 02 01
您的字节值大小为八位,但您需要最后七位,丢弃第一位,因为第一位的值始终为零。
所以:
tagSize = (tagSize[i] << 21) | (tagSize[++i] << 14) | (tagSize[++i] << 7) | (tagSize[++i] << 0);
对于 0x00, 0x1f, 0x1a, 0x3f
的输入,这将产生 511295
的大小。
我正在编写自己的 ID3v2 标签 reader,但 APIC 标签似乎有问题。每当它读取它时,它会说它是 2,038,335 字节大,而实际上它是 511,281 字节大。我不知道为什么,我觉得这与这条线有关:
int size = ( data[ i ] << 24 ) | ( data[ ++i ] << 16 ) | ( data[ ++i ] << 8 ) | ( data[ ++i ] << 0 ) - 1;
但是这条线适用于我测试过的所有其他标签。也可能是我遗漏了 ID3v2 标签标准中的某些内容或完全不同的内容。这是一段代码,用于存储图像供以后使用:
List<byte> temp = new List<byte>();
for( int i = 1; i < frame.Length; i++ ) {
if(frame[i] == 0x00 ) {
break;
} else {
temp.Add( frame[ i ] );
}
}
string strVer = Encoding.Default.GetString( temp.ToArray() );
if ( strVer.StartsWith( "image/" ) ) {
List<byte> image = new List<byte>();
for(int i = temp.Count + 1 + frame[ temp.Count + 2 ]; i < frame.Length; i++ ) {
image.Add( frame[ i ] );
}
tagInfo[ tag ] = image.ToArray();
}
tagInfo[ tag ] = frame;
我用于测试的文件是 "Resistence by Aero Chord",带有 2000x2000 像素的图像。
这是生成相同大小的脚本:
using System;
using System.IO;
using System.Text;
using System.Threading;
class Program {
static void Main( string[] args ) {
int tagSize = 0;
byte[] fileData = byte[] fileData = { 0x41, 0x50, 0x49, 0x43, 0x00, 0x1f, 0x1a, 0x3f };
for ( int i = 0; i < fileData.Length - 3; i++ ) {
string tag = Encoding.Default.GetString( new byte[] { fileData[ i ], fileData[ i + 1 ], fileData[ i + 2 ], fileData[ i + 3 ] } );
if ( tag.Equals( "APIC" ) ) {
i += 4;
tagSize = ( fileData[ i ] << 24 ) | ( fileData[ ++i ] << 16 ) | ( fileData[ ++i ] << 8 ) | ( fileData[ ++i ] << 0 ) - 1;
break;
}
}
Console.Write( $"Tag stated size: {tagSize} bytes." );
Thread.Sleep( 60000 );
}
}
预期:511,281 字节
结果:2,038,334 字节
使用文件中嵌入的图像和文件中的 APIC 标签。
来自standard:
The ID3 tag size is encoded with four bytes where the first bit (bit 7) is set to zero in every byte, making a total of 28 bits. The zeroed bits are ignored, so a 257 bytes long tag is represented as [=13=] 00 02 01
您的字节值大小为八位,但您需要最后七位,丢弃第一位,因为第一位的值始终为零。
所以:
tagSize = (tagSize[i] << 21) | (tagSize[++i] << 14) | (tagSize[++i] << 7) | (tagSize[++i] << 0);
对于 0x00, 0x1f, 0x1a, 0x3f
的输入,这将产生 511295
的大小。