0

私は現在、独自のpngリーダーの作成に取り組んでおり、個々のチャンクの読み取りに取り組んでおり、最初の2つのチャンクを正しく読み取っているように見えますが、IDATチャンクになるととんでもないサイズになります.

bool LoadImage(char * path, Image * target)
{
std::ifstream file;

file.open("Lenna.png", std::ios::in | std::ios::binary);
if(!file.is_open())
    return -false;

std::cout << "Opened file : Lenna.png" <<  std::endl;
struct stat filestatus;
if (stat("Lenna.png", &filestatus) != 0)
    return false;

unsigned int fileSize = filestatus.st_size;
unsigned int bytesRead = 8;
file.seekg(8, std::ios::beg);

while(bytesRead < fileSize)
{
    //Read the length, type, then the data and at last the crc(Cyclic redundancy crap, whatever that may be)
    char length [4];
    file.read(length, 4);
    //Reverse the 4 bytes due to network type writing.
    unsigned int dataLength = (length[0] << 24) | (length[1] << 16) | (length[2] << 8) | length[3];
    char type [4];
    file.read(type, 4);
    char * data = new char[dataLength];
    file.read(data, dataLength);
    char crc [4];
    file.read(crc, 4);
    bytesRead += 12 + dataLength;
}

return true;
}

デバッガーを使用して、最初の 2 つのチャンクを次のように読み取ります。

タイプ : IDHR
長さ : 13 バイト

タイプ : sRGB
長さ : 1 バイト

タイプ: IDAT
長さ: 4294967201 バイト

これは約 2.3 GB のデータで、png は 462 kb です。なぜうまくいかないのですか?

ソース画像 : http://i.cubeupload.com/sCHXFV.png

4

2 に答える 2

2

問題は、バイト順の反転と左シフトにあります。シフト演算の結果の符号は、シフトされる値の符号と同じです。そのため、符号付きをシフトすると、char予想とは異なる動作になります。

修正するには、length配列のタイプを に変更しunsigned charます。

于 2012-05-13T15:19:03.923 に答える
1

長さを宣言する必要があるため、バイト値 >= 128 の符号拡張はbyteunsigned charではありません。これが 0xffffffa1 になった方法です。負の値を or-ed しました。

于 2012-05-13T15:27:22.527 に答える