jpeglibの勉強
Adobe GILでもjpeglibが使われていた。自分もこれを使おうと思うので勉強。
テストコード
// jpeg_test.cpp #include <stdio.h> #include <stdlib.h> #include <jpeglib.h> int main(int argc, char **argv) { struct jpeg_decompress_struct cinfo1; struct jpeg_error_mgr jerr; cinfo1.err = jpeg_std_error(&jerr); // 画像の展開 jpeg_create_decompress(&cinfo1); FILE *infile = fopen(argv[1], "rb"); jpeg_stdio_src(&cinfo1, infile); jpeg_read_header(&cinfo1, TRUE); jpeg_start_decompress(&cinfo1); int width = cinfo1.output_width; int height = cinfo1.output_height; JSAMPARRAY img = (JSAMPARRAY)malloc(sizeof(JSAMPROW)*height); for(int i = 0; i < height; ++i){ img[i] = (JSAMPROW)calloc(sizeof(JSAMPLE), 3 * width); } while(cinfo1.output_scanline < cinfo1.output_height){ jpeg_read_scanlines(&cinfo1, img + cinfo1.output_scanline, cinfo1.output_height - cinfo1.output_scanline); } jpeg_finish_decompress(&cinfo1); jpeg_destroy_decompress(&cinfo1); fclose(infile); // とりあえずRGB値を取り替えるだけ for(int i = 0; i < height; ++i){ for(int j = 0; j < width; ++j){ JSAMPLE tmp = img[i][j * 3 + 0]; img[i][j * 3 + 0] = img[i][j * 3 + 1]; img[i][j * 3 + 1] = img[i][j * 3 + 2]; img[i][j * 3 + 2] = tmp; } } // 画像の圧縮 struct jpeg_compress_struct cinfo2; cinfo2.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo2); FILE *outfile = fopen(argv[2], "wb"); jpeg_stdio_dest(&cinfo2, outfile); cinfo2.image_width = width; cinfo2.image_height = height; cinfo2.input_components = 3; cinfo2.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo2); jpeg_start_compress(&cinfo2, TRUE); jpeg_write_scanlines(&cinfo2, img, width); jpeg_finish_compress(&cinfo2); jpeg_destroy_compress(&cinfo2); fclose(outfile); for(int i = 0; i < height; ++i){ free(img[i]); } free(img); return 0; }
とりあえず、RGB値を取り換える処理だけをしている。
%g++ -o jpeg_test jpeg_test.cpp -ljpeg %./jpeg_test input.jpg output.jpg
簡単に説明。
JSAMPLEがRGBのそれぞれの値を表していて3つで一つの画素を表す。(LCS_RGBの場合)
JSAMPARRAYはJSAMPROW(JSAMPLEの配列)の配列。
画像展開後のデータをこのバッファに読み込む。
jpeg_decompress_struct | 画像の展開に関する情報 |
jpeg_error_mgr | エラー処理に関するもの |
jpeg_create_decompress/jpeg_destroy_decompress | 必ず対で。初期化/後始末を行う。 |
jpeg_stdio_src | 画像の読み込み先を指定。stdio streamを使用する。 |
jpeg_read_header | 画像のサイズなどのヘッダ情報を読み込む。 |
jpeg_start_decompress/jpeg_finish_decompress | 展開を開始/終了。 |
jpeg_read_scanlines | 画像をバッファに読み込む。一度では全て読み込まれないので注意 |
画像の圧縮についても同様。