Home > プログラミング > libpng

libpng

どうせ画像を回転させるなら 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
★下記に2つの英単語をスペースで区切って入力してください

Home > プログラミング > libpng

Search
Feeds

Page Top