OSDN Git Service

git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit/trunk@802 7cac0...
[nyartoolkit-and/nyartoolkit-and.git] / lib / src / jp / nyatla / nyartoolkit / core / rasterreader / NyARPerspectiveRasterReader.java
1 /* \r
2  * PROJECT: NyARToolkit(Extension)\r
3  * --------------------------------------------------------------------------------\r
4  * The NyARToolkit is Java edition ARToolKit class library.\r
5  * Copyright (C)2008-2009 Ryo Iizuka\r
6  *\r
7  * This program is free software: you can redistribute it and/or modify\r
8  * it under the terms of the GNU General Public License as published by\r
9  * the Free Software Foundation, either version 3 of the License, or\r
10  * (at your option) any later version.\r
11  * \r
12  * This program is distributed in the hope that it will be useful,\r
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15  * GNU General Public License for more details.\r
16  *\r
17  * You should have received a copy of the GNU General Public License\r
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
19  * \r
20  * For further information please contact.\r
21  *      http://nyatla.jp/nyatoolkit/\r
22  *      <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
23  * \r
24  */\r
25 package jp.nyatla.nyartoolkit.core.rasterreader;\r
26 \r
27 import jp.nyatla.nyartoolkit.NyARException;\r
28 import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
29 import jp.nyatla.nyartoolkit.core.types.*;\r
30 import jp.nyatla.nyartoolkit.core.utils.*;\r
31 \r
32 \r
33 /**\r
34  * このクラスは、ラスタから任意四角形のパターンを取得します。\r
35  * パターンは、遠近法を使ったパースペクティブ補正をかけて、ラスタ矩形に得られます。\r
36  * <p>サンプリングモード -\r
37  * このクラスは、2種類のサンプリングモードがあります。単体サンプルモードと、マルチサンプルモードです。\r
38  * 単体サンプルモードは、{@link #read4Point}関数の解像度値に1を指定したときのモードです。出力1ピクセルに対して、入力1ピクセルを割り当てます。\r
39  * マルチサンプルモードは、{@link #read4Point}関数の解像度値に2以上を指定したときのモードです。出力1ピクセルに対して、入力nピクセルの平均値を割り当てます。\r
40  * 低解像度の出力を得る場合、マルチサンプルモードの方が良い結果が得られますが、単体サンプルモードと比較して低速になります。\r
41  * </p>\r
42  * <p>入力ラスタについて\r
43  * 基本的には全ての{@link INyARRgbRaster}を実装したクラスを処理できますが、次の3種類のバッファを持つものを推奨します。\r
44  * <ul>\r
45  * <li>{@link NyARBufferType#INT1D_X8R8G8B8_32}\r
46  * <li>{@link NyARBufferType#BYTE1D_B8G8R8_24}\r
47  * <li>{@link NyARBufferType#BYTE1D_R8G8B8_24}\r
48  * </ul>\r
49  * </p>\r
50  * <p>出力ラスタについて\r
51  * 基本的には全ての{@link NyARBufferType.INT1D_X8R8G8B8_32}形式のバッファを持つラスタを使用してください。\r
52  * 他の形式でも動作しますが、低速な場合があります。\r
53  * </p>\r
54  * <p>高速化について - \r
55  * 入力ラスタ形式が、{@link NyARBufferType#INT1D_X8R8G8B8_32},{@link NyARBufferType#BYTE1D_B8G8R8_24)\r
56  * ,{@link NyARBufferType#BYTE1D_R8G8B8_24}のものについては、他の形式よりも高速に動作します。\r
57  * また、出力ラスタ形式が、{@link NyARBufferType#INT1D_X8R8G8B8_32}の物については、単体サンプリングモードの時のみ、さらに高速に動作します。\r
58  * 他の形式のラスタでは、以上のものよりも低速転送で対応します。\r
59  * <p>メモ-\r
60  * この関数は、1倍の時はNyARColorPatt_Perspective,\r
61  * n倍の時はNyARColorPatt_Perspective_O2の関数を元に作ってます。\r
62  * </p>\r
63  */\r
64 public class NyARPerspectiveRasterReader\r
65 {\r
66         /** 射影変換パラメータ生成器*/\r
67         protected NyARPerspectiveParamGenerator _perspective_gen;\r
68         private static final int LOCAL_LT=1;\r
69         /** 射影変換パラメータの記憶配列*/\r
70         protected final double[] __pickFromRaster_cpara=new double[8];\r
71         private IPickupRasterImpl _picker;      \r
72         private void initializeInstance(int i_buffer_type)\r
73         {\r
74                 //新しいモードに対応したら書いてね。\r
75                 switch(i_buffer_type){\r
76                 case NyARBufferType.BYTE1D_B8G8R8X8_32:\r
77                         this._picker=new PPickup_Impl_BYTE1D_B8G8R8X8_32();\r
78                         break;\r
79                 case NyARBufferType.BYTE1D_B8G8R8_24:\r
80                         this._picker=new PPickup_Impl_BYTE1D_B8G8R8_24();\r
81                         break;\r
82                 case NyARBufferType.BYTE1D_R8G8B8_24:\r
83                         this._picker=new PPickup_Impl_BYTE1D_R8G8B8_24();\r
84                         break;\r
85                 default:\r
86                         this._picker=new PPickup_Impl_AnyRaster();\r
87                         //低速インタフェイス警告。必要に応じて、高速取得系を実装してね\r
88 //                      System.out.println("NyARToolKit Warning:"+this.getClass().getName()+":Low speed interface.");\r
89                         break;\r
90                 }\r
91                 this._perspective_gen=new NyARPerspectiveParamGenerator_O1(LOCAL_LT,LOCAL_LT);\r
92                 return;         \r
93         }\r
94         /**\r
95          * コンストラクタです。\r
96          * このコンストラクタで作成したインスタンスは、入力ラスタタイプに依存しませんが低速です。\r
97          * 入力画像の画素形式が既知の場合は、もう一方のコンストラクタを使用してください。\r
98          */\r
99         public NyARPerspectiveRasterReader()\r
100         {\r
101                 initializeInstance(NyARBufferType.NULL_ALLZERO);\r
102                 return;\r
103         }\r
104         /**\r
105          * コンストラクタです。入力ラスタの形式を制限してインスタンスを作成します。\r
106          * @param i_input_raster_type\r
107          * {@link #read4Point}へ入力するラスタの画素形式。値については、クラスの説明を参照してください。\r
108          */\r
109         public NyARPerspectiveRasterReader(int i_input_raster_type)\r
110         {\r
111                 //入力制限\r
112                 this.initializeInstance(i_input_raster_type);\r
113                 return;\r
114         }\r
115 \r
116         /**\r
117          * この関数は、入力ラスタの4頂点(i_vertexs)でかこまれた領域の画像を射影変換して、o_outへ格納します。\r
118          * @param i_in_raster\r
119          * このラスタの形式は、コンストラクタで制限したものと一致している必要があります。(制限した場合のみ)\r
120          * @param i_vertex\r
121          * 4頂点を格納した配列です。\r
122          * @param i_edge_x\r
123          * X方向のエッジ割合です。0-99の数値を指定します。\r
124          * @param i_edge_y\r
125          * Y方向のエッジ割合です。0-99の数値を指定します。\r
126          * @param i_resolution\r
127          * 出力の1ピクセルあたりのサンプリング数を指定します。例えば2を指定すると、出力1ピクセルあたり4ピクセルをサンプリングします。\r
128          * @param o_out\r
129          * 出力先のラスタです。\r
130          * @return\r
131          * パターンの取得に成功すると、trueを返します。\r
132          * @throws NyARException\r
133          */\r
134         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\r
135         {\r
136                 NyARIntSize out_size=o_out.getSize();\r
137                 int xe=out_size.w*i_edge_x/50;\r
138                 int ye=out_size.h*i_edge_y/50;\r
139 \r
140                 //サンプリング解像度で分岐\r
141                 if(i_resolution==1){\r
142                         if (!this._perspective_gen.getParam((xe*2+out_size.w),(ye*2+out_size.h),i_vertex, this.__pickFromRaster_cpara)) {\r
143                                 return false;\r
144                         }\r
145                         this._picker.onePixel(xe+LOCAL_LT,ye+LOCAL_LT,this.__pickFromRaster_cpara,i_in_raster,o_out);\r
146                 }else{\r
147                         if (!this._perspective_gen.getParam((xe*2+out_size.w)*i_resolution,(ye*2+out_size.h)*i_resolution,i_vertex, this.__pickFromRaster_cpara)) {\r
148                                 return false;\r
149                         }\r
150                         this._picker.multiPixel(xe*i_resolution+LOCAL_LT,ye*i_resolution+LOCAL_LT,this.__pickFromRaster_cpara,i_resolution,i_in_raster,o_out);\r
151                 }\r
152                 return true;\r
153         }\r
154         /**\r
155          * この関数は、入力ラスタの4頂点(i_vertexs)でかこまれた領域の画像を射影変換して、o_outへ格納します。\r
156          * 2番目の引数型だけが、{@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}と異なります。\r
157          * @param i_in_raster\r
158          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
159          * @param i_vertex\r
160          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
161          * @param i_edge_x\r
162          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
163          * @param i_edge_y\r
164          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
165          * @param i_resolution\r
166          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
167          * @param o_out\r
168          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
169          * @return\r
170          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
171          * @throws NyARException\r
172          */\r
173         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\r
174         {\r
175                 NyARIntSize out_size=o_out.getSize();\r
176                 int xe=out_size.w*i_edge_x/50;\r
177                 int ye=out_size.h*i_edge_y/50;\r
178 \r
179                 //サンプリング解像度で分岐\r
180                 if(i_resolution==1){\r
181                         if (!this._perspective_gen.getParam((xe*2+out_size.w),(ye*2+out_size.h),i_vertex, this.__pickFromRaster_cpara)) {\r
182                                 return false;\r
183                         }\r
184                         this._picker.onePixel(xe+LOCAL_LT,ye+LOCAL_LT,this.__pickFromRaster_cpara,i_in_raster,o_out);\r
185                 }else{\r
186                         if (!this._perspective_gen.getParam((xe*2+out_size.w)*i_resolution,(ye*2+out_size.h)*i_resolution,i_vertex, this.__pickFromRaster_cpara)) {\r
187                                 return false;\r
188                         }\r
189                         this._picker.multiPixel(xe*i_resolution+LOCAL_LT,ye*i_resolution+LOCAL_LT,this.__pickFromRaster_cpara,i_resolution,i_in_raster,o_out);\r
190                 }\r
191                 return true;\r
192         }\r
193         /**\r
194          * この関数は、入力ラスタの4頂点(i_vertexs)でかこまれた領域の画像を射影変換して、o_outへ格納します。\r
195          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}と比較して、\r
196          * 4頂点を直値で指定する違いがあります。\r
197          * @param i_in_raster\r
198          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
199          * @param i_x1\r
200          * 1番目の頂点の座標\r
201          * @param i_y1\r
202          * 1番目の頂点の座標\r
203          * @param i_x2\r
204          * 2番目の頂点の座標\r
205          * @param i_y2\r
206          * 2番目の頂点の座標\r
207          * @param i_x3\r
208          * 3番目の頂点の座標\r
209          * @param i_y3\r
210          * 3番目の頂点の座標\r
211          * @param i_x4\r
212          * 4番目の頂点の座標\r
213          * @param i_y4\r
214          * 4番目の頂点の座標\r
215          * @param i_edge_x\r
216          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
217          * @param i_edge_y\r
218          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
219          * @param i_resolution\r
220          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
221          * @param o_out\r
222          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
223          * @return\r
224          * {@link #read4Point(INyARRgbRaster, NyARDoublePoint2d[], int, int, int, INyARRgbRaster)}を参照。\r
225          * @throws NyARException\r
226          */\r
227         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\r
228         {\r
229                 NyARIntSize out_size=o_out.getSize();\r
230                 int xe=out_size.w*i_edge_x/50;\r
231                 int ye=out_size.h*i_edge_y/50;\r
232 \r
233                 //サンプリング解像度で分岐\r
234                 if(i_resolution==1){\r
235                         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)) {\r
236                                 return false;\r
237                         }\r
238                         this._picker.onePixel(xe+LOCAL_LT,ye+LOCAL_LT,this.__pickFromRaster_cpara,i_in_raster,o_out);\r
239                 }else{\r
240                         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)) {\r
241                                 return false;\r
242                         }\r
243                         this._picker.multiPixel(xe*i_resolution+LOCAL_LT,ye*i_resolution+LOCAL_LT,this.__pickFromRaster_cpara,i_resolution,i_in_raster,o_out);\r
244                 }\r
245                 return true;\r
246         }       \r
247 }\r
248 \r
249 \r
250 //\r
251 //ここから先は入力画像毎のラスタドライバ\r
252 //\r
253 \r
254 /** 画素形式毎のドライバ定義*/\r
255 interface IPickupRasterImpl\r
256 {\r
257         public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException;\r
258         public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException;\r
259 }\r
260 \r
261 /** BYTE1D_R8G8B8_24形式のドライバ*/\r
262 final class PPickup_Impl_BYTE1D_R8G8B8_24 implements IPickupRasterImpl\r
263 {\r
264         public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
265         {\r
266                 assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));\r
267                 //出力形式による分岐\r
268                 switch(o_out.getBufferType())\r
269                 {\r
270                 case NyARBufferType.INT1D_X8R8G8B8_32:\r
271                         onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
272                         break;\r
273                 default:\r
274                         onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
275                         break;\r
276                 }\r
277                 return;\r
278         }\r
279         public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
280         {\r
281                 assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_R8G8B8_24));\r
282                 //出力形式による分岐(分解能が高い時は大した差が出ないから、ANYだけ。)\r
283                 multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
284                 return;         \r
285         }\r
286         \r
287         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\r
288         {\r
289                 assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
290                 int[] pat_data=(int[])o_out.getBuffer();\r
291                 //ピクセルリーダーを取得\r
292                 double cp0=cpara[0];\r
293                 double cp3=cpara[3];\r
294                 double cp6=cpara[6];\r
295                 double cp1=cpara[1];\r
296                 double cp4=cpara[4];\r
297                 double cp7=cpara[7];\r
298                 \r
299                 int out_w=o_out.getWidth();\r
300                 int out_h=o_out.getHeight();\r
301                 double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
302                 double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
303                 double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
304                 int r,g,b;\r
305                 int p=0;\r
306                 for(int iy=0;iy<out_h;iy++){\r
307                         //解像度分の点を取る。\r
308                         double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
309                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
310                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
311                         \r
312                         for(int ix=0;ix<out_w;ix++){\r
313                                 //1ピクセルを作成\r
314                                 final double d=1/(cp7_cy_1_cp6_cx);\r
315                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
316                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
317                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
318                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
319                                                 \r
320                                 final int bp = (x + y * in_w) * 3;\r
321                                 r=(i_in_buf[bp + 0] & 0xff);\r
322                                 g=(i_in_buf[bp + 1] & 0xff);\r
323                                 b=(i_in_buf[bp + 2] & 0xff);\r
324                                 cp7_cy_1_cp6_cx+=cp6;\r
325                                 cp1_cy_cp2_cp0_cx+=cp0;\r
326                                 cp4_cy_cp5_cp3_cx+=cp3;\r
327                                 pat_data[p]=(r<<16)|(g<<8)|((b&0xff));\r
328                                 p++;\r
329                         }\r
330                         cp7_cy_1+=cp7;\r
331                         cp1_cy_cp2+=cp1;\r
332                         cp4_cy_cp5+=cp4;\r
333                 }\r
334                 return;\r
335         }\r
336         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\r
337         {\r
338                 INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
339 \r
340                 //ピクセルリーダーを取得\r
341                 double cp0=cpara[0];\r
342                 double cp3=cpara[3];\r
343                 double cp6=cpara[6];\r
344                 double cp1=cpara[1];\r
345                 double cp4=cpara[4];\r
346                 double cp7=cpara[7];\r
347                 \r
348                 int out_w=o_out.getWidth();\r
349                 int out_h=o_out.getHeight();\r
350                 double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
351                 double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
352                 double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
353                 int r,g,b;\r
354                 for(int iy=0;iy<out_h;iy++){\r
355                         //解像度分の点を取る。\r
356                         double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
357                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
358                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
359                         \r
360                         for(int ix=0;ix<out_w;ix++){\r
361                                 //1ピクセルを作成\r
362                                 final double d=1/(cp7_cy_1_cp6_cx);\r
363                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
364                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
365                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
366                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
367                                                 \r
368                                 final int bp = (x + y * in_w) * 3;\r
369                                 r=(i_in_buf[bp + 0] & 0xff);\r
370                                 g=(i_in_buf[bp + 1] & 0xff);\r
371                                 b=(i_in_buf[bp + 2] & 0xff);\r
372                                 cp7_cy_1_cp6_cx+=cp6;\r
373                                 cp1_cy_cp2_cp0_cx+=cp0;\r
374                                 cp4_cy_cp5_cp3_cx+=cp3;\r
375 \r
376                                 out_reader.setPixel(ix,iy,r,g,b);\r
377                         }\r
378                         cp7_cy_1+=cp7;\r
379                         cp1_cy_cp2+=cp1;\r
380                         cp4_cy_cp5+=cp4;\r
381                 }\r
382                 return;\r
383         }\r
384         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\r
385         {\r
386                 final int res_pix=i_resolution*i_resolution;\r
387 \r
388                 INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
389 \r
390                 //ピクセルリーダーを取得\r
391                 double cp0=cpara[0];\r
392                 double cp3=cpara[3];\r
393                 double cp6=cpara[6];\r
394                 double cp1=cpara[1];\r
395                 double cp4=cpara[4];\r
396                 double cp7=cpara[7];\r
397                 double cp2=cpara[2];\r
398                 double cp5=cpara[5];\r
399                 \r
400                 int out_w=o_out.getWidth();\r
401                 int out_h=o_out.getHeight();\r
402                 for(int iy=out_h-1;iy>=0;iy--){\r
403                         //解像度分の点を取る。\r
404                         for(int ix=out_w-1;ix>=0;ix--){\r
405                                 int r,g,b;\r
406                                 r=g=b=0;\r
407                                 int cy=pk_t+iy*i_resolution;\r
408                                 int cx=pk_l+ix*i_resolution;\r
409                                 double cp7_cy_1_cp6_cx_b  =cp7*cy+1.0+cp6*cx;\r
410                                 double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;\r
411                                 double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;\r
412                                 for(int i2y=i_resolution-1;i2y>=0;i2y--){\r
413                                         double cp7_cy_1_cp6_cx  =cp7_cy_1_cp6_cx_b;\r
414                                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;\r
415                                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;\r
416                                         for(int i2x=i_resolution-1;i2x>=0;i2x--){\r
417                                                 //1ピクセルを作成\r
418                                                 final double d=1/(cp7_cy_1_cp6_cx);\r
419                                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
420                                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
421                                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
422                                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
423                                                 \r
424                                                 final int bp = (x + y * in_w) * 3;\r
425                                                 r+=(i_in_buf[bp + 0] & 0xff);\r
426                                                 g+=(i_in_buf[bp + 1] & 0xff);\r
427                                                 b+=(i_in_buf[bp + 2] & 0xff);\r
428                                                 cp7_cy_1_cp6_cx+=cp6;\r
429                                                 cp1_cy_cp2_cp0_cx+=cp0;\r
430                                                 cp4_cy_cp5_cp3_cx+=cp3;\r
431                                         }\r
432                                         cp7_cy_1_cp6_cx_b+=cp7;\r
433                                         cp1_cy_cp2_cp0_cx_b+=cp1;\r
434                                         cp4_cy_cp5_cp3_cx_b+=cp4;\r
435                                 }\r
436                                 out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);\r
437                         }\r
438                 }\r
439                 return;\r
440         }\r
441 }\r
442 \r
443 \r
444 \r
445 \r
446 \r
447 /** BYTE1D_B8G8R8_24形式のドライバ*/\r
448 final class PPickup_Impl_BYTE1D_B8G8R8_24 implements IPickupRasterImpl\r
449 {\r
450         public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
451         {\r
452                 assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24));\r
453                 //出力形式による分岐\r
454                 switch(o_out.getBufferType())\r
455                 {\r
456                 case NyARBufferType.INT1D_X8R8G8B8_32:\r
457                         onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
458                         break;\r
459                 default:\r
460                         onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
461                         break;\r
462                 }\r
463                 return;\r
464         }\r
465         public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
466         {\r
467                 assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8_24));\r
468                 //出力形式による分岐(分解能が高い時は大した差が出ないから、ANYだけ。)\r
469                 multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
470                 return;         \r
471         }\r
472         \r
473         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\r
474         {\r
475                 assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
476                 int[] pat_data=(int[])o_out.getBuffer();\r
477                 //ピクセルリーダーを取得\r
478                 double cp0=cpara[0];\r
479                 double cp3=cpara[3];\r
480                 double cp6=cpara[6];\r
481                 double cp1=cpara[1];\r
482                 double cp4=cpara[4];\r
483                 double cp7=cpara[7];\r
484                 \r
485                 int out_w=o_out.getWidth();\r
486                 int out_h=o_out.getHeight();\r
487                 double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
488                 double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
489                 double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
490                 int r,g,b;\r
491                 int p=0;\r
492                 for(int iy=0;iy<out_h;iy++){\r
493                         //解像度分の点を取る。\r
494                         double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
495                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
496                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
497                         \r
498                         for(int ix=0;ix<out_w;ix++){\r
499                                 //1ピクセルを作成\r
500                                 final double d=1/(cp7_cy_1_cp6_cx);\r
501                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
502                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
503                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
504                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
505                                                 \r
506                                 final int bp = (x + y * in_w) * 3;\r
507                                 r=(i_in_buf[bp + 2] & 0xff);\r
508                                 g=(i_in_buf[bp + 1] & 0xff);\r
509                                 b=(i_in_buf[bp + 0] & 0xff);\r
510                                 cp7_cy_1_cp6_cx+=cp6;\r
511                                 cp1_cy_cp2_cp0_cx+=cp0;\r
512                                 cp4_cy_cp5_cp3_cx+=cp3;\r
513                                 pat_data[p]=(r<<16)|(g<<8)|((b&0xff));\r
514                                 p++;\r
515                         }\r
516                         cp7_cy_1+=cp7;\r
517                         cp1_cy_cp2+=cp1;\r
518                         cp4_cy_cp5+=cp4;\r
519                 }\r
520                 return;\r
521         }\r
522         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\r
523         {\r
524                 INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
525 \r
526                 //ピクセルリーダーを取得\r
527                 double cp0=cpara[0];\r
528                 double cp3=cpara[3];\r
529                 double cp6=cpara[6];\r
530                 double cp1=cpara[1];\r
531                 double cp4=cpara[4];\r
532                 double cp7=cpara[7];\r
533                 \r
534                 int out_w=o_out.getWidth();\r
535                 int out_h=o_out.getHeight();\r
536                 double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
537                 double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
538                 double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
539                 int r,g,b;\r
540                 for(int iy=0;iy<out_h;iy++){\r
541                         //解像度分の点を取る。\r
542                         double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
543                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
544                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
545                         \r
546                         for(int ix=0;ix<out_w;ix++){\r
547                                 //1ピクセルを作成\r
548                                 final double d=1/(cp7_cy_1_cp6_cx);\r
549                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
550                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
551                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
552                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
553                                                 \r
554                                 final int bp = (x + y * in_w) * 3;\r
555                                 r=(i_in_buf[bp + 2] & 0xff);\r
556                                 g=(i_in_buf[bp + 1] & 0xff);\r
557                                 b=(i_in_buf[bp + 0] & 0xff);\r
558                                 cp7_cy_1_cp6_cx+=cp6;\r
559                                 cp1_cy_cp2_cp0_cx+=cp0;\r
560                                 cp4_cy_cp5_cp3_cx+=cp3;\r
561 \r
562                                 out_reader.setPixel(ix,iy,r,g,b);\r
563                         }\r
564                         cp7_cy_1+=cp7;\r
565                         cp1_cy_cp2+=cp1;\r
566                         cp4_cy_cp5+=cp4;\r
567                 }\r
568                 return;\r
569         }\r
570         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\r
571         {\r
572                 final int res_pix=i_resolution*i_resolution;\r
573 \r
574                 INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
575 \r
576                 //ピクセルリーダーを取得\r
577                 double cp0=cpara[0];\r
578                 double cp3=cpara[3];\r
579                 double cp6=cpara[6];\r
580                 double cp1=cpara[1];\r
581                 double cp4=cpara[4];\r
582                 double cp7=cpara[7];\r
583                 double cp2=cpara[2];\r
584                 double cp5=cpara[5];\r
585                 \r
586                 int out_w=o_out.getWidth();\r
587                 int out_h=o_out.getHeight();\r
588                 for(int iy=out_h-1;iy>=0;iy--){\r
589                         //解像度分の点を取る。\r
590                         for(int ix=out_w-1;ix>=0;ix--){\r
591                                 int r,g,b;\r
592                                 r=g=b=0;\r
593                                 int cy=pk_t+iy*i_resolution;\r
594                                 int cx=pk_l+ix*i_resolution;\r
595                                 double cp7_cy_1_cp6_cx_b  =cp7*cy+1.0+cp6*cx;\r
596                                 double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;\r
597                                 double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;\r
598                                 for(int i2y=i_resolution-1;i2y>=0;i2y--){\r
599                                         double cp7_cy_1_cp6_cx  =cp7_cy_1_cp6_cx_b;\r
600                                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;\r
601                                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;\r
602                                         for(int i2x=i_resolution-1;i2x>=0;i2x--){\r
603                                                 //1ピクセルを作成\r
604                                                 final double d=1/(cp7_cy_1_cp6_cx);\r
605                                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
606                                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
607                                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
608                                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
609                                                 \r
610                                                 final int bp = (x + y * in_w) * 3;\r
611                                                 r+=(i_in_buf[bp + 2] & 0xff);\r
612                                                 g+=(i_in_buf[bp + 1] & 0xff);\r
613                                                 b+=(i_in_buf[bp + 0] & 0xff);\r
614                                                 cp7_cy_1_cp6_cx+=cp6;\r
615                                                 cp1_cy_cp2_cp0_cx+=cp0;\r
616                                                 cp4_cy_cp5_cp3_cx+=cp3;\r
617                                         }\r
618                                         cp7_cy_1_cp6_cx_b+=cp7;\r
619                                         cp1_cy_cp2_cp0_cx_b+=cp1;\r
620                                         cp4_cy_cp5_cp3_cx_b+=cp4;\r
621                                 }\r
622                                 out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);\r
623                         }\r
624                 }\r
625                 return;\r
626         }\r
627 }\r
628 \r
629 \r
630 \r
631 /** BYTE1D_B8G8R8X8_32形式のドライバ*/\r
632 final class PPickup_Impl_BYTE1D_B8G8R8X8_32 implements IPickupRasterImpl\r
633 {\r
634         public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
635         {\r
636                 assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8X8_32));\r
637                 //出力形式による分岐\r
638                 switch(o_out.getBufferType())\r
639                 {\r
640                 case NyARBufferType.INT1D_X8R8G8B8_32:\r
641                         onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
642                         break;\r
643                 default:\r
644                         onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
645                         break;\r
646                 }\r
647                 return;\r
648         }\r
649         public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
650         {\r
651                 assert(i_in_raster.isEqualBufferType(NyARBufferType.BYTE1D_B8G8R8X8_32));\r
652                 //出力形式による分岐(分解能が高い時は大した差が出ないから、ANYだけ。)\r
653                 multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,(byte[])i_in_raster.getBuffer(),o_out);\r
654                 return;         \r
655         }\r
656         \r
657         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\r
658         {\r
659                 assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
660                 int[] pat_data=(int[])o_out.getBuffer();\r
661                 //ピクセルリーダーを取得\r
662                 double cp0=cpara[0];\r
663                 double cp3=cpara[3];\r
664                 double cp6=cpara[6];\r
665                 double cp1=cpara[1];\r
666                 double cp4=cpara[4];\r
667                 double cp7=cpara[7];\r
668                 \r
669                 int out_w=o_out.getWidth();\r
670                 int out_h=o_out.getHeight();\r
671                 double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
672                 double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
673                 double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
674                 int r,g,b;\r
675                 int p=0;\r
676                 for(int iy=0;iy<out_h;iy++){\r
677                         //解像度分の点を取る。\r
678                         double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
679                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
680                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
681                         \r
682                         for(int ix=0;ix<out_w;ix++){\r
683                                 //1ピクセルを作成\r
684                                 final double d=1/(cp7_cy_1_cp6_cx);\r
685                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
686                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
687                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
688                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
689                                                 \r
690                                 final int bp = (x + y * in_w) * 4;\r
691                                 r=(i_in_buf[bp + 2] & 0xff);\r
692                                 g=(i_in_buf[bp + 1] & 0xff);\r
693                                 b=(i_in_buf[bp + 0] & 0xff);\r
694                                 cp7_cy_1_cp6_cx+=cp6;\r
695                                 cp1_cy_cp2_cp0_cx+=cp0;\r
696                                 cp4_cy_cp5_cp3_cx+=cp3;\r
697                                 pat_data[p]=(r<<16)|(g<<8)|((b&0xff));\r
698                                 p++;\r
699                         }\r
700                         cp7_cy_1+=cp7;\r
701                         cp1_cy_cp2+=cp1;\r
702                         cp4_cy_cp5+=cp4;\r
703                 }\r
704                 return;\r
705         }\r
706         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\r
707         {\r
708                 INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
709 \r
710                 //ピクセルリーダーを取得\r
711                 double cp0=cpara[0];\r
712                 double cp3=cpara[3];\r
713                 double cp6=cpara[6];\r
714                 double cp1=cpara[1];\r
715                 double cp4=cpara[4];\r
716                 double cp7=cpara[7];\r
717                 \r
718                 int out_w=o_out.getWidth();\r
719                 int out_h=o_out.getHeight();\r
720                 double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
721                 double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
722                 double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
723                 int r,g,b;\r
724                 for(int iy=0;iy<out_h;iy++){\r
725                         //解像度分の点を取る。\r
726                         double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
727                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
728                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
729                         \r
730                         for(int ix=0;ix<out_w;ix++){\r
731                                 //1ピクセルを作成\r
732                                 final double d=1/(cp7_cy_1_cp6_cx);\r
733                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
734                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
735                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
736                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
737                                                 \r
738                                 final int bp = (x + y * in_w) * 4;\r
739                                 r=(i_in_buf[bp + 2] & 0xff);\r
740                                 g=(i_in_buf[bp + 1] & 0xff);\r
741                                 b=(i_in_buf[bp + 0] & 0xff);\r
742                                 cp7_cy_1_cp6_cx+=cp6;\r
743                                 cp1_cy_cp2_cp0_cx+=cp0;\r
744                                 cp4_cy_cp5_cp3_cx+=cp3;\r
745 \r
746                                 out_reader.setPixel(ix,iy,r,g,b);\r
747                         }\r
748                         cp7_cy_1+=cp7;\r
749                         cp1_cy_cp2+=cp1;\r
750                         cp4_cy_cp5+=cp4;\r
751                 }\r
752                 return;\r
753         }\r
754 \r
755         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\r
756         {\r
757                 final int res_pix=i_resolution*i_resolution;\r
758 \r
759                 INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
760 \r
761                 //ピクセルリーダーを取得\r
762                 double cp0=cpara[0];\r
763                 double cp3=cpara[3];\r
764                 double cp6=cpara[6];\r
765                 double cp1=cpara[1];\r
766                 double cp4=cpara[4];\r
767                 double cp7=cpara[7];\r
768                 double cp2=cpara[2];\r
769                 double cp5=cpara[5];\r
770                 \r
771                 int out_w=o_out.getWidth();\r
772                 int out_h=o_out.getHeight();\r
773                 for(int iy=out_h-1;iy>=0;iy--){\r
774                         //解像度分の点を取る。\r
775                         for(int ix=out_w-1;ix>=0;ix--){\r
776                                 int r,g,b;\r
777                                 r=g=b=0;\r
778                                 int cy=pk_t+iy*i_resolution;\r
779                                 int cx=pk_l+ix*i_resolution;\r
780                                 double cp7_cy_1_cp6_cx_b  =cp7*cy+1.0+cp6*cx;\r
781                                 double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;\r
782                                 double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;\r
783                                 for(int i2y=i_resolution-1;i2y>=0;i2y--){\r
784                                         double cp7_cy_1_cp6_cx  =cp7_cy_1_cp6_cx_b;\r
785                                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;\r
786                                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;\r
787                                         for(int i2x=i_resolution-1;i2x>=0;i2x--){\r
788                                                 //1ピクセルを作成\r
789                                                 final double d=1/(cp7_cy_1_cp6_cx);\r
790                                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
791                                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
792                                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
793                                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
794                                                 \r
795                                                 final int bp = (x + y * in_w) * 4;\r
796                                                 r+=(i_in_buf[bp + 2] & 0xff);\r
797                                                 g+=(i_in_buf[bp + 1] & 0xff);\r
798                                                 b+=(i_in_buf[bp + 0] & 0xff);\r
799                                                 cp7_cy_1_cp6_cx+=cp6;\r
800                                                 cp1_cy_cp2_cp0_cx+=cp0;\r
801                                                 cp4_cy_cp5_cp3_cx+=cp3;\r
802                                         }\r
803                                         cp7_cy_1_cp6_cx_b+=cp7;\r
804                                         cp1_cy_cp2_cp0_cx_b+=cp1;\r
805                                         cp4_cy_cp5_cp3_cx_b+=cp4;\r
806                                 }\r
807                                 out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);\r
808                         }\r
809                 }\r
810                 return;\r
811         }\r
812 }\r
813 \r
814 /**\r
815  * 全種類のNyARRasterを入力できるクラス\r
816  */\r
817 final class PPickup_Impl_AnyRaster implements IPickupRasterImpl\r
818 {\r
819         private final int[] __pickFromRaster_rgb_tmp = new int[3];\r
820         public void onePixel(int pk_l,int pk_t,double[] cpara,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
821         {\r
822                 //出力形式による分岐\r
823                 switch(o_out.getBufferType())\r
824                 {\r
825                 case NyARBufferType.INT1D_X8R8G8B8_32:\r
826                         onePixel_INT1D_X8R8G8B8_32(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,i_in_raster.getRgbPixelReader(),o_out);\r
827                         break;\r
828                 default:\r
829                         onePixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),cpara,i_in_raster.getRgbPixelReader(),o_out);\r
830                         break;\r
831                 }\r
832                 return;\r
833         }\r
834         public void multiPixel(int pk_l,int pk_t,double[] cpara,int i_resolution,INyARRgbRaster i_in_raster,INyARRgbRaster o_out)throws NyARException\r
835         {\r
836                 //出力形式による分岐\r
837                 switch(o_out.getBufferType())\r
838                 {\r
839                 case NyARBufferType.INT1D_X8R8G8B8_32:\r
840                         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);\r
841                         break;\r
842                 default:\r
843                         multiPixel_ANY(pk_l,pk_t,i_in_raster.getWidth(),i_in_raster.getHeight(),i_resolution,cpara,i_in_raster.getRgbPixelReader(),o_out);\r
844                         break;\r
845                 }\r
846                 return;         \r
847         }\r
848         \r
849         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\r
850         {\r
851                 assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
852                 final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
853                 int[] pat_data=(int[])o_out.getBuffer();\r
854 \r
855                 //ピクセルリーダーを取得\r
856                 double cp0=cpara[0];\r
857                 double cp3=cpara[3];\r
858                 double cp6=cpara[6];\r
859                 double cp1=cpara[1];\r
860                 double cp4=cpara[4];\r
861                 double cp7=cpara[7];\r
862                 \r
863                 int out_w=o_out.getWidth();\r
864                 int out_h=o_out.getHeight();\r
865                 double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
866                 double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
867                 double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
868                 int p=0;\r
869                 for(int iy=out_h-1;iy>=0;iy--){\r
870                         //解像度分の点を取る。\r
871                         double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
872                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
873                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
874                         \r
875                         for(int ix=out_w-1;ix>=0;ix--){\r
876                                 //1ピクセルを作成\r
877                                 final double d=1/(cp7_cy_1_cp6_cx);\r
878                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
879                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
880                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
881                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
882                                                 \r
883                                 i_in_reader.getPixel(x, y, rgb_tmp);\r
884                                 cp7_cy_1_cp6_cx+=cp6;\r
885                                 cp1_cy_cp2_cp0_cx+=cp0;\r
886                                 cp4_cy_cp5_cp3_cx+=cp3;\r
887 \r
888                                 pat_data[p]=(rgb_tmp[0]<<16)|(rgb_tmp[1]<<8)|((rgb_tmp[2]&0xff));\r
889                                 p++;\r
890                         }\r
891                         cp7_cy_1+=cp7;\r
892                         cp1_cy_cp2+=cp1;\r
893                         cp4_cy_cp5+=cp4;\r
894                 }\r
895                 return;\r
896         }\r
897         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\r
898         {\r
899                 final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
900                 INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
901 \r
902                 //ピクセルリーダーを取得\r
903                 double cp0=cpara[0];\r
904                 double cp3=cpara[3];\r
905                 double cp6=cpara[6];\r
906                 double cp1=cpara[1];\r
907                 double cp4=cpara[4];\r
908                 double cp7=cpara[7];\r
909                 \r
910                 int out_w=o_out.getWidth();\r
911                 int out_h=o_out.getHeight();\r
912                 double cp7_cy_1  =cp7*pk_t+1.0+cp6*pk_l;\r
913                 double cp1_cy_cp2=cp1*pk_t+cpara[2]+cp0*pk_l;\r
914                 double cp4_cy_cp5=cp4*pk_t+cpara[5]+cp3*pk_l;\r
915                 \r
916                 for(int iy=0;iy<out_h;iy++){\r
917                         //解像度分の点を取る。\r
918                         double cp7_cy_1_cp6_cx  =cp7_cy_1;\r
919                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2;\r
920                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5;\r
921                         \r
922                         for(int ix=0;ix<out_w;ix++){\r
923                                 //1ピクセルを作成\r
924                                 final double d=1/(cp7_cy_1_cp6_cx);\r
925                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
926                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
927                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
928                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
929                                                 \r
930                                 i_in_reader.getPixel(x, y, rgb_tmp);\r
931                                 cp7_cy_1_cp6_cx+=cp6;\r
932                                 cp1_cy_cp2_cp0_cx+=cp0;\r
933                                 cp4_cy_cp5_cp3_cx+=cp3;\r
934 \r
935                                 out_reader.setPixel(ix,iy,rgb_tmp);\r
936                         }\r
937                         cp7_cy_1+=cp7;\r
938                         cp1_cy_cp2+=cp1;\r
939                         cp4_cy_cp5+=cp4;\r
940                 }\r
941                 return;\r
942         }\r
943 \r
944         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\r
945         {\r
946                 assert(o_out.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));\r
947                 final int res_pix=i_resolution*i_resolution;\r
948 \r
949                 final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
950                 int[] pat_data=(int[])o_out.getBuffer();\r
951 \r
952                 //ピクセルリーダーを取得\r
953                 double cp0=cpara[0];\r
954                 double cp3=cpara[3];\r
955                 double cp6=cpara[6];\r
956                 double cp1=cpara[1];\r
957                 double cp4=cpara[4];\r
958                 double cp7=cpara[7];\r
959                 double cp2=cpara[2];\r
960                 double cp5=cpara[5];\r
961                 \r
962                 int out_w=o_out.getWidth();\r
963                 int out_h=o_out.getHeight();\r
964                 int p=(out_w*out_h-1);\r
965                 for(int iy=out_h-1;iy>=0;iy--){\r
966                         //解像度分の点を取る。\r
967                         for(int ix=out_w-1;ix>=0;ix--){\r
968                                 int r,g,b;\r
969                                 r=g=b=0;\r
970                                 int cy=pk_t+iy*i_resolution;\r
971                                 int cx=pk_l+ix*i_resolution;\r
972                                 double cp7_cy_1_cp6_cx_b  =cp7*cy+1.0+cp6*cx;\r
973                                 double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;\r
974                                 double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;\r
975                                 for(int i2y=i_resolution-1;i2y>=0;i2y--){\r
976                                         double cp7_cy_1_cp6_cx  =cp7_cy_1_cp6_cx_b;\r
977                                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;\r
978                                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;\r
979                                         for(int i2x=i_resolution-1;i2x>=0;i2x--){\r
980                                                 //1ピクセルを作成\r
981                                                 final double d=1/(cp7_cy_1_cp6_cx);\r
982                                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
983                                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
984                                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
985                                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
986                                                 \r
987                                                 i_in_reader.getPixel(x, y, rgb_tmp);\r
988                                                 r+=rgb_tmp[0];\r
989                                                 g+=rgb_tmp[1];\r
990                                                 b+=rgb_tmp[2];\r
991                                                 cp7_cy_1_cp6_cx+=cp6;\r
992                                                 cp1_cy_cp2_cp0_cx+=cp0;\r
993                                                 cp4_cy_cp5_cp3_cx+=cp3;\r
994                                         }\r
995                                         cp7_cy_1_cp6_cx_b+=cp7;\r
996                                         cp1_cy_cp2_cp0_cx_b+=cp1;\r
997                                         cp4_cy_cp5_cp3_cx_b+=cp4;\r
998                                 }\r
999                                 r/=res_pix;\r
1000                                 g/=res_pix;\r
1001                                 b/=res_pix;\r
1002                                 pat_data[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));\r
1003                                 p--;\r
1004                         }\r
1005                 }\r
1006                 return;\r
1007         }\r
1008         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\r
1009         {\r
1010                 final int res_pix=i_resolution*i_resolution;\r
1011 \r
1012                 final int[] rgb_tmp = this.__pickFromRaster_rgb_tmp;\r
1013                 INyARRgbPixelReader out_reader=o_out.getRgbPixelReader();\r
1014 \r
1015                 //ピクセルリーダーを取得\r
1016                 double cp0=cpara[0];\r
1017                 double cp3=cpara[3];\r
1018                 double cp6=cpara[6];\r
1019                 double cp1=cpara[1];\r
1020                 double cp4=cpara[4];\r
1021                 double cp7=cpara[7];\r
1022                 double cp2=cpara[2];\r
1023                 double cp5=cpara[5];\r
1024                 \r
1025                 int out_w=o_out.getWidth();\r
1026                 int out_h=o_out.getHeight();\r
1027                 for(int iy=out_h-1;iy>=0;iy--){\r
1028                         //解像度分の点を取る。\r
1029                         for(int ix=out_w-1;ix>=0;ix--){\r
1030                                 int r,g,b;\r
1031                                 r=g=b=0;\r
1032                                 int cy=pk_t+iy*i_resolution;\r
1033                                 int cx=pk_l+ix*i_resolution;\r
1034                                 double cp7_cy_1_cp6_cx_b  =cp7*cy+1.0+cp6*cx;\r
1035                                 double cp1_cy_cp2_cp0_cx_b=cp1*cy+cp2+cp0*cx;\r
1036                                 double cp4_cy_cp5_cp3_cx_b=cp4*cy+cp5+cp3*cx;\r
1037                                 for(int i2y=i_resolution-1;i2y>=0;i2y--){\r
1038                                         double cp7_cy_1_cp6_cx  =cp7_cy_1_cp6_cx_b;\r
1039                                         double cp1_cy_cp2_cp0_cx=cp1_cy_cp2_cp0_cx_b;\r
1040                                         double cp4_cy_cp5_cp3_cx=cp4_cy_cp5_cp3_cx_b;\r
1041                                         for(int i2x=i_resolution-1;i2x>=0;i2x--){\r
1042                                                 //1ピクセルを作成\r
1043                                                 final double d=1/(cp7_cy_1_cp6_cx);\r
1044                                                 int x=(int)((cp1_cy_cp2_cp0_cx)*d);\r
1045                                                 int y=(int)((cp4_cy_cp5_cp3_cx)*d);\r
1046                                                 if(x<0){x=0;}else if(x>=in_w){x=in_w-1;}\r
1047                                                 if(y<0){y=0;}else if(y>=in_h){y=in_h-1;}\r
1048                                                 \r
1049                                                 i_in_reader.getPixel(x, y, rgb_tmp);\r
1050                                                 r+=rgb_tmp[0];\r
1051                                                 g+=rgb_tmp[1];\r
1052                                                 b+=rgb_tmp[2];\r
1053                                                 cp7_cy_1_cp6_cx+=cp6;\r
1054                                                 cp1_cy_cp2_cp0_cx+=cp0;\r
1055                                                 cp4_cy_cp5_cp3_cx+=cp3;\r
1056                                         }\r
1057                                         cp7_cy_1_cp6_cx_b+=cp7;\r
1058                                         cp1_cy_cp2_cp0_cx_b+=cp1;\r
1059                                         cp4_cy_cp5_cp3_cx_b+=cp4;\r
1060                                 }\r
1061                                 out_reader.setPixel(ix,iy,r/res_pix,g/res_pix,b/res_pix);\r
1062                         }\r
1063                 }\r
1064                 return;\r
1065         }       \r
1066 }\r
1067 \r
1068 \r