/*
* PROJECT: NyARToolkit(Extension)
* --------------------------------------------------------------------------------
* The NyARToolkit is Java edition ARToolKit class library.
* Copyright (C)2008-2009 Ryo Iizuka
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For further information please contact.
* http://nyatla.jp/nyatoolkit/
* <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
*
*/
package jp.nyatla.nyartoolkit.core.rasterreader;
import jp.nyatla.nyartoolkit.NyARException;
import jp.nyatla.nyartoolkit.core.raster.rgb.*;
import jp.nyatla.nyartoolkit.core.types.*;
import jp.nyatla.nyartoolkit.core.utils.*;
/**
* このクラスは、ラスタから任意四角形のパターンを取得します。
* パターンは、遠近法を使ったパースペクティブ補正をかけて、ラスタ矩形に得られます。
* <p>サンプリングモード -
* このクラスは、2種類のサンプリングモードがあります。単体サンプルモードと、マルチサンプルモードです。
* 単体サンプルモードは、{@link #read4Point}関数の解像度値に1を指定したときのモードです。出力1ピクセルに対して、入力1ピクセルを割り当てます。
* マルチサンプルモードは、{@link #read4Point}関数の解像度値に2以上を指定したときのモードです。出力1ピクセルに対して、入力nピクセルの平均値を割り当てます。
* 低解像度の出力を得る場合、マルチサンプルモードの方が良い結果が得られますが、単体サンプルモードと比較して低速になります。
* </p>
* <p>入力ラスタについて
* 基本的には全ての{@link INyARRgbRaster}を実装したクラスを処理できますが、次の3種類のバッファを持つものを推奨します。
* <ul>
* <li>{@link NyARBufferType#INT1D_X8R8G8B8_32}
* <li>{@link NyARBufferType#BYTE1D_B8G8R8_24}
* <li>{@link NyARBufferType#BYTE1D_R8G8B8_24}
* </ul>
* </p>
* <p>出力ラスタについて
* 基本的には全ての{@link NyARBufferType#INT1D_X8R8G8B8_32}形式のバッファを持つラスタを使用してください。
* 他の形式でも動作しますが、低速な場合があります。
* </p>
* <p>高速化について -
* 入力ラスタ形式が、{@link NyARBufferType#INT1D_X8R8G8B8_32},{@link NyARBufferType#BYTE1D_B8G8R8_24}
* ,{@link NyARBufferType#BYTE1D_R8G8B8_24}のものについては、他の形式よりも高速に動作します。
* また、出力ラスタ形式が、{@link NyARBufferType#INT1D_X8R8G8B8_32}の物については、単体サンプリングモードの時のみ、さらに高速に動作します。
* 他の形式のラスタでは、以上のものよりも低速転送で対応します。
* <p>メモ-
* この関数は、1倍の時はNyARColorPatt_Perspective,
* n倍の時はNyARColorPatt_Perspective_O2の関数を元に作ってます。
* </p>
*/
public class NyARPerspectiveRasterReader
{
/** 射影変換パラメータ生成器*/
protected NyARPerspectiveParamGenerator _perspective_gen;
private static final int LOCAL_LT=1;
/** 射影変換パラメータの記憶配列*/
protected final double[] __pickFromRaster_cpara=new double[8];
private IPickupRasterImpl _picker;
private void initializeInstance(int i_buffer_type)
{
//新しいモードに対応したら書いてね。
switch(i_buffer_type){
case NyARBufferType.BYTE1D_B8G8R8X8_32:
this._picker=new PPickup_Impl_BYTE1D_B8G8R8X8_32();
break;
case NyARBufferType.BYTE1D_B8G8R8_24:
this._picker=new PPickup_Impl_BYTE1D_B8G8R8_24();
break;
case NyARBufferType.BYTE1D_R8G8B8_24:
this._picker=new PPickup_Impl_BYTE1D_R8G8B8_24();
break;
default:
this._picker=new PPickup_Impl_AnyRaster();
//低速インタフェイス警告。必要に応じて、高速取得系を実装してね
// System.out.println("NyARToolKit Warning:"+this.getClass().getName()+":Low speed interface.");
break;
}
this._perspective_gen=new NyARPerspectiveParamGenerator_O1(LOCAL_LT,LOCAL_LT);
return;
}
/**
* コンストラクタです。
* このコンストラクタで作成したインスタンスは、入力ラスタタイプに依存しませんが低速です。
* 入力画像の画素形式が既知の場合は、もう一方のコンストラクタを使用してください。
*/
public NyARPerspectiveRasterReader()
{
initializeInstance(NyARBufferType.NULL_ALLZERO);
return;
}
/**
* コンストラクタです。入力ラスタの形式を制限してインスタンスを作成します。
* @param i_input_raster_type
* {@link #read4Point}へ入力するラスタの画素形式。値については、クラスの説明を参照してください。
*/
public NyARPerspectiveRasterReader(int i_input_raster_type)
{
//入力制限
this.initializeInstance(i_input_raster_type);
return;
}
/**
* この関数は、入力ラスタの4頂点(i_vertexs)でかこまれた領域の画像を射影変換して、o_outへ格納します。
* @param i_in_raster
* このラスタの形式は、コンストラクタで制限したものと一致している必要があります。(制限した場合のみ)
* @param i_vertex
* 4頂点を格納した配列です。
* @param i_edge_x
* X方向のエッジ割合です。0-99の数値を指定します。
* @param i_edge_y
* Y方向のエッジ割合です。0-99の数値を指定します。
* @param i_resolution
* 出力の1ピクセルあたりのサンプリング数を指定します。例えば2を指定すると、出力1ピクセルあたり4ピクセルをサンプリングします。
* @param o_out
* 出力先のラスタです。
* @return
* パターンの取得に成功すると、trueを返します。
* @throws NyARException
*/
public boolean read4Point(INyARRgbRaster i_in_raster,NyARDoublePoint2d[] i_vertex,int i_edge_x,int i_edge_y,int i_resolution,INyARRgbRaster o_out)throws NyARException
{
NyARIntSize out_size=o_out.getSize();
int xe=out_size.w*i_edge_x/50;
int ye=out_size.h*i_edge_y/50;
//サンプリング解像度で分岐
if(i_resolution==1){
if (!this._perspective_gen.getParam((xe*2+out_size.w),(ye*2+out_size.h),i_vertex, this.__pickFromRaster_cpara)) {
return false;
}
this._picker.onePixel(xe+LOCAL_LT,ye+LOCAL_LT,this.__pickFromRaster_cpara,i_in_raster,o_out);
}else{
if (!this._perspective_gen.getParam((xe*2+out_size.w)*i_resolution,(ye*2+out_size.h)*i_resolution,i_vertex, this.__pickFromRaster_cpara)) {
return false;
}
this._picker.multiPixel(xe*i_resolution+LOCAL_LT,ye*i_resolution+LOCAL_LT,this.__pickFromRaster_cpara,i_resolution,i_in_raster,o_out);
}
return true;
}
/**
* この関数は、入力ラスタの4頂点(i_vertexs)でかこまれた領域の画像を射影変換して、o_outへ格納します。
* 2番目の引数型だけが、{@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}と異なります。
* @param i_in_raster
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @param i_vertex
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @param i_edge_x
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @param i_edge_y
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @param i_resolution
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @param o_out
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @return
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @throws NyARException
*/
public boolean read4Point(INyARRgbRaster i_in_raster,NyARIntPoint2d[] i_vertex,int i_edge_x,int i_edge_y,int i_resolution,INyARRgbRaster o_out)throws NyARException
{
NyARIntSize out_size=o_out.getSize();
int xe=out_size.w*i_edge_x/50;
int ye=out_size.h*i_edge_y/50;
//サンプリング解像度で分岐
if(i_resolution==1){
if (!this._perspective_gen.getParam((xe*2+out_size.w),(ye*2+out_size.h),i_vertex, this.__pickFromRaster_cpara)) {
return false;
}
this._picker.onePixel(xe+LOCAL_LT,ye+LOCAL_LT,this.__pickFromRaster_cpara,i_in_raster,o_out);
}else{
if (!this._perspective_gen.getParam((xe*2+out_size.w)*i_resolution,(ye*2+out_size.h)*i_resolution,i_vertex, this.__pickFromRaster_cpara)) {
return false;
}
this._picker.multiPixel(xe*i_resolution+LOCAL_LT,ye*i_resolution+LOCAL_LT,this.__pickFromRaster_cpara,i_resolution,i_in_raster,o_out);
}
return true;
}
/**
* この関数は、入力ラスタの4頂点(i_vertexs)でかこまれた領域の画像を射影変換して、o_outへ格納します。
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}と比較して、
* 4頂点を直値で指定する違いがあります。
* @param i_in_raster
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @param i_x1
* 1番目の頂点の座標
* @param i_y1
* 1番目の頂点の座標
* @param i_x2
* 2番目の頂点の座標
* @param i_y2
* 2番目の頂点の座標
* @param i_x3
* 3番目の頂点の座標
* @param i_y3
* 3番目の頂点の座標
* @param i_x4
* 4番目の頂点の座標
* @param i_y4
* 4番目の頂点の座標
* @param i_edge_x
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @param i_edge_y
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @param i_resolution
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @param o_out
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @return
* {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。
* @throws NyARException
*/
public boolean read4Point(INyARRgbRaster i_in_raster,double i_x1,double i_y1,double i_x2,double i_y2,double i_x3,double i_y3,double i_x4,double i_y4,int i_edge_x,int i_edge_y,int i_resolution,INyARRgbRaster o_out)throws NyARException
{
NyARIntSize out_size=o_out.getSize();
int xe=out_size.w*i_edge_x/50;
int ye=out_size.h*i_edge_y/50;
//サンプリング解像度で分岐
if(i_resolution==1){
if (!this._perspective_gen.getParam((xe*2+out_size.w),(ye*2+out_size.h),i_x1,i_y1,i_x2,i_y2,i_x3,i_y3,i_x4,i_y4, this.__pickFromRaster_cpara)) {
return false;
}
this._picker.onePixel(xe+LOCAL_LT,ye+LOCAL_LT,this.__pickFromRaster_cpara,i_in_raster,o_out);
}else{
if (!this._perspective_gen.getParam((xe*2+out_size.w)*i_resolution,(ye*2+out_size.h)*i_resolution,i_x1,i_y1,i_x2,i_y2,i_x3,i_y3,i_x4,i_y4, this.__pickFromRaster_cpara)) {
return false;
}
this._picker.multiPixel(xe*i_resolution+LOCAL_LT,ye*i_resolution+LOCAL_LT,this.__pickFromRaster_cpara,i_resolution,i_in_raster,o_out);
}
return true;
}
}
//
//ここから先は入力画像毎のラスタドライバ
//
/** 画素形式毎のドライバ定義*/
interface IPickupRasterImpl
{
public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException;
public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException;
}
/** BYTE1D_R8G8B8_24形式のドライバ*/
final class PPickup_Impl_BYTE1D_R8G8B8_24 implements IPickupRasterImpl
{
public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException
{
assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));
//出力形式による分岐
switch(o_out.getBufferType())
{
case NyARBufferType.INT1D_X8R8G8B8_32:
onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);
break;
default:
onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);
break;
}
return;
}
public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException
{
assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));
//出力形式による分岐(分解能が高い時は大した差が出ないから、ANYだけ。)
multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,(byte[])i_in_raster.getBuffer(),o_out);
return;
}
private void onePixel_INT1D_X8R8G8B8_32(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException
{
assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));
int[] pat_data=(int[])o_out.getBuffer();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
double cp7_cy_1 =cp7*pk_t+1.0+cp6*pk_l;
double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;
double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;
int r,g,b;
int p=0;
for(int iy=0;iy<out_h;iy++){
//解像度分の点を取る。
double cp7_cy_1_cp6_cx =cp7_cy_1;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;
for(int ix=0;ix<out_w;ix++){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
final int bp = (x + y * in_w) * 3;
r=(i_in_buf[bp + 0] & 0xff);
g=(i_in_buf[bp + 1] & 0xff);
b=(i_in_buf[bp + 2] & 0xff);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
pat_data[p]=(r<<16)|(g<<8)|((b&0xff));
p++;
}
cp7_cy_1+=cp7;
cp1_cy_cp2+=cp1;
cp4_cy_cp5+=cp4;
}
return;
}
private void onePixel_ANY(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException
{
INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
double cp7_cy_1 =cp7*pk_t+1.0+cp6*pk_l;
double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;
double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;
int r,g,b;
for(int iy=0;iy<out_h;iy++){
//解像度分の点を取る。
double cp7_cy_1_cp6_cx =cp7_cy_1;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;
for(int ix=0;ix<out_w;ix++){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
final int bp = (x + y * in_w) * 3;
r=(i_in_buf[bp + 0] & 0xff);
g=(i_in_buf[bp + 1] & 0xff);
b=(i_in_buf[bp + 2] & 0xff);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
out_reader.setPixel(ix,iy,r,g,b);
}
cp7_cy_1+=cp7;
cp1_cy_cp2+=cp1;
cp4_cy_cp5+=cp4;
}
return;
}
private void multiPixel_ANY(int pk_l,int pk_t,int in_w,int in_h,int i_resolution,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException
{
final int res_pix=i_resolution*i_resolution;
INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
double cp2=cpara[2];
double cp5=cpara[5];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
for(int iy=out_h-1;iy>=0;iy--){
//解像度分の点を取る。
for(int ix=out_w-1;ix>=0;ix--){
int r,g,b;
r=g=b=0;
int cy=pk_t+iy*i_resolution;
int cx=pk_l+ix*i_resolution;
double cp7_cy_1_cp6_cx_b =cp7*cy+1.0+cp6*cx;
double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;
double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;
for(int i2y=i_resolution-1;i2y>=0;i2y--){
double cp7_cy_1_cp6_cx =cp7_cy_1_cp6_cx_b;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;
for(int i2x=i_resolution-1;i2x>=0;i2x--){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
final int bp = (x + y * in_w) * 3;
r+=(i_in_buf[bp + 0] & 0xff);
g+=(i_in_buf[bp + 1] & 0xff);
b+=(i_in_buf[bp + 2] & 0xff);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
}
cp7_cy_1_cp6_cx_b+=cp7;
cp1_cy_cp2_cp0_cx_b+=cp1;
cp4_cy_cp5_cp3_cx_b+=cp4;
}
out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);
}
}
return;
}
}
/** BYTE1D_B8G8R8_24形式のドライバ*/
final class PPickup_Impl_BYTE1D_B8G8R8_24 implements IPickupRasterImpl
{
public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException
{
assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24));
//出力形式による分岐
switch(o_out.getBufferType())
{
case NyARBufferType.INT1D_X8R8G8B8_32:
onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);
break;
default:
onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);
break;
}
return;
}
public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException
{
assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24));
//出力形式による分岐(分解能が高い時は大した差が出ないから、ANYだけ。)
multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,(byte[])i_in_raster.getBuffer(),o_out);
return;
}
private void onePixel_INT1D_X8R8G8B8_32(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException
{
assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));
int[] pat_data=(int[])o_out.getBuffer();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
double cp7_cy_1 =cp7*pk_t+1.0+cp6*pk_l;
double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;
double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;
int r,g,b;
int p=0;
for(int iy=0;iy<out_h;iy++){
//解像度分の点を取る。
double cp7_cy_1_cp6_cx =cp7_cy_1;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;
for(int ix=0;ix<out_w;ix++){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
final int bp = (x + y * in_w) * 3;
r=(i_in_buf[bp + 2] & 0xff);
g=(i_in_buf[bp + 1] & 0xff);
b=(i_in_buf[bp + 0] & 0xff);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
pat_data[p]=(r<<16)|(g<<8)|((b&0xff));
p++;
}
cp7_cy_1+=cp7;
cp1_cy_cp2+=cp1;
cp4_cy_cp5+=cp4;
}
return;
}
private void onePixel_ANY(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException
{
INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
double cp7_cy_1 =cp7*pk_t+1.0+cp6*pk_l;
double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;
double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;
int r,g,b;
for(int iy=0;iy<out_h;iy++){
//解像度分の点を取る。
double cp7_cy_1_cp6_cx =cp7_cy_1;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;
for(int ix=0;ix<out_w;ix++){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
final int bp = (x + y * in_w) * 3;
r=(i_in_buf[bp + 2] & 0xff);
g=(i_in_buf[bp + 1] & 0xff);
b=(i_in_buf[bp + 0] & 0xff);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
out_reader.setPixel(ix,iy,r,g,b);
}
cp7_cy_1+=cp7;
cp1_cy_cp2+=cp1;
cp4_cy_cp5+=cp4;
}
return;
}
private void multiPixel_ANY(int pk_l,int pk_t,int in_w,int in_h,int i_resolution,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException
{
final int res_pix=i_resolution*i_resolution;
INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
double cp2=cpara[2];
double cp5=cpara[5];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
for(int iy=out_h-1;iy>=0;iy--){
//解像度分の点を取る。
for(int ix=out_w-1;ix>=0;ix--){
int r,g,b;
r=g=b=0;
int cy=pk_t+iy*i_resolution;
int cx=pk_l+ix*i_resolution;
double cp7_cy_1_cp6_cx_b =cp7*cy+1.0+cp6*cx;
double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;
double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;
for(int i2y=i_resolution-1;i2y>=0;i2y--){
double cp7_cy_1_cp6_cx =cp7_cy_1_cp6_cx_b;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;
for(int i2x=i_resolution-1;i2x>=0;i2x--){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
final int bp = (x + y * in_w) * 3;
r+=(i_in_buf[bp + 2] & 0xff);
g+=(i_in_buf[bp + 1] & 0xff);
b+=(i_in_buf[bp + 0] & 0xff);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
}
cp7_cy_1_cp6_cx_b+=cp7;
cp1_cy_cp2_cp0_cx_b+=cp1;
cp4_cy_cp5_cp3_cx_b+=cp4;
}
out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);
}
}
return;
}
}
/** BYTE1D_B8G8R8X8_32形式のドライバ*/
final class PPickup_Impl_BYTE1D_B8G8R8X8_32 implements IPickupRasterImpl
{
public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException
{
assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8X8_32));
//出力形式による分岐
switch(o_out.getBufferType())
{
case NyARBufferType.INT1D_X8R8G8B8_32:
onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);
break;
default:
onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);
break;
}
return;
}
public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException
{
assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8X8_32));
//出力形式による分岐(分解能が高い時は大した差が出ないから、ANYだけ。)
multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,(byte[])i_in_raster.getBuffer(),o_out);
return;
}
private void onePixel_INT1D_X8R8G8B8_32(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException
{
assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));
int[] pat_data=(int[])o_out.getBuffer();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
double cp7_cy_1 =cp7*pk_t+1.0+cp6*pk_l;
double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;
double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;
int r,g,b;
int p=0;
for(int iy=0;iy<out_h;iy++){
//解像度分の点を取る。
double cp7_cy_1_cp6_cx =cp7_cy_1;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;
for(int ix=0;ix<out_w;ix++){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
final int bp = (x + y * in_w) * 4;
r=(i_in_buf[bp + 2] & 0xff);
g=(i_in_buf[bp + 1] & 0xff);
b=(i_in_buf[bp + 0] & 0xff);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
pat_data[p]=(r<<16)|(g<<8)|((b&0xff));
p++;
}
cp7_cy_1+=cp7;
cp1_cy_cp2+=cp1;
cp4_cy_cp5+=cp4;
}
return;
}
private void onePixel_ANY(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException
{
INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
double cp7_cy_1 =cp7*pk_t+1.0+cp6*pk_l;
double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;
double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;
int r,g,b;
for(int iy=0;iy<out_h;iy++){
//解像度分の点を取る。
double cp7_cy_1_cp6_cx =cp7_cy_1;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;
for(int ix=0;ix<out_w;ix++){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
final int bp = (x + y * in_w) * 4;
r=(i_in_buf[bp + 2] & 0xff);
g=(i_in_buf[bp + 1] & 0xff);
b=(i_in_buf[bp + 0] & 0xff);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
out_reader.setPixel(ix,iy,r,g,b);
}
cp7_cy_1+=cp7;
cp1_cy_cp2+=cp1;
cp4_cy_cp5+=cp4;
}
return;
}
private void multiPixel_ANY(int pk_l,int pk_t,int in_w,int in_h,int i_resolution,double[] cpara,byte[] i_in_buf,INyARRgbRaster o_out)throws NyARException
{
final int res_pix=i_resolution*i_resolution;
INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
double cp2=cpara[2];
double cp5=cpara[5];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
for(int iy=out_h-1;iy>=0;iy--){
//解像度分の点を取る。
for(int ix=out_w-1;ix>=0;ix--){
int r,g,b;
r=g=b=0;
int cy=pk_t+iy*i_resolution;
int cx=pk_l+ix*i_resolution;
double cp7_cy_1_cp6_cx_b =cp7*cy+1.0+cp6*cx;
double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;
double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;
for(int i2y=i_resolution-1;i2y>=0;i2y--){
double cp7_cy_1_cp6_cx =cp7_cy_1_cp6_cx_b;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;
for(int i2x=i_resolution-1;i2x>=0;i2x--){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
final int bp = (x + y * in_w) * 4;
r+=(i_in_buf[bp + 2] & 0xff);
g+=(i_in_buf[bp + 1] & 0xff);
b+=(i_in_buf[bp + 0] & 0xff);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
}
cp7_cy_1_cp6_cx_b+=cp7;
cp1_cy_cp2_cp0_cx_b+=cp1;
cp4_cy_cp5_cp3_cx_b+=cp4;
}
out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);
}
}
return;
}
}
/**
* 全種類のNyARRasterを入力できるクラス
*/
final class PPickup_Impl_AnyRaster implements IPickupRasterImpl
{
private final int[] __pickFromRaster_rgb_tmp = new int[3];
public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException
{
//出力形式による分岐
switch(o_out.getBufferType())
{
case NyARBufferType.INT1D_X8R8G8B8_32:
onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,i_in_raster.getRgbPixelReader(),o_out);
break;
default:
onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,i_in_raster.getRgbPixelReader(),o_out);
break;
}
return;
}
public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException
{
//出力形式による分岐
switch(o_out.getBufferType())
{
case NyARBufferType.INT1D_X8R8G8B8_32:
multiPixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,i_in_raster.getRgbPixelReader(),o_out);
break;
default:
multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,i_in_raster.getRgbPixelReader(),o_out);
break;
}
return;
}
private void onePixel_INT1D_X8R8G8B8_32(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,INyARRgbPixelReader i_in_reader,INyARRgbRaster o_out)throws NyARException
{
assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));
final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;
int[] pat_data=(int[])o_out.getBuffer();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
double cp7_cy_1 =cp7*pk_t+1.0+cp6*pk_l;
double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;
double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;
int p=0;
for(int iy=out_h-1;iy>=0;iy--){
//解像度分の点を取る。
double cp7_cy_1_cp6_cx =cp7_cy_1;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;
for(int ix=out_w-1;ix>=0;ix--){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
i_in_reader.getPixel(x, y, rgb_tmp);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
pat_data[p]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|((rgb_tmp[2]&0xff));
p++;
}
cp7_cy_1+=cp7;
cp1_cy_cp2+=cp1;
cp4_cy_cp5+=cp4;
}
return;
}
private void onePixel_ANY(int pk_l,int pk_t,int in_w,int in_h,double[] cpara,INyARRgbPixelReader i_in_reader,INyARRgbRaster o_out)throws NyARException
{
final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;
INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
double cp7_cy_1 =cp7*pk_t+1.0+cp6*pk_l;
double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;
double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;
for(int iy=0;iy<out_h;iy++){
//解像度分の点を取る。
double cp7_cy_1_cp6_cx =cp7_cy_1;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;
for(int ix=0;ix<out_w;ix++){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
i_in_reader.getPixel(x, y, rgb_tmp);
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
out_reader.setPixel(ix,iy,rgb_tmp);
}
cp7_cy_1+=cp7;
cp1_cy_cp2+=cp1;
cp4_cy_cp5+=cp4;
}
return;
}
private void multiPixel_INT1D_X8R8G8B8_32(int pk_l,int pk_t,int in_w,int in_h,int i_resolution,double[] cpara,INyARRgbPixelReader i_in_reader,INyARRgbRaster o_out)throws NyARException
{
assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));
final int res_pix=i_resolution*i_resolution;
final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;
int[] pat_data=(int[])o_out.getBuffer();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
double cp2=cpara[2];
double cp5=cpara[5];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
int p=(out_w*out_h-1);
for(int iy=out_h-1;iy>=0;iy--){
//解像度分の点を取る。
for(int ix=out_w-1;ix>=0;ix--){
int r,g,b;
r=g=b=0;
int cy=pk_t+iy*i_resolution;
int cx=pk_l+ix*i_resolution;
double cp7_cy_1_cp6_cx_b =cp7*cy+1.0+cp6*cx;
double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;
double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;
for(int i2y=i_resolution-1;i2y>=0;i2y--){
double cp7_cy_1_cp6_cx =cp7_cy_1_cp6_cx_b;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;
for(int i2x=i_resolution-1;i2x>=0;i2x--){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
i_in_reader.getPixel(x, y, rgb_tmp);
r+=rgb_tmp[0];
g+=rgb_tmp[1];
b+=rgb_tmp[2];
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
}
cp7_cy_1_cp6_cx_b+=cp7;
cp1_cy_cp2_cp0_cx_b+=cp1;
cp4_cy_cp5_cp3_cx_b+=cp4;
}
r/=res_pix;
g/=res_pix;
b/=res_pix;
pat_data[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));
p--;
}
}
return;
}
private void multiPixel_ANY(int pk_l,int pk_t,int in_w,int in_h,int i_resolution,double[] cpara,INyARRgbPixelReader i_in_reader,INyARRgbRaster o_out)throws NyARException
{
final int res_pix=i_resolution*i_resolution;
final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;
INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();
//ピクセルリーダーを取得
double cp0=cpara[0];
double cp3=cpara[3];
double cp6=cpara[6];
double cp1=cpara[1];
double cp4=cpara[4];
double cp7=cpara[7];
double cp2=cpara[2];
double cp5=cpara[5];
int out_w=o_out.getWidth();
int out_h=o_out.getHeight();
for(int iy=out_h-1;iy>=0;iy--){
//解像度分の点を取る。
for(int ix=out_w-1;ix>=0;ix--){
int r,g,b;
r=g=b=0;
int cy=pk_t+iy*i_resolution;
int cx=pk_l+ix*i_resolution;
double cp7_cy_1_cp6_cx_b =cp7*cy+1.0+cp6*cx;
double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;
double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;
for(int i2y=i_resolution-1;i2y>=0;i2y--){
double cp7_cy_1_cp6_cx =cp7_cy_1_cp6_cx_b;
double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;
double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;
for(int i2x=i_resolution-1;i2x>=0;i2x--){
//1ピクセルを作成
final double d=1/(cp7_cy_1_cp6_cx);
int x=(int)((cp1_cy_cp2_cp0_cx)*d);
int y=(int)((cp4_cy_cp5_cp3_cx)*d);
if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}
if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}
i_in_reader.getPixel(x, y, rgb_tmp);
r+=rgb_tmp[0];
g+=rgb_tmp[1];
b+=rgb_tmp[2];
cp7_cy_1_cp6_cx+=cp6;
cp1_cy_cp2_cp0_cx+=cp0;
cp4_cy_cp5_cp3_cx+=cp3;
}
cp7_cy_1_cp6_cx_b+=cp7;
cp1_cy_cp2_cp0_cx_b+=cp1;
cp4_cy_cp5_cp3_cx_b+=cp4;
}
out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);
}
}
return;
}
}