/*
	test.c
	
	zoom の最適化のための実験
*/

#include <stdio.h>
#include <ryosuke.h>

typedef	int	deci;
#define	Dshift	8
#define	DUNIT	(1<<Dshift)
#define	Dmask	(DUNIT-1)
#define	ID(i)	((i)<<Dshift)
#define	DI(d)	((d)>>Dshift)

void zoomcopy(int sx1, int sy1, int sx2, int sy2,
			  int dx1, int dy1, int dx2, int dy2, bool matte_sw)
// matte_sw : 半透明指定を有効化するスイッチ(通常 ON, view時 OFF)
{
	printf("zoomcopy source:[%3d,%3d,%3d,%3d]\n",sx1,sy1,sx2,sy2);
	printf("         dest  :[%3d,%3d,%3d,%3d]\n",dx1,dy1,dx2,dy2);
	// 縮小処理
	//   ８ビット固定小数で計算
#define	_swap(a,b)	{ int t; t=(a); (a)=(b); (b)=t; }
	if (sx2 < sx1)
		_swap(sx1,sx2);
	if (sy2 < sy1)
		_swap(sy1,sy2);
	if (dx2 < dx1)
		_swap(dx1,dx2);
	if (dy2 < dy1)
		_swap(dy1,dy2);
	int sxl,syl,dxl,dyl;
	sxl = sx2-sx1+1;
	syl = sy2-sy1+1;
	dxl = dx2-dx1+1;
	dyl = dy2-dy1+1;
	int x,y;
	if (1 /* mode == MODE32K */)
	{
		if (dxl <= sxl || dyl <= syl) 	// 縮小処理
		{
			printf("縮小\n");
			for (y=dy1; y<=dy2; y++)
			{
				for (x=dx1; x<=dx2; x++)
				{
					// 現在の転送先領域（点）に対応する転送元領域を算出
					deci y1,y2,x1,x2;
					if (dxl<=1)
					{
						x1 = ID(sx1);
						x2 = ID(sx2)-1;
					}
					else
					{
						x1 = ID(sx1) + (sxl-1) * (ID(x-dx1  )) / (dxl-1);
						x2 = ID(sx1) + (sxl-1) * (ID(x-dx1+1)) / (dxl-1) - 1;
					}
					if (dyl<=1)
					{
						y1 = ID(sy1);
						y2 = ID(sy2)-1;
					}
					else
					{
						y1 = ID(sy1) + (syl-1) * (ID(y-dy1  )) / (dyl-1);
						y2 = ID(sy1) + (syl-1) * (ID(y-dy1+1)) / (dyl-1) - 1;
					}
					int iy,ix;
					// XY方向の平均色を算出
					deci mean[3];
					{
						int i;
						deci mean_sum[3],mean_pow[3];
						mean_sum[0] = mean_sum[1] = mean_sum[2] = 0; // 重平均wk
						mean_pow[0] = mean_pow[1] = mean_pow[2] = 0; // 重みの和
						for (iy=DI(y1); iy<=DI(y2); iy++)
						{
							// X 方向の平均色を算出
							deci xmean[3];
							{
								int i;
								deci xmean_sum[3], xmean_pow[3];
								xmean_sum[0] = xmean_sum[1] = xmean_sum[2] = 0;	// 重平均wk
								xmean_pow[0] = xmean_pow[1] = xmean_pow[2] = 0; // 重みの和
								for (ix=DI(x1); ix<=DI(x2); ix++)
								{
									deci leftx,rightx;
									leftx = (ix==DI(x1) ? x1 : ID(ix));
									rightx = (ix==DI(x2) ? x2 : ID(ix+1));
									int c,rgb[3];
									c = 0;
									printf("point(%d,%d)\n", ix,iy);
									rgb[0]=(c>>5)&0x1f; rgb[1]=(c>>10)&0x1f; rgb[2]=c&0x1f;
									int i;
									for (i=0; i<3; i++)
									{
										xmean_sum[i] += rgb[i] * (rightx-leftx);
										xmean_pow[i] += (rightx-leftx);
									}
								}
								for (i=0; i<3; i++)
								{
									if (xmean_pow[i] == 0)
										xmean[i] = 0;
									else
										xmean[i] = (xmean_sum[i]<<Dshift)/xmean_pow[i];
								}
							}
							deci topy, bottomy;
							topy = (iy==DI(y1) ? y1 : ID(iy));
							bottomy = (iy==DI(y2) ? y2 : ID(iy+1));
							for (i=0; i<3; i++)
							{
								mean_sum[i] += (xmean[i] * (bottomy-topy))>>Dshift;
								mean_pow[i] += (bottomy-topy);
							}
						}
						for (i=0; i<3; i++)
						{
							if (mean_pow[i] == 0)
								mean[i] = 0;
							else
								mean[i] = ((mean_sum[i]<<Dshift) / mean_pow[i] + DUNIT/2) >> Dshift;
						}
					}
					printf("pset(%d,%d)\n",x,y);
				}
			}
		}
		else 	// 拡大処理
		{
			printf("拡大\n");
			for (y=dy1; y<=dy2; y++)
			{
				for (x=dx1; x<=dx2; x++)
				{
					deci sx,sy;
					if (dxl<=1)
						sx = ID(sx1);
					else
						sx = ID(sx1) + ((sxl-1) * (ID((x-dx1)))) / (dxl-1);
					if (dyl<=1)
						sy = ID(sy1);
					else
						sy = ID(sy1) + ((syl-1) * (ID((y-dy1)))) / (dyl-1);
					int r[2][2],g[2][2],b[2][2],i,j;
					for (i=0; i<2; i++)
					{
						for (j=0; j<2; j++)
						{
							int c;
							c = 0;
							printf("point(%d,%d)\n", DI(sx)+j,DI(sy)+i);
							r[j][i] = (c >>  5) & 0x1f;
							g[j][i] = (c >> 10) & 0x1f;
							b[j][i] =  c        & 0x1f;
						}
					}
					int t1,t2,r1,g1,b1;
						t1 = (r[0][0]*(DUNIT-(sx&Dmask)) + r[1][0]*(sx&Dmask)) >> Dshift;
						t2 = (r[0][1]*(DUNIT-(sx&Dmask)) + r[1][1]*(sx&Dmask)) >> Dshift;
					r1 = (t1*(DUNIT-(sy&Dmask)) + t2*(sy&Dmask)) >> Dshift;
						t1 = (g[0][0]*(DUNIT-(sx&Dmask)) + g[1][0]*(sx&Dmask)) >> Dshift;
						t2 = (g[0][1]*(DUNIT-(sx&Dmask)) + g[1][1]*(sx&Dmask)) >> Dshift;
					g1 = (t1*(DUNIT-(sy&Dmask)) + t2*(sy&Dmask)) >> Dshift;
						t1 = (b[0][0]*(DUNIT-(sx&Dmask)) + b[1][0]*(sx&Dmask)) >> Dshift;
						t2 = (b[0][1]*(DUNIT-(sx&Dmask)) + b[1][1]*(sx&Dmask)) >> Dshift;
					b1 = (t1*(DUNIT-(sy&Dmask)) + t2*(sy&Dmask)) >> Dshift;
					printf("pset(%d,%d)\n", x,y);
				}
			}
		}
	}
}


main(int argc, char *argv[])
{
	if (argc < 9)
	{
		printf("usage : test sx1 sy1 sx2 sy2 dx1 dy1 dx2 dy2\n");
		exit(0);
	}
	zoomcopy(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]),
			 atoi(argv[5]),atoi(argv[6]),atoi(argv[7]),atoi(argv[8]),NO);
}
