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 | 画像をバッファに読み込む。一度では全て読み込まれないので注意 |
画像の圧縮についても同様。

