どうせ画像を回転させるなら png でも読み込ませようと考えて, libpng を使ってみることに.面倒なのでフルカラー png のみをひとつの大きな位置次元配列に展開する関数を作った.
// full color PNG を一列のバッファにして返す
int readPNG(const char *fname, unsigned char**buf, int *iHeight, int *iWidth, bool *bAlpha, int *iRowbytes)
{
const int number = 8;
unsigned char header[number];
FILE *fp = fopen(fname, "rb");
if (!fp) return -1;
fread(header, 1, number, fp);
bool is_png = !png_sig_cmp(header, 0, number); // Signature check
if (!is_png) return -1;
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) return -1;
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr){
png_destroy_read_struct(&png_ptr,
(png_infopp)NULL, (png_infopp)NULL);
return -1;
}
png_infop end_info = png_create_info_struct(png_ptr);
if (!end_info){
png_destroy_read_struct(&png_ptr, &info_ptr,
(png_infopp)NULL);
return -1;
}
png_init_io(png_ptr, fp); // init
png_set_sig_bytes(png_ptr, number); // inform libpng read-bytes
png_read_info(png_ptr, info_ptr); // get info
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
int compression_type, filter_method;
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method);
int channels = png_get_channels(png_ptr, info_ptr);
int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
switch(color_type){
case PNG_COLOR_TYPE_RGB: // RGB only
case PNG_COLOR_TYPE_RGB_ALPHA:
break;
case PNG_COLOR_TYPE_GRAY:
case PNG_COLOR_TYPE_PALETTE:
case PNG_COLOR_MASK_PALETTE:
// case PNG_COLOR_MASK_COLOR:
case PNG_COLOR_MASK_ALPHA:
return -1;
}
if(bit_depth!=8) return -1;
*buf = new unsigned char[rowbytes*height];
unsigned char **rows = new unsigned char*[height];
for(int i = 0; i < height; i++){
rows[i] = &(*buf)[i*rowbytes];
}
png_read_image(png_ptr, rows);
png_read_end(png_ptr, end_info);
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
*iHeight = height;
*iWidth = width;
*bAlpha = color_type == PNG_COLOR_TYPE_RGB_ALPHA;
*iRowbytes = rowbytes;
delete rows;
return 0;
}
コンパイルは png.h をインクルードしてから -lpng12 -lz -lm をつければいいはず.
ちなみに,Cygwin には mingw の libpng がないのでソースから作る必要があるっぽい.cygwin の libpng を使ったらプログラムが止まらなくなったりしたし.作るのは普通どおりにただ cygwin 使うなと指定してやれば良いみたい.
CFLAGS="-Wall -O3 -funroll-loops -mno-cygwin" ./configure --libdir=/lib/mingw/ --includedir=/usr/include/mingw/ make make install
- Newer: ことはじめ