掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
GIF画像サイズを取得する方法は? (ID:51832)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
> //Global Color Table情報取得 > int used ; > unsigned char red,blue, green; > if (Ncolos > 0) GIFColorTable(GIFStream, used, &red, &green, &blue); 配列、又は malloc() 等を使用して必要なサイズ分のメモリを確保しないと… > int var_long, iImageNum = 0; > int leftposition, topposition, imagew, imageh, bsize; > while (_read(GIFStream, &var_long, 1) == 1) var_long = 0xFFFFFFFF; _read(GIFStream, &var_long, 1) と4バイトの変数に_read()で1バイトデータを読込む、なんてすると var_longの中身は 0xFFFFFF** と上位3バイトには以前の値が残り正確な値が取得できません。 (まあ、2つ目は私の書いたコードなんで私の間違いですが…) こんなのが重なってエラーが出ているのでしょう。 とりあえずソース貼らせて貰います。VC6.0 + SP5 Win98 で動作確認済み。 後は仕様書を見ながらで何とかなるでしょう。 ----------------------------------------------- //GIFHeader部分 int GetGIFSize(int GIFStream, int *gsize, int *width, int *height, int *Ncolos) { unsigned char count = 0; unsigned char bitdata, bcindex,ratio; unsigned short var_short; unsigned char s[4], s1[4]; // GIF 認識文字 "GIF" (0x47 0x49 0x46の固定値) if (_read(GIFStream,&s,3) == 3) { if (memcmp(&s, "GIF", 3) == 0) printf("[GIF] GIF file\n"); else exit(1); count += 3; } //ヴァージョンの確認 //("87a"の場合は,0x38 0x37 0x61の固定値 "89a"の場合は,0x38 0x39 0x61の固定値となる。) if (_read(GIFStream,&s1,3) == 3) { if (memcmp(&s1, "87a", 3)== 0) printf("Version GIF file\n"); else if (memcmp(&s1, "89a", 3)== 0) printf("Version GIF file\n"); else exit(1); count += 3; } // GIF画像全体の幅 (0x1234の場合は,0x34 0x12と格納される。) if (_read(GIFStream,&var_short, 2) == 2) { printf(" Width : %ld [pixel]\n", var_short); *width = var_short; count += 2; } // GIF画像全体の高さ (0x1234の場合は,0x34 0x12と格納される。) if (_read(GIFStream,&var_short, 2) == 2) { printf(" Height : %ld [pixel]\n", var_short); *height = var_short; count += 2; } //bitdata読み込み if (_read(GIFStream,&bitdata, 1) == 1) { count +=1; //bitdataの最上位ビットをチェックしてGlobal Color Table が存在するなら //色数を得る。存在しない場合は、0を設定。 *Ncolos = ((bitdata & 0x80) ? (2 << (bitdata & 0x07)): 0); } //背景色index if (_read(GIFStream,&bcindex, 1) == 1) { unsigned char bc = bcindex; printf(" \n"); count += 1; } //ピクセルの縦横比 if (_read(GIFStream,&ratio, 1) == 1) { unsigned char rt = ratio; printf(" \n"); count += 1; } return count; } //Global Color Table Flag が存在する場合のTableの情報 int GIFColorTable(int GIFStream, long used, unsigned char *red, unsigned char *green, unsigned char *blue) { //ビットの並びはRGB //red,blue,greenはメモリ確保済みとして、 for(int i = 0; i < used; i++) { _read(GIFStream, &red[i], 1); _read(GIFStream, &green[i], 1); _read(GIFStream, &blue[i], 1); } return used*3; } /*------------------------------------------------------------------*/ /* Image Block */ /*------------------------------------------------------------------*/ int ImageBlock(int GIFStream,int *leftposition, int *topposition, int *imagew, int *imageh, int *bsize) { int count = 0; unsigned short var_short; //Image Left Position (0x1234の場合は,0x34 0x12と格納される。) if (_read(GIFStream,&var_short, 2) == 2) { *leftposition = var_short; count += 2; } // Image TOP Position (0x1234の場合は,0x34 0x12と格納される。) if (_read(GIFStream,&var_short, 2) == 2) { *topposition = var_short; count += 2; } // ImageBlockの幅 if (_read(GIFStream,&var_short, 2) == 2) { printf(" ImWidth : %d [pixel]\n", var_short); *imagew = var_short; count += 2; } // ImageBlockの高さ if (_read(GIFStream,&var_short, 2) == 2) { printf(" ImHeight : %d [pixel]\n", var_short); *imageh = var_short; count += 2; } //Local Color Table Flag, Interlace Flag //Sort Flag, Reserved, Size of Local Color Table unsigned char var_byte; if (_read(GIFStream,&var_byte, 1) == 1) count += 1; if ((var_byte & 0x80)) { //Local Color Tableが存在したが面倒なので無視する _lseek(GIFStream, (2 << (var_byte & 0x07)), SEEK_CUR); count += (2 << (var_byte & 0x07)); } //LZW Mimimum Code Side(LZWコードの最小ビット数) if (_read(GIFStream,&var_byte, 1) == 1) { count += 1; } //Block Size(イメージサイズ) *bsize = 0; while (_read(GIFStream, &var_byte, 1) == 1) { if(var_byte == 0) break; //データ副ブロックのブロック寸法領域のサイズを足す。 *bsize += (1 + var_byte); //次のデータ副ブロック開始位置へ _lseek(GIFStream, var_byte, SEEK_CUR); } return count + *bsize; } int main() { int GIFStream = _open("F:\\siisiselogo.gif", _O_RDONLY|_O_BINARY); //Logical Screen Descripter 情報取得 int gsize, width, height, Ncolos; GetGIFSize(GIFStream, &gsize, &width, &height, &Ncolos); //Global Color Table情報取得 unsigned char *red, *blue, *green; red = blue = green = NULL; if (Ncolos > 0) { red = (unsigned char*)malloc(Ncolos); blue = (unsigned char*)malloc(Ncolos); green = (unsigned char*)malloc(Ncolos); GIFColorTable(GIFStream, Ncolos, red, green, blue); } //ブロックを解析 unsigned char var_byte; int iImageNum = 0; int leftposition, topposition, imagew, imageh, bsize; while (_read(GIFStream, &var_byte, 1) == 1) { switch (var_byte){ case 0x2C : //イメージ記述ブロック ImageBlock(GIFStream,&leftposition, &topposition, &imagew, &imageh, &bsize); iImageNum++; break; case 0x3B ://ストリーム終了 goto End; case 0x21 : //拡張ブロック //ラベル領域を飛ばす!! _lseek(GIFStream, 1, SEEK_CUR); default : while (_read(GIFStream, &var_byte, 1) == 1){ if (var_byte == 0) break; //次のデータ副ブロックへ _lseek(GIFStream, var_byte, SEEK_CUR); } break; } } End: //後処理 if (red != NULL) free(red); if (green != NULL) free(green); if (blue != NULL) free(blue); _close(GIFStream); printf("%d枚の画像が格納されています。\n",iImageNum); return 0; }
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2020 Takeshi Okamoto All Rights Reserved.