giflib の使い方 (2)
ファイルでなくデータ配列で GIF データを渡したいと思ってた所に、
便利な関数を発見。(3.1.0 で追加された)
/******************************************************************* * GifFileType constructor with user supplied input function (TVT) ******************************************************************/ GifFileType * DGifOpen(void *userData, InputFunc readFunc) {
入力ファンクションを自分で作って渡せます。
DGifOpen の使い方
giflib/gba/giftest.c のコードでは、データ配列を渡すのに、
int readFunc(GifFileType* GifFile, GifByteType* buf, int count) { char* ptr = GifFile->UserData; memcpy(buf, ptr, count); GifFile->UserData = ptr + count; return count; }
の関数を用意して、
u8 *userData; /* u8 = unsigned char */
GifFileType * GifFile = DGifOpen(userData, readFunc);
のように使ってました。
ただ、これだと用意したデータ配列の長さに関係なく、
GIF 的にキリのよい所までデータを参照するはずなので、
このまま真似すると、buffer overflow しそうです。
libpng だと png_get_io_ptr があって、
任意の構造体でデータを渡せるようになっています。
giflib では (VoidPtr)UserData がそれに相当するようなので、
この仕組みを使って境界チェックさせる事にします。
さっそく実装
DGifOpen & DGifSlurp でデータを取り込んでから、
GifFileType 構造体のメンバー(の幾つか)を表示。
% gcc -W -Wall gif_dump.c -lgif % ./a.out aria.gif gif_filename=aria.gif gif_buff.data_len=24207 (SWidth, SHeight)=(200, 150) SColorResolution=8 SBackGroundColor=0 ColorMapObject: ColorCount=256 BitsPerPixel=8 Colors= (00,00,00) (ff,ff,ff) (96,53,58) (29,1b,1c) (e6,b0, b8) (b2,69,76) (37,26,29) (d6,96,a1) image_count=1 # image no=0 (Left, Top) = (0, 0) (Width, Height) = (200, 150) Interlace=0 No ColorMap
それっぽく dump 出来ました。