These pages are written by only Japanese.
|
Namazu for hns による簡易全文検索です。 詳細は 詳細指定/ヘルプをご参照下さい。 |
|||||||||||||||||||||||||||||||||||||||||||||||
libpng にある入出力はpng_read() や png_write() を通して処理されます。 現行では fread() や fwrite() を呼ぶだけです。FILE * は png_struct 内部に記憶され、png_init_io() を経由して初期化されます。 I/O 命令を変更したいなら、png_init_io() を呼ぶ代わりに実行時に png_set_read_fn() と png_set_write_fn() 関数を通してライブラリ指定 のコールバックを設定することができます。という事ですが、
png_set_read_fn(png_structp read_ptr, voidp read_io_ptr, png_rw_ptr read_data_fn) png_set_write_fn(png_structp write_ptr, voidp write_io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn); voidp read_io_ptr = png_get_io_ptr(read_ptr); voidp write_io_ptr = png_get_io_ptr(write_ptr); void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length); void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length); void user_flush_data(png_structp png_ptr);API群を見てもいまいちピンと来ないので、 「png_set_write_fn」で検索したところ以下のページを発見。
png_get_io_ptrによって、png_set_read_fun/png_set_write_funで与えた引数を png_ptrで示されるコンテキストオブジェクトから取得できるので、それを ストリームへのポインタにキャストして仕事をまっとうしているわけです。あー。なるほど。
static void png_default_write_data(png_structp png_ptr,png_bytep data,png_size_ t length) { OSErr err; long llong=length; short refNum=((MyPNGFileRec *)png_ptr->io_ptr)->refNum; err=FSWrite(refNum,&llong,data); if (err!=noErr) { png_error(png_ptr,"Write Error"); } }なるほど。なるほど。
typedef struct my_png_buffer_ { unsigned char *data; unsigned long data_len; unsigned long data_offset; } my_png_buffer; void png_memread_func(png_structp png_ptr, png_bytep buf, png_size_t size){ my_png_buffer *png_buff = (my_png_buffer *)png_get_io_ptr(png_ptr); if (png_buff->data_offset + size <= png_buff->data_len) { memcpy(buf, png_buff->data + png_buff->data_offset, size); png_buff->data_offset += size; } else { png_error(png_ptr,"png_mem_read_func failed"); } } void png_data_read(png_structp png_ptr, my_png_buffer *png_buff) { png_set_read_fn(png_ptr, (png_voidp) png_buff, (png_rw_ptr)png_memread_func); }こんな感じでいいかな。
% ./a.out cyan_3x3.PNG png_filename=cyan_3x3.PNG png_buff.data_len=152 (width, height)=(3,3) bpp=8 color_type=2異常なファイル1 (バッファオーバーフロウ)
% ./a.out cyan_3x3-cut.PNG png_filename=cyan_3x2-cut.PNG png_buff.data_len=91 libpng error: png_mem_read_func failed アボートしましたファイルの後ろを少し削ったファイルを渡したところ、 長さチェックで弾いてくれました。よしっ。
% ./a.out pngtest.png png_filename=pngtest.png png_buff.data_len=8574 libpng error: PNG unsigned integer out of range. アボートしましたふむ。完璧。