/*	
 *	clipjpeg.h
 *
 *	JPEG Decoder
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2009 Naoyuki Sawa
 *
 *	* Fri Feb 06 22:32:46 JST 2009 Naoyuki Sawa
 *	- 作成開始。
 *	* Mon Feb 09 23:11:25 JST 2009 Naoyuki Sawa
 *	- 1st リリース。
 *	* Sun Jun 07 18:04:03 JST 2009 Naoyuki Sawa
 *	- jpeg_decode()に、data_proc引数を追加しました。
 *	* Thu Sep 03 14:03:54 JST 2009 Naoyuki Sawa
 *	- jpeg_decode()に、component引数を追加しました。
 */
#ifndef __CLIP_JPEG_H__
#define __CLIP_JPEG_H__

/****************************************************************************
 *	
 ****************************************************************************/

/* メモリ上のJPEGデータをデコードします。
 * [in]
 *	data_ptr		JPEGデータの先頭アドレス。
 *	component		draw_procで取得するコンポーネント。(0 = Y, 1 = Cb, 2 = Cr)
 *	size_proc		幅・高さ通知コールバック。(NULL可)
 *	draw_proc		ピクセル描画コールバック。(NULL可)
 *	data_proc		データ継続コールバック。(NULL可) {{2009/06/07:追加}}
 *	user_data		任意のユーザーデータ。
 * [out]
 *	戻り値			JPEGデータの終端アドレス。
 *				将来的に、モーションJPEGに対応するための戻り値です。
 *				モーションJPEGについて未調査のため、実際に役立つかどうかわかりません。
 * [note]
 *	* デコード可能なJPEGデータは、Baseline DCT形式(SOF0)のみです。
 *	  Baseline DCT形式の次によく使われる、Progressive DCT形式(SOF2)はデコードできません。
 *	  Progressive DCT形式も含めて、他の形式のJPEGデータを指定した場合の動作は未定義です。
 *	* size_proc、draw_procの両方を指定した場合、必ずsize_proc、draw_procの順にコールバックします。
 *	  従って、size_procで幅・高さに応じた展開バッファを割当て、draw_procで格納することができます。
 *	  または、draw_procで直接、画面に描画を行うこともできます。
 *	* すべてのピクセルに対してdraw_procをコールバックするため、大きな画像のデコードには時間がかかります。
 *	  本関数は、デコードを途中で中止する機能を持っていませんが、setjmp、longjmpを利用して中止が可能です。
 *	  draw_procの中で、pcePadGetDirectなどを使って中止を判断し、longjmpで呼び出し元へ戻ってください。
 *	  本関数は、内部でリソース割当てを行っていませんので、longjmpで中止してもリソース漏れは発生しません。
 * [example]
 *	jmp_buf jb;
 *	int width;
 *	int height;
 *	static void my_size_proc(int w, int h, void* user_data) {
 *		width = w;
 *		height = h;
 *	}
 *	static void my_draw_proc(int x, int y, int c, void* user_data) {
 *		render_point(&render, x, y, (c >> 4) ^ 15);
 *		if(pcePadGetDirect()) {
 *			longjmp(jb, 1);
 *		}
 *	}
 *	void example() {
 *		if(!setjmp(jb)) {
 *			jpeg_decode(JPEG_DATA, 0, my_size_proc, my_draw_proc, NULL, NULL);
 *		}
 *		render_printf(&render, 0, 0, 0, 15, "%d x %d", width, height);
 *	}
 * [追記]
 *	* Sun Jun 07 16:15:05 JST 2009 Naoyuki Sawa
 *	- data_proc引数を追加しました。
 *	  テーブル(DQT,DHT)とイメージ(SOF0,SOS)が分離して格納されたデータの、デコードに対応するためです。
 *	- Flash MXなどで生成した、古いSWFファイルのJPEGデータが、以下のように格納されています。
 *	  - JPEGTables		SOI 〜 DQT  〜 DHT 〜 EOI
 *	    DefineBits		SOI 〜 SOF0 〜 SOS 〜 EOI
 *	  - DefineBitsJPEG2(3)	SOI 〜 DQT  〜 DHT 〜 EOI 〜 SOI 〜 SOF0 〜 SOS 〜 EOI
 *	  新しいFlash(?)で生成したSWFファイルのJPEGデータは、通常のJPEGファイルと同様に格納されています。
 *	  - DefineBitsJPEG2(3)	SOI 〜 DQT  〜 DHT 〜 SOF0 〜 SOS 〜 EOI
 *	- data_procの使い方について、説明します。
 *	  JPEGTablesとDefineBitsのように、テーブルとイメージが分離していることがあらかじめわかっている場合は、
 *	  - jpeg_decode()のdata_ptrにテーブルのアドレスを渡し、
 *	  - 一度目のdata_procコールバックからイメージのアドレスを返してデータ継続し、
 *	  - 二度目のdata_procコールバックからNULLを返してください。
 *	  古いSWFのDefineBitsJPEG2(3)のように、連続したデータだが、分離しているかどうかがわからない場合は、
 *	  - jpeg_decode()のdata_ptrにデータの先頭アドレスを渡し、
 *	  - data_procコールバック時に画像展開が完了していなければ、引数data_ptrをそのまま返してデータ継続し、
 *	  - data_procコールバック時に画像展開が完了してれば、NULLを返してください。
 *	- 具体的には、clipswf.cのソースコードを参照してください。
 *	  なお、通常のJPEGファイルの場合は、draw_procにNULLを指定すれば、これまでの使い方と変わり有りません。
 * [追記]
 *	* Thu Sep 03 14:03:54 JST 2009 Naoyuki Sawa
 *	- jpeg_decode()に、component引数を追加しました。
 *	  これまでは、Y成分だけを取得していましたが、Cb,Cr成分も取得できるようになりました。
 *	- component=0を指定すると、Y成分について、data_procをコールバックします。
 *	  グレースケール,カラーどちらのJPEGファイルも、必ずY成分を持っているので、このコールバックは保証されます。
 *	- component=1,2を指定すると、Cb,Cr成分について、data_procをコールバックします。
 *	  グレースケールのJPEGファイルに対してcomponent=1,2を指定した場合、data_procのコールバックが発生しません。
 *	- グレースケール,カラーどちらのJPEGファイルか不明の場合に、カラーJPEGファイルに等価な結果を得るには、
 *	  Cb,Crのコンポーネント値を格納するバッファを、128(=Cb,Crの中央値)に初期化しておいてください。
 *	  具体的なコード例は、jpegwin/main.cを参照してください。
 *	- Y,Cb,CrからR,G,Bへの変換式は、以下のとおりです。(JPEG File Interchange Format Version 1.02 より)
 *	    R = Y                        + 1.402   * (Cr - 128)
 *	    G = Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)
 *	    B = Y + 1.772   * (Cb - 128)
 *	  Y,Cb,CrからR,G,Bへの変換結果は、-1以下や256以上になることも有り得ます。
 *	  R,G,Bを直接unsigned char型に格納することは危険であり、いったんint型に格納してクリッピングしてください。
 */
const void* jpeg_decode(const void* data_ptr,
	int component,
	void (*size_proc)(int w, int h, void* user_data),
	void (*draw_proc)(int x, int y, int c, void* user_data),
	const void* (*data_proc)(const void* data_ptr, void* user_data),
	void* user_data);

#endif /*__CLIP_JPEG_H__*/

