2009年03月29日

libjpegで画像を読み込む

djpegでいいと思うのだけれどlibjpegを使ってみた。
癖はいろんなソフトでも使っているのでわかりやすいが
使用法はクロスプラットフォームなソースのためわかりにくい。
今回は基本中の基本であるファイル読み込みをやってみた。
SDLサーフィスに直接読み込む手法は若干トリッキーかもしれない。

ヘッダーは

#include <jpeglib.h>


コンパイルオプションは

-ljpeg


libjpeg.docに使っている変数名+αを宣言

struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
char *filename,*line;
FILE *infile;

char *bits,*filename;
int k;


あとW,H,i,j等を使いまわす。

初期化

filename=IMGNAME;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
W = cinfo.output_width;
H = cinfo.output_height;
img1=SDL_CreateRGBSurface(SDL_SWSURFACE,W,H
, 32, rmask, gmask, bmask,amask);//RGBA


jpeg_decompress_structがインスタンスということで
上記処理はテンプレ化されている。
メモリーからの読み込みの場合やエラー処理などコールバックを登録するようだ。
ヘッダーを読み込んだ段階でサイズが分かる。

読み込み処理

bits=img1->pixels;
k=W<<2;
puts("copystart2");
for(i=0; i < H; i++)
{
jpeg_read_scanlines(&cinfo, &bits, 1);
for(j=W-1; j >=0; j--)
{
pix=*(int*)(bits+3*j)|amask;
*(int*)(bits+4*j)=pix;
}
bits+=k;
}

Cはポインタ型もintにすると4byte移動するので*char型を使っている。
libjpegで1ライン読み込み後ろから4byteに移動している。
移動は32bitでやっているので一見効率が良いがそもそも無駄な作業。

また3byte型のメモリー空間に読むならばいらない。

終了処理

jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(infile);


djpeg使うのとあんまり変わらない。
でもこれを関数化したらSDL_Imageがいらないとも言える。
ハフマン展開したテーブルが欲しいとかいいだすと
結局libjpegも使わないはめになりそうだが実際直接組んでみると
案外とコード量は短いのでメモリーストリームやセーブに着手する事にする。


ラベル:画像 SDL
posted by Xo_ox at 01:18| Comment(0) | C | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。