ndsでのjpeg表示に再挑戦(8)
jpegのデコードはできるようになったのですが、元々、コマンドライン上で使うプログラムとして作られているので、エラーが起きたときに、exit()してコマンドプロンプトに戻る仕様に作られており、呼び出したところにエラーと共に戻ってこない問題があります。
jerror.cを修正してエラー時に戻るようにする
jpegの展開プログラムはとてもよくできているので、エラーが発生してexit()するときには、必ずファイナライズ処理をして、error_exit()関数に飛んでくるように作られています。そこで、このerror_exit()の部分にエラー発生時に元に戻るプログラムを追記しました。
また、中にはエラーが発生しても、できるだけデコードを行って、error_exit()に戻ってこないで、デコード処理を途中で止めて、jpeg_start_decompress()を抜けてくるものもあります。この場合にも対応できるように、グローバル変数としてDecodeErrorを用意しました。
以下コードの説明です。
グローバル変数を2つ宣言
jmp_buf EnvData; //setjump用 bool DecodeError; //展開エラーフラグ昨日のブログに書いたjpeg2pmm()関数をjpeg2pmmMain()に変更。そして、DecodeError = true;を追加。
// ******************************************** // jpegファイルをpmmファイルに変換します // ******************************************** int jpeg2pmmMain( FILE *inFp, FILE *outFp ) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; djpeg_dest_ptr dest_mgr = NULL; JDIMENSION num_scanlines; DecodeError = true; 以下略 return( DecodeError ); }
そして、エラー時に戻ってくるプログラムです。正確にはエラー時には戻り値1と共にsetjmp()のところに戻ってきます。
// ******************************************** // jpegファイルをpmmファイルに変換します // ******************************************** bool jpeg2pmm( FILE *inFp, FILE *outFp ) { bool ret = true; //try{} if( setjmp( EnvData )==0 ){ ret = jpeg2pmmMain( inFp, outFp ); } //catch{} else{ ret = false; } //finally{} { if( ret==false ){ ShinoUpPrint( SubScreenA, (u8 *)"エラーが起きました", RGB(31,31,31),RGB(0,0,0), 1,RGB(0,0,0) ); } } return ret; }jerror.cの変更箇所です。
#ifdef USE_NDS_ERROR_ROUTINES #include <nds.h> #include <setjmp.h> #include "../tarosa_Shinofont03.h" #include "../tarosa_Graphic20100228.h" //自作のグラフィック extern uint16 *SubScreenA; extern jmp_buf EnvData; //setjump用 extern bool DecodeError; //展開エラーフラグ #endiferror_exit()の処理変更部
METHODDEF(void) error_exit (j_common_ptr cinfo) { /* Always display the message */ (*cinfo->err->output_message) (cinfo); /* Let the memory manager delete any temp files before we die */ jpeg_destroy(cinfo); #ifdef USE_NDS_ERROR_ROUTINES longjmp( EnvData, 1 ); //setjmp()に飛ぶ #else exit(EXIT_FAILURE); #endif }そして、DecodeError = false;の追記ですが、エラー発生時には、必ずエラーメッセージを表示するoutput_message()関数を通るので、ここに追記しました。
ETHODDEF(void) output_message (j_common_ptr cinfo) { char buffer[JMSG_LENGTH_MAX]; /* Create the message */ (*cinfo->err->format_message) (cinfo, buffer); #ifdef USE_WINDOWS_MESSAGEBOX /* Display it in a message dialog box */ MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", MB_OK | MB_ICONERROR); #else #ifdef USE_NDS_ERROR_ROUTINES //エラーメッセージ表示 ShinoUpPrint( SubScreenA, (u8 *)buffer, RGB(31,0,0),RGB(0,0,0), 1,RGB(0,0,0) ); DecodeError = false; #else /* Send it to stderr, adding a newline */ fprintf(stderr, "%s\n", buffer); #endif #endif }
以上で、無事、エラーの時でもエラーを表示して、jpeg2pmm()の呼び出し元に返ってくるようになりました。また、jconfig.hには、#define USE_NDS_ERROR_ROUTINESを追加しています。
今日はこの辺で。
本当にやりたいことリスト
(ブログの終わりにやりたいことを書いておきたいと思います)
- 求職活動・・・このブログで興味を持った人一声かけてください。m(_ _)m
- Androidプログラム
- Web系のプログラム