//----------------------------------------------------------------------------
// JPEGライブラリヘッダー
// ユーザー参照用

#ifndef	__AIG_JPEG__
#define	__AIG_JPEG__	1

#include "defines.h"
#include <stdio.h>

//----------------------------------------------------------------------------
// 機種依存

// X68の65536色モードでの画面幅
#define	X68GWX		512	// 横幅＝横ワード数
#define	X68GWY		512	// 縦幅
// 画面アドレス計算
#define	GramAdrs(x,y)	(unshort *)(0xc00000+(x+y*X68GWX)*sizeof(unshort))

//----------------------------------------------------------------------------
// 設定ビット定義(bit0〜30まで)

// サンプリングファクタ
#define	MD_AMODE	0x000f		// bit0-3
#define	MD_111		0		// 1 :1:1圧縮展開
#define	MD_2I11		BIT0		// 2I:1:1圧縮展開
#define	MD_2_11		BIT1		// 2-:1:1圧縮展開
#define	MD_411		(BIT0|BIT1)	// 4 :1:1圧縮展開

// 圧縮倍率
// B_MODEは処置の都合上ビット対応しているがOR指定出来ない
#define	MD_BMODE	(BIT5|BIT6|BIT7)
#define	MD_BAI		BIT5	// 縦倍圧縮
#define	MD_1_2		BIT6	// 縦横1/2
#define	MD_1_4		BIT7	// 縦横1/4
#define	MD_1_8		(BIT6|BIT7)	// 縦横1/8

// 展開倍率
// E_MODEは処置の都合上ビット対応しているがOR指定出来ない
#define	MD_EMODE	(BIT8|BIT9|BIT10)
#define	MD_BAIE		BIT8	// 縦倍展開
#define	MD_1_2E		BIT9	// 縦横1/2
#define	MD_1_4E		BIT10	// 縦横1/4
#define	MD_1_8E		(BIT9|BIT10)	// 縦横1/8

// その他
#define	MD_BW	BIT12	// 白黒圧縮展開
#define	MD_BWE	BIT13	// 白黒展開（圧縮は通常）

//----------------------------------------------------------------------------
// １ブロックとしての処理単位ドット数
// JWX*JWYドットのブロックを１つとして処理していく
// 全て８で変更不可
#define	JWX	8
#define	JWY	8
#define	JWU	8
#define	JWV	8

//----------------------------------------------------------------------------

// 内部標準量子化テーブル
// これをshortにするとかえって遅くなる
extern	unchar	const	QtableY[];
extern	unchar  const	QtableUV[];

// ジグザグスキャン表
extern	unchar	const	 _zigzag[];

//----------------------------------------------------------------------------
// ハフマンコード表用

typedef struct {	// 圧縮用ハフマンコード用構造体
	unshort code;	// ハフマンコード
	short	len;	// そのコードのビット長さ
} HUFFMAN;
// 圧縮用は固定テーブルなので定数表である
#define	ACBIT	11	// AC成分の記録に必要なビット数
#define	ACLEN	16	// AC成分記録で０の長さの最大長（これ以上はZRL）
extern	const HUFFMAN	HuffDC_Y[],HuffDC_UV[];
extern	const HUFFMAN	HuffAC_Y[ACLEN][ACBIT],HuffAC_UV[ACLEN][ACBIT];

typedef struct {	// 展開用ハフマンコード用構造体
	unshort code;	// ハフマンコード
	unchar	len;	// そのコードのビット長さ
	unchar	dat;	// そのコードの対応する数字（意味はDCとACで異なる）
} iHUFFMAN;
// 展開用はファイルから作成するワークエリアである
// dat : DCでは後に続くデータのビット長＝HuffDC_*[]の要素番号
//	 ACではHuffAC_*[]の要素番号

