ふとしたことからpngイメージの中身が気になってしまい、いろいろ調べていたのですが
IHDRチャンクの読み込みができた後、うまくいかずに困っております。
具体的には、
#FFFFFF(まっしろ)の1*1のpngイメージを読み込もうと組んだコードで、
ihdrが終わったあと次のチャンクが正しく読み込めていないのか、iendが正しく認識できていないのです。(終了してくれない)
また、ihdrの中のオフセット0x0008にあたる画像の幅も実際の幅とは違う物でした。(ihdrにもフィルタリングが施されているのでしょうか?)
以上曖昧な知識のまま組んだプログラムなのですが、以下になります。
void LoadPNGtest(const char* filename){
// ・参考文献
// http://www.setsuki.com/hsp/ext/chunk/IDAT.htm
// http://qiita.com/sounisi5011/items/e685ed1501a3cd979a3c
// http://www.cplusplus.com/forum/beginner/96592/
// pngの仕様書
// 以上の情報をふまえてコードをかいてみる。
//
NSLog(@"%s",filename);
FILE*rfp;
rfp=fopen(filename, "rb");
unsigned char siz_[4];
unsigned char dtp_[4];
unsigned char buf[8];
unsigned char crc__[4];
if (rfp == NULL)
{
NSLog(@"Unable to open the image file\n");
goto ENDOFREAD;
}
if (fread (buf, 1, sizeof (buf), rfp) != sizeof(buf))
{
NSLog(@"Unable to read file contents (file may be empty)\n");
goto ENDOFREAD;
}
if (buf[0] == 0x89 &&
buf[1] == 0x50 &&
buf[2] == 0x4E &&
buf[3] == 0x47 &&
buf[4] == 0x0D &&
buf[5] == 0x0A &&
buf[6] == 0x1A &&
buf[7] == 0x0A){
NSLog(@"this is png image.");
}
else{
NSLog(@"error:this is invalid file.");
goto ENDOFREAD;
}
// シグネチャの確認が終わった
// 次にチャンクを読み込んでいく。
// 最初は必ずIHDRチャンクである。
// 最後は必ずIENDチャンクである。
for (int endflag=0; !endflag; ) {
fread (siz_, 1, sizeof (siz_), rfp);// データサイズの取得
fread (dtp_, 1, sizeof (dtp_), rfp);// データタイプの取得
unsigned char* dat = (unsigned char*) malloc(siz_[3]+siz_[2]*16+siz_[1]*16*16+siz_[0]*16*16*16);
fread (dat, 1, sizeof (dat), rfp);// データの取得
fread(crc__, 1, sizeof(crc__), rfp);// crcの取得
// ここから展開(まだかけていない)
if (dtp_[0]==0x49&&dtp_[1]==0x48&&dtp_[2]==0x44&&dtp_[3]==0x52) {// ihdr
NSLog(@"ihdr");
// 画像の幅などを受け取る
NSLog(@"width:%d",dat[3]+dat[2]*16+dat[1]*16*16+dat[0]*16*16*16);
}
else if (dtp_[0]==0x73&&dtp_[1]==0x72&&dtp_[2]==0x68&&dtp_[3]==0x82) {// idat
NSLog(@"idat");
}
else if(dtp_[0]==0x50&&dtp_[1]==0x4C&&dtp_[2]==0x54&&dtp_[3]==0x45){// iplt
NSLog(@"iplt");
}
else if(dtp_[0]==0x49&&dtp_[1]==0x45&&dtp_[2]==0x4E&&dtp_[3]==0x44){// iend49 45 4E 44
NSLog(@"iend");
endflag=1;
}
else{
NSLog(@"%d %d %d %d",dtp_[0],dtp_[1],dtp_[2],dtp_[3]);
}
}
ENDOFREAD:;
fclose(rfp);
}
nslogなどはただのデバッグ用のメッセージを出す関数ですので気にしないでください。
以上、やや見づらいコードで申し訳ないのですがおかしい点等ございましたらご指摘をお願いします。