2017-03-29 4 views
0

PNG画像ファイルのIDATブロックからデータを膨らませようとするのに何らかの問題がありました。これまでのところ、私はIHDRブロックを読み取り、正しいデータを返すことができました。しかし、ファイルの生のRGB値を取得するために圧縮解除しようとすると、他のものから0を取得している間に1つの画像にしか成功することができませんでした。これはzlibから膨らませるために使用したコードです。以上のことから PNGからの膨張データは、特定の画像でのみ成功しますか?

unsigned char temp[4]; 
fread(&temp,1,4,pf); 
unsigned int ihdr_size = convert_endian(temp); 

unsigned char blk[ihdr_size + 8]; 
fread(blk,1,ihdr_size + 8,pf); 

if (check_ihdr(blk) == -1){ 
    fclose(pf); 
    return -1; 
} 
this->width = convert_endian(blk+4); 
this->height = convert_endian(blk+8); 
long area = this->width*this->height*3 +this->height+1; 
printf("%ld x %ld\n",this->width, this->height); 
printf("Bit depth: %1x\n", (unsigned char)blk[12]); 
printf("Color type: %1x\n", (unsigned char)blk[13]); 

while(fread(&temp,1,4,pf) > 0){ 
    unsigned int bsize = convert_endian(temp); 
    unsigned char chunk[bsize+8] = {0}; 
    fread(chunk,1, bsize+8,pf); //8 extra for block name and CRC 
    if (chunk_type(chunk)== 1){ //IDAT 
     this->picture = new unsigned char[area]; 

     z_stream infstream; 
     infstream.zalloc = Z_NULL; 
     infstream.zfree = Z_NULL; 
     infstream.opaque = Z_NULL; 
     infstream.avail_in = bsize; // size of input 
     infstream.next_in = chunk+4; // input char array (without chunk name) 
     infstream.avail_out = area; // size of output 
     infstream.next_out = this->picture; // output char array 

     inflateInit(&infstream); 
     if (int er = inflate(&infstream, Z_NO_FLUSH) != Z_STREAM_END){ 
      printf("Error!\n"); 
     } 
     inflateEnd(&infstream); 
     printf("OUT:%d %ld\n", infstream.avail_out, area); 
     for (long i = 0; i < 1000; i+=4){ 
      printf("%x %x %x\n",this->picture[i], this->picture[i+1], this->picture[i+2]); 
     } 


    } 
    printf("B:%x\n",bsize); 
    printf("%c%c%c%c\n",chunk[0], chunk[1], chunk[2], chunk[3]); 
} 

、私はこのイメージ image2 で試してみました(同じ画像が、トリミング)する場合、 image#1 しかし、この画像でRGB値を得ることに成功していた、プログラムはのみ返すことができましたRGBデータの最初の3バイト(残りはゼロです)。このコードで正しく実装されていませんでしたか?

答えて

1

結果が正しく解釈されていません。 +this->heightの理由は、画像の各行の前にフィルタバイトが付いているためです。 「成功」した画像では、フィルタバイトはすべてゼロであり、フィルタリングがないことを示します。つまり、ピクセル値は圧縮解除されたデータに直接表示されます。その場合でも、フィルタのバイトを見越して移動していないため、ピクセル値の不正なバイトが表示されます。 「成功」しなかった、最初の行はフィルタ1を使用し、後続のラインがフィルタ2を使用してフィルタ1は、画素値に先行する最初にそれらから減算した後ことを示す、サブフィルタされた画像について

前のピクセル値2は、Upフィルタを示します。ここで、最初の行の後の各ピクセル値は、その位置の前の行のピクセル値から減算されます。そのため、最初の値の後のほとんどの値(ではなく、すべて)がゼロになります。結果をより注意深く見てください。

関連する問題