OSDN Git Service

Merge branch 'git-svn'
[nyartoolkit-and/nyartoolkit-and.git] / tags / 2.5.0 / src.utils / jmf / jp / nyatla / nyartoolkit / jmf / utils / JmfNyARRaster_RGB.java
1 /* \r
2  * PROJECT: NyARToolkit JMF utilities.\r
3  * --------------------------------------------------------------------------------\r
4  * The MIT License\r
5  * Copyright (c) 2008 nyatla\r
6  * airmail(at)ebony.plala.or.jp\r
7  * http://nyatla.jp/nyartoolkit/\r
8  * \r
9  * Permission is hereby granted, free of charge, to any person obtaining a copy\r
10  * of this software and associated documentation files (the "Software"), to deal\r
11  * in the Software without restriction, including without limitation the rights\r
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
13  * copies of the Software, and to permit persons to whom the Software is\r
14  * furnished to do so, subject to the following conditions:\r
15  * The above copyright notice and this permission notice shall be included in\r
16  * all copies or substantial portions of the Software.\r
17  * \r
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
24  * THE SOFTWARE.\r
25  * \r
26  */\r
27 package jp.nyatla.nyartoolkit.jmf.utils;\r
28 \r
29 import javax.media.format.*;\r
30 import javax.media.*;\r
31 import java.awt.Dimension;\r
32 import com.sun.media.codec.video.colorspace.*;\r
33 \r
34 import jp.nyatla.nyartoolkit.NyARException;\r
35 import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
36 import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
37 import jp.nyatla.nyartoolkit.core.raster.*;\r
38 import jp.nyatla.nyartoolkit.core.types.*;\r
39 \r
40 \r
41 \r
42 \r
43 \r
44 /**\r
45  * \r
46  * RGB形式のJMFバッファをラップするNyARRasterです。\r
47  * JMFから得たラスタデータのピクセル並び順を考慮します。\r
48  *\r
49  */\r
50 public class JmfNyARRaster_RGB implements INyARRgbRaster\r
51 {\r
52         private JmfRGB24RasterHolder _holder;\r
53         protected NyARIntSize _size;\r
54 \r
55         /**\r
56          * i_fmtに一致する画素フォーマットのRasterを作成します。\r
57          * このコンストラクタで作成したクラスは、hasBuffer()がfalseを返すことがあります。\r
58          * @param i_width\r
59          * @param i_height\r
60          * @param i_fmt\r
61          * @throws NyARException\r
62          */\r
63         public JmfNyARRaster_RGB(int i_width,int i_height,VideoFormat i_fmt) throws NyARException\r
64         {\r
65                 initMember(i_width,i_height,i_fmt);\r
66         }\r
67         /**\r
68          * i_fmtに一致する画素フォーマットのRasterを作成します。\r
69          * このコンストラクタで作成したクラスは、hasBuffer()がfalseを返すことがあります。\r
70          * @param i_size\r
71          * @param i_fmt\r
72          * @throws NyARException\r
73          */\r
74         public JmfNyARRaster_RGB(NyARIntSize i_size,VideoFormat i_fmt) throws NyARException\r
75         {\r
76                 initMember(i_size.w,i_size.h,i_fmt);\r
77         }\r
78         private void initMember(int i_width,int i_height,VideoFormat i_fmt) throws NyARException\r
79         {\r
80                 this._size= new NyARIntSize(i_width,i_height);\r
81                 // データサイズの確認\r
82                 final Dimension s = i_fmt.getSize();\r
83                 if (!this._size.isEqualSize(s.width,s.height)) {\r
84                         throw new NyARException();\r
85                 }\r
86                 // データ配列の確認\r
87                 if(i_fmt instanceof YUVFormat){\r
88                         //YUVフォーマット\r
89                         this._holder=new NyARGLPixelReader_YUV(this._size,(YUVFormat)i_fmt);                    \r
90                 }else if(i_fmt instanceof RGBFormat){\r
91                         //RGBフォーマット\r
92                         this._holder=new NyARGLPixelReader_RGB24(this._size,(RGBFormat)i_fmt);\r
93                 }else{\r
94                         throw new NyARException();\r
95                 }               \r
96         }\r
97         public void setBuffer(javax.media.Buffer i_buffer) throws NyARException\r
98         {\r
99                 this._holder.setMediaBuffer(i_buffer);\r
100                 return;\r
101         }\r
102         final public int getWidth()\r
103         {\r
104                 return this._size.w;\r
105         }\r
106 \r
107         final public int getHeight()\r
108         {\r
109                 return this._size.h;\r
110         }\r
111 \r
112         final public NyARIntSize getSize()\r
113         {\r
114                 return this._size;\r
115         }\r
116         final public int getBufferType()\r
117         {\r
118                 return this._holder.buffer_type;\r
119         }\r
120         final public INyARRgbPixelReader getRgbPixelReader()\r
121         {\r
122                 return this._holder;\r
123         }\r
124         /**\r
125          * インスタンスがバッファを所有するかを返します。\r
126          * @return\r
127          */     \r
128         final public boolean hasBuffer()\r
129         {\r
130                 return this._holder.buffer!=null;\r
131         }\r
132         final public Object getBuffer()\r
133         {\r
134                 assert(this._holder.buffer!=null);\r
135                 return this._holder.buffer;\r
136         }\r
137         final public boolean isEqualBufferType(int i_type_value)\r
138         {\r
139                 return this._holder.buffer_type==i_type_value;\r
140         }\r
141         final public void wrapBuffer(Object i_ref_buf) throws NyARException\r
142         {\r
143                 NyARException.notImplement();\r
144         }\r
145         /**\r
146          *      @deprecated hasBuffer()関数を使ってください。\r
147          * \r
148          */\r
149         final public boolean hasData()\r
150         {\r
151                 return this.hasBuffer();\r
152         }\r
153 \r
154 }\r
155 \r
156 \r
157 /**\r
158  * JMFと汎用バッファを中継する拡張INyARRgbPixelReader\r
159  * @author nyatla\r
160  *\r
161  */\r
162 abstract class JmfRGB24RasterHolder implements INyARRgbPixelReader\r
163 {\r
164         public int buffer_type;\r
165         public byte[] buffer;\r
166         public abstract void setMediaBuffer(javax.media.Buffer i_buffer);\r
167 }\r
168 \r
169 /**\r
170  * RGB24フォーマットのデータを扱うピクセルリーダ\r
171  */\r
172 class NyARGLPixelReader_RGB24 extends JmfRGB24RasterHolder\r
173 {\r
174         protected boolean _is_flipped;\r
175         private NyARIntSize _ref_size;\r
176         public NyARGLPixelReader_RGB24(NyARIntSize i_ref_size,RGBFormat i_input_format) throws NyARException\r
177         {\r
178                 this._ref_size=i_ref_size;\r
179                 //ピクセルフォーマットを設定(現状は24bitRGBを受けつける。)\r
180                 RGBFormat fm=(RGBFormat)i_input_format;\r
181                 if(fm.getBitsPerPixel()!=24){\r
182                         throw new NyARException();\r
183                 }\r
184                 int r=fm.getRedMask();\r
185                 int b=fm.getBlueMask();\r
186                 if(r==1 && b==3){\r
187                         this.buffer_type=NyARBufferType.BYTE1D_R8G8B8_24;\r
188                 }else if(r==3 && b==1){\r
189                         this.buffer_type=NyARBufferType.BYTE1D_B8G8R8_24;                       \r
190                 }else{\r
191                         throw new NyARException();\r
192                 }\r
193                 //vertical反転の有無を確認\r
194                 this._is_flipped=i_input_format.getFlipped()!=0?true:false;\r
195                 this.buffer=new byte[i_ref_size.w*i_ref_size.h*3];\r
196                 //RGBフォーマット\r
197                 \r
198                 return;\r
199         }\r
200         public void setMediaBuffer(javax.media.Buffer i_buffer)\r
201         {\r
202                 //vertical反転が必要ならば、反転した画像を作成する。\r
203                 byte[] src=(byte[])i_buffer.getData();\r
204                 if(this._is_flipped){\r
205                         final int length = this._ref_size.w * 3;\r
206                         int src_idx = 0;\r
207                         int dest_idx = (this._ref_size.h - 1) * length;                 \r
208                         for (int i = 0; i < this._ref_size.h; i++) {\r
209                                 System.arraycopy(src,src_idx, this.buffer, dest_idx, length);\r
210                                 src_idx += length;\r
211                                 dest_idx -= length;\r
212                         }\r
213                 }else{\r
214                         System.arraycopy(src,0,this.buffer,0,this.buffer.length);\r
215                         this.buffer=(byte[])i_buffer.getData();\r
216                 }\r
217                 return;\r
218         }\r
219         public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
220         {\r
221                 int bp = (i_x + i_y * this._ref_size.w) * 3;\r
222                 byte[] ref = this.buffer;\r
223                 switch(this.buffer_type){\r
224                 case NyARBufferType.BYTE1D_R8G8B8_24:\r
225                         o_rgb[0] = (ref[bp + 0] & 0xff);// R\r
226                         o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
227                         o_rgb[2] = (ref[bp + 2] & 0xff);// B\r
228                         break;\r
229                 case NyARBufferType.BYTE1D_B8G8R8_24:\r
230                         o_rgb[0] = (ref[bp + 2] & 0xff);// B\r
231                         o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
232                         o_rgb[2] = (ref[bp + 0] & 0xff);// R\r
233                         break;\r
234                 default:\r
235                         throw new NyARException();\r
236                 }\r
237                 return;\r
238         }\r
239         public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
240         {\r
241                 int width = this._ref_size.w;\r
242                 byte[] ref = this.buffer;\r
243                 int bp;\r
244                 switch(this.buffer_type){\r
245                 case NyARBufferType.BYTE1D_R8G8B8_24:\r
246                         for (int i = i_num - 1; i >= 0; i--) {\r
247                                 bp = (i_x[i] + i_y[i] * width) * 3;\r
248                                 o_rgb[i * 3 + 0] = (ref[bp + 0] & 0xff);// R\r
249                                 o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
250                                 o_rgb[i * 3 + 2] = (ref[bp + 2] & 0xff);// B\r
251                         }\r
252                         break;\r
253                 case NyARBufferType.BYTE1D_B8G8R8_24:\r
254                         for (int i = i_num - 1; i >= 0; i--) {\r
255                                 bp = (i_x[i] + i_y[i] * width) * 3;\r
256                                 o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// B\r
257                                 o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
258                                 o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// R\r
259                         }\r
260                         break;\r
261                 default:\r
262                         throw new NyARException();\r
263                 }\r
264                 return;\r
265         }\r
266         public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
267         {\r
268                 NyARException.notImplement();           \r
269         }\r
270         public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
271         {\r
272                 NyARException.notImplement();           \r
273         }\r
274         public void switchBuffer(Object i_ref_object) throws NyARException\r
275         {\r
276                 NyARException.notImplement();           \r
277         }\r
278 \r
279 }\r
280 \r
281 \r
282 \r
283 \r
284 /**\r
285  * ソースがYUVフォーマットのデータをBGR24として扱うピクセルリーダ\r
286  * ソースデータをセットした時に変換します。\r
287  * (将来YUVをそのまま素通りさせるように書き換えるかも)\r
288  */\r
289 class NyARGLPixelReader_YUV extends JmfRGB24RasterHolder\r
290 {\r
291         private NyARIntSize _ref_size;  \r
292         private YUVToRGB _yuv2rgb;\r
293 \r
294         private javax.media.Buffer _rgb_buf;\r
295         /**\r
296          * フォーマットアレイから、BGR24フォーマットを探す\r
297          * @param i_formats\r
298          * @return\r
299          */\r
300         private Format pickRGB24Format(Format[] i_formats)\r
301         {\r
302                 for(int i=0;i<i_formats.length;i++){\r
303                         RGBFormat f=(RGBFormat)i_formats[i];\r
304                         if(f.getBitsPerPixel()!=24){\r
305                                 continue;\r
306                         }\r
307                         if(f.getRedMask()!=3 ||f.getGreenMask()!=2 ||f.getBlueMask()!=1 || f.getFlipped()!=0)\r
308                         {\r
309                                 continue;\r
310                         }\r
311                         return f;\r
312                 }\r
313                 return null;\r
314         }\r
315         public NyARGLPixelReader_YUV(NyARIntSize i_ref_size,YUVFormat i_input_format) throws NyARException\r
316         {\r
317                 this._ref_size=i_ref_size;\r
318                 this.buffer_type=NyARBufferType.BYTE1D_B8G8R8_24;\r
319                 this.buffer=null;\r
320                 this._yuv2rgb=new YUVToRGB();\r
321                 this._rgb_buf=new javax.media.Buffer();\r
322                 //24bit-BGRフォーマットのものを探す\r
323                 Format output_format=pickRGB24Format(this._yuv2rgb.getSupportedOutputFormats(i_input_format));\r
324                 if(output_format==null){\r
325                         throw new NyARException();\r
326                 }\r
327                 this._yuv2rgb.setInputFormat(i_input_format);\r
328                 this._yuv2rgb.setOutputFormat(output_format);\r
329                 try{\r
330                         this._yuv2rgb.open();\r
331                 }catch(Exception e){\r
332                         throw new NyARException();\r
333                 }\r
334                 return;\r
335         }\r
336         public void setMediaBuffer(javax.media.Buffer i_buffer)\r
337         {\r
338                 //エラー出した時のトラップ\r
339                 if(this._yuv2rgb.process(i_buffer, this._rgb_buf)!=YUVToRGB.BUFFER_PROCESSED_OK){\r
340                         System.err.println("YUVToRGB.process error:");\r
341                 }\r
342                 this.buffer=(byte[])this._rgb_buf.getData();\r
343                 return;\r
344         }\r
345         public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
346         {\r
347                 //IN :BGRBGR\r
348                 //   :012012\r
349                 final int bp = (i_x + i_y * this._ref_size.w) * 3;\r
350                 final byte[] ref = this.buffer;\r
351                 o_rgb[0] = (ref[bp + 2] & 0xff);// R\r
352                 o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
353                 o_rgb[2] = (ref[bp + 0] & 0xff);// B\r
354                 return;\r
355         }\r
356         public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
357         {\r
358                 int bp;\r
359                 final int width = this._ref_size.w;\r
360                 final byte[] ref = this.buffer;\r
361                 for (int i = i_num - 1; i >= 0; i--) {\r
362                         bp = (i_x[i] + i_y[i] * width) * 3;\r
363                         o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// R\r
364                         o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
365                         o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// B\r
366                 }\r
367                 return;\r
368         }\r
369         public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
370         {\r
371                 NyARException.notImplement();           \r
372         }\r
373         public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
374         {\r
375                 NyARException.notImplement();           \r
376         }\r
377         public void switchBuffer(Object i_ref_object) throws NyARException\r
378         {\r
379                 NyARException.notImplement();           \r
380         }       \r
381 }\r
382 \r