// ハフマンコード表展開用ワーク宣言（定義はユーザーが行う）
#define	HUFF_DC_Y_SIZE		(1+16)
#define	HUFF_DC_UV_SIZE		(1+16)
#define	HUFF_AC_Y_SIZE		(ACLEN*16)
#define	HUFF_AC_UV_SIZE		(ACLEN*16)
#define	CNT_DC_Y_SIZE		(16)
#define	CNT_DC_UV_SIZE		(16)
#define	CNT_AC_Y_SIZE		(16)
#define	CNT_AC_UV_SIZE		(16)
// このサイズ以上確保すれば良いので、ここではサイズ付き宣言はしない
extern iHUFFMAN iHuffDC_Y[],iHuffDC_UV[];
extern iHUFFMAN iHuffAC_Y[],iHuffAC_UV[];
extern unchar cntDC_Y[],cntAC_Y[],cntDC_UV[],cntAC_UV[];

//----------------------------------------------------------------------------
// ＪＰＥＧマーカー(0xff??)

#define	JPGMAKHED	0xff	// JPEGのマーカーは0xff??である
typedef enum {
//	 TEM=0xff01
	 SOF0=0xffc0	// 基本DCTフレームヘッダー
	,SOF1	,SOF2	,SOF3
	,DHT=0xffc4	// ハフマンテーブル定義
	,SOF5	,SOF6	,SOF7
	,JPG		// JPEG拡張のためのリザーブ
	,SOF9	,SOF10	,SOF11
	,DAC=0xffcc	// 算術符号化条件付け定義
	,SOF13	,SOF14	,SOF15
	,RST0=0xffd0	// ↓リスタートマーカー
		,RST1	,RST2	,RST3	,RST4	,RST5	,RST6	,RST7
			// ↑リスタートマーカー
	,SOI=0xffd8	// 画像開始
	,EOI=0xffd9	// 画像終了
	,SOS=0xffda	// スキャンヘッダー
	,DQT=0xffdb	// 量子化テーブル定義
	,DNL=0xffdc	// ライン数定義
	,DRI=0xffdd	// リスタートインターバル定義
	,DHP=0xffde
	,EXP=0xffdf
	,APP0=0xffe0	// アプリケーションセグメント
		,APP1	,APP2	,APP3	,APP4	,APP5	,APP6	,APP7
	,APP8	,APP9	,APP10	,APP11	,APP12	,APP13	,APP14	,APP15
	,JPG0=0xfff0
		,JPG1	,JPG2	,JPG3	,JPG4	,JPG5	,JPG6	,JPG7
	,JPG8	,JPG9	,JPG10	,JPG11	,JPG12	,JPG13
	,COM=0xfffe	// コメント
} JPEGMAKER;

//----------------------------------------------------------------------------
// エラーコード定義

typedef enum {
	 JPEG_OK=0
	,JPEG_READ_ERR
	,JPEG_WRITE_ERR
	,JPEG_MAKER_ERR		// マーカーエラー
	,JPEG_NO_JPEG
	,JPEG_NO_WORK
	,JPEG_ILL_HEADER	// ヘッダー異常
	,JPEG_ALREADY_BW	// すでに白黒である(jpgbw2で使用)
} JPEGERR;

//----------------------------------------------------------------------------
// プロトタイプ宣言

