// RGB→YUV（縦倍対応）完全MCU用
// ＧＲＡＭ構成が機種依存。
// X68は1dot 1wordである。RGBI構成はプログラム参照のこと。

#include "_jpeglib.h"
#include "jpeg.h"

void RGB2YUV1(unshort *gram,short *y,short *u,short *v,int yw,int vwx)
// JWX*ywドット範囲から読み取り、RGB→YUV変換する
// 1:1:1用
{
short wx,wy;
unshort *gram0;
	for (wy=0;wy<yw;wy++) {
		gram0=gram;
		for (wx=0;wx<JWX;wx++) {
			*y++=RGB2YUV0(gram++,u++,v++);
		}
		gram=gram0+vwx; // 行飛ばし
	}
}

void RGB2YUV4(unshort *gram,short *y,short *u,short *v,int yw,int vwx)
// JWX*ywドット単位をZ順で読み取り、RGB→YUV変換する
// Yは全ドット、U/Vは2ドット毎に取得する
// 4:1:1用
{
short wx,wy,i,j,*yy[2],*y0;
unshort *gram0;
	y0=y;
	for (j=0;j<2;j++) { // 上２ブロック→下２ブロック
	    yy[0]=y;
	    yy[1]=&y[JWX*JWY]; // 隣のブロック分先頭（縦倍時はブロックの半分しか使わないが隣ブロックのアドレスは変わらない）
	    for (wy=0;wy<yw;wy+=2) {
		// 第一ライン
	 	gram0=gram;
		for (i=0;i<2;i++) { // 横２ブロックを一気に処理する（u,vのため）
		    for (wx=0;wx<JWX;wx+=2) { // [0]=左ブロック,[1]=右ブロック（wxは回数）
			*yy[i]++=RGB2YUV0(gram++,u++,v++);
			*yy[i]++=RGB2Y0(gram++); // U/Vは２ドット目は捨てる
		    }
		}
		gram0=gram=gram0+vwx;
		// 第２ライン
		for (i=0;i<2;i++) { // 横２ブロックを一気に処理する（u,vのため）
		    for (wx=0;wx<JWX;wx++) { // [0]=左ブロック,[1]=右ブロック（wxは回数）
			*yy[i]++=RGB2Y0(gram++);
		    }
		}
		gram=gram0+vwx;
	    } // for wy
	    y=&y0[JWX*JWY*2]; // 隣のブロックは処理済みなのでさらにその先
	} // for j
	// 縦倍時も&y[0〜3][0]からに格納するため、各yの下半分は空きとする
	// ＝&y[?][0〜JWX*JWY/2-1]迄を使い、それ以降を空けたままにすると言うこと
}

void RGB2YUV2_(unshort *gram,short *y,short *u,short *v,int yw,int vwx)
// JWX*wyドット単位を-順で読み取り、RGB→YUV変換する
// Yは全ドット、U/Vは横2ドット縦1ドット毎に取得する
// 2-:1:1用
{
short wx,wy,*yy[2];
unshort *gram0;
int i;
	yy[0]=y;
	yy[1]=&y[JWX*JWY]; // 隣のブロック分先頭（縦倍時はブロックの半分しか使わないが隣ブロックのアドレスは変わらない）
	for (wy=0;wy<yw;wy++) {
	    gram0=gram;
	    for (i=0;i<2;i++) { // 横２ブロックを一気に処理する（u,vのため）
		for (wx=0;wx<JWX;wx+=2) { // [0]=左ブロック,[1]=右ブロック（wxは回数）
			*yy[i]++=RGB2YUV0(gram++,u++,v++);
			*yy[i]++=RGB2Y0(gram++); // U/Vは２ドット目は捨てる
		}
	    }
	    gram=gram0+vwx;
	}
	// 縦倍時も&y[0〜1][0]からに格納するため、各yの下半分は空きとする
	// ＝&y[?][0〜JWX*JWY/2-1]迄を使い、それ以降を空けたままにすると言うこと
}

void RGB2YUV2I(unshort *gram,short *y,short *u,short *v,int yw,int vwx)
// JWX*wyドット単位をI順で読み取り、RGB→YUV変換する。
// Yは全ドット、U/Vは横1ドット縦2ドット毎に取得する
// 2I:1:1用
{
short wx,wy,i,*yy,*y0;
unshort *gram0;
	y0=y;
	for (i=0;i<2;i++) { // 上ブロック→下ブロック
	    for (wy=0;wy<yw;wy+=2) {
		yy=y+JWX; // １ライン下
		gram0=gram;
		for (wx=0;wx<JWX;wx++) {
			*y ++=RGB2YUV0(gram,u++,v++); // 第１ライン
			*yy++=RGB2Y0(gram+vwx);    // 第２ライン：U/Vは全部捨てる
			gram++;
		}
		y=yy;
		gram=gram0+vwx*2; // 行飛ばし
	    }
	    y=&y0[JWX*JWY]; // 次ブロック
	}
	// 縦倍時も&y[0〜1][0]からに格納するため、各yの下半分は空きとする
	// ＝&y[?][0〜JWX*JWY/2-1]迄を使い、それ以降を空けたままにすると言うこと
}