#ifdef  __cplusplus
extern  "C" {
#endif
// 共用
int	MakeiHuff(unchar **,iHUFFMAN [],unchar []);
int	MakeHuffDC(unchar *,HUFFMAN [],int );
int	MakeHuffAC(unchar *,HUFFMAN [][],int );
void	RemakeHuff(unchar *,unchar *,unchar *,unchar *,long);
void	iHuff2HuffAC(iHUFFMAN [],unchar [],HUFFMAN [][]);
void	iHuff2HuffDC(iHUFFMAN [],unchar [],HUFFMAN []);
//
void	DCT2(short *,short *,unchar const *);
void	DCT2b(short *,short *,unchar const *);
void	IDCT2(short *,short *,unchar const *);
//
short	RGB2YUV0(unshort *,short *,short *);
short	RGB2Y0(unshort *);
void	RGB2YUV1( unshort *,short *,short *,short *,int,int);
void	RGB2YUV2I(unshort *,short *,short *,short *,int,int);
void	RGB2YUV2_(unshort *,short *,short *,short *,int,int);
void	RGB2YUV4( unshort *,short *,short *,short *,int,int);
void	GetRGB(unshort *,unshort *,int ,int ,int ,int ,int );

void	YUV2RGB0( unshort *,short  ,short  ,short);
void	YUV2RGB01(unshort *,short  ,short  ,short);

void	YUV2RGB1(  unshort *,short *,short *,short *);
void	YUV2RGB2I( unshort *,short *,short *,short *);
void	YUV2RGB2_( unshort *,short *,short *,short *);
void	YUV2RGB4(  unshort *,short *,short *,short *);

void	YUV2RGB1x( unshort *,short *,short *,short *,int ,int ,int );
void	YUV2RGB2Ix(unshort *,short *,short *,short *,int ,int ,int );
void	YUV2RGB2_x(unshort *,short *,short *,short *,int ,int ,int );
void	YUV2RGB4x( unshort *,short *,short *,short *,int ,int ,int );
//
void	SetQtable(int ,unchar [],unchar []);
//
int	PressParamX(int,int,int *,int *,long ,short *,int *);
//
// ファイル版
int	BitOut(FILE *,unshort ,int );
int	BitOutFlush(FILE *);
int	BitIn(FILE *,int );
int	BitIn1(FILE *);
void	BitInFlush(void);
int	GetMaker(FILE *);
int	PutMaker(FILE *,int );
//
int	HuffDC(FILE *,short   ,HUFFMAN [],short *);
int	HuffAC(FILE *,short [],HUFFMAN [][]);
//
int	CmpiHuff(FILE *,iHUFFMAN [],unchar []);
int	iHuffDC(FILE *,iHUFFMAN [],unchar [], short [],short *);
int	iHuffAC(FILE *,iHUFFMAN [],unchar [], short []);
//
int	JpegPress(FILE *,int ,int ,int ,int ,long ,short,int,int,unchar *,unchar *,unchar *,short [][],short [],short [],short []);
int	JpegExpand(FILE *,int ,int ,int ,int ,int,int,long ,short,unchar *,unchar *,unchar *,short [][],short [],short [],short []);
//
// オンメモリ版
int	mBitOut(unchar *(*),unshort ,int );
int	mBitOutFlush(unchar *(*));
int	mBitIn(unchar *(*),int );
int	mBitIn1(unchar *(*));
void	mBitInFlush(void);
int	mGetMaker(unchar *(*));
int	mPutMaker(unchar *(*),int );
//
int	mHuffDC(unchar *(*),short   ,HUFFMAN [],short *);
int	mHuffAC(unchar *(*),short [],HUFFMAN [][]);
//
int	mCmpiHuff(unchar *(*),iHUFFMAN [],unchar []);
int	miHuffDC(unchar *(*),iHUFFMAN [],unchar [], short [],short *);
int	miHuffAC(unchar *(*),iHUFFMAN [],unchar [], short []);
//
int	mJpegPress(unchar *(*),int ,int ,int ,int ,long ,short,int,int,unchar *,unchar *,unchar *,short [][],short [],short [],short []);
int	mJpegExpand(unchar *(*),int ,int ,int ,int ,int,int,long ,short,unchar *,unchar *,unchar *,short [][],short [],short [],short []);
//
// ファイル化版
int	JpegStart(FILE *);
int	JpegEnd(FILE *);
int	JpegMakeHeader(FILE *,int ,int ,short,unchar *,unchar *,unchar *
			,unchar *,int,unchar *,int,unchar *,int,unchar *,int,long,unchar *);
JPEGERR JpegReadHeader(FILE *,int *,int *,long *,short *,unchar *,unchar *,unchar *,int ,int );
#ifdef  __cplusplus
}
#endif

//----------------------------------------------------------------------------

#endif

//----------------------------------------------------------------------------
