OSDN Git Service

[TAG]NyARToolkit for Java 2.4.2
[nyartoolkit-and/nyartoolkit-and.git] / tags / 2.4.2 / 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.types.*;\r
38 \r
39 \r
40 \r
41 /**\r
42  * RGB24フォーマットのデータを扱うピクセルリーダ\r
43  */\r
44 class NyARBufferReader_Reader_RGB24 extends NyARBufferReader_Reader\r
45 {\r
46         protected boolean _is_flipped;\r
47         public NyARBufferReader_Reader_RGB24(RGBFormat i_input_format,NyARIntSize i_ref_size) throws NyARException\r
48         {\r
49                 super(i_ref_size);\r
50                 //ピクセルフォーマットを設定(現状は24bitRGBを受けつける。)\r
51                 RGBFormat fm=(RGBFormat)i_input_format;\r
52                 if(fm.getBitsPerPixel()!=24){\r
53                         throw new NyARException();\r
54                 }\r
55                 int r=fm.getRedMask();\r
56                 int b=fm.getBlueMask();\r
57                 if(r==1 && b==3){\r
58                         this._buf_type=BUFFERFORMAT_BYTE1D_R8G8B8_24;\r
59                 }else if(r==3 && b==1){\r
60                         this._buf_type=BUFFERFORMAT_BYTE1D_B8G8R8_24;                   \r
61                 }else{\r
62                         throw new NyARException();\r
63                 }\r
64                 //vertical反転の有無を確認\r
65                 this._is_flipped=i_input_format.getFlipped()!=0?true:false;\r
66                 this._ref_buf=new byte[i_ref_size.w*i_ref_size.h*3];\r
67                 //RGBフォーマット\r
68                 \r
69                 return;\r
70         }\r
71         public void changeBuffer(javax.media.Buffer i_buffer)\r
72         {\r
73                 //vertical反転が必要ならば、反転した画像を作成する。\r
74                 byte[] src=(byte[])i_buffer.getData();\r
75                 if(this._is_flipped){\r
76                         final int length = this._ref_size.w * 3;\r
77                         int src_idx = 0;\r
78                         int dest_idx = (this._ref_size.h - 1) * length;                 \r
79                         for (int i = 0; i < this._ref_size.h; i++) {\r
80                                 System.arraycopy(src,src_idx, this._ref_buf, dest_idx, length);\r
81                                 src_idx += length;\r
82                                 dest_idx -= length;\r
83                         }\r
84                 }else{\r
85                         System.arraycopy(src,0,this._ref_buf,0,this._ref_buf.length);\r
86                         this._ref_buf=(byte[])i_buffer.getData();\r
87                 }\r
88                 return;\r
89         }\r
90         public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
91         {\r
92                 int bp = (i_x + i_y * this._ref_size.w) * 3;\r
93                 byte[] ref = this._ref_buf;\r
94                 switch(this._buf_type){\r
95                 case BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
96                         o_rgb[0] = (ref[bp + 0] & 0xff);// R\r
97                         o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
98                         o_rgb[2] = (ref[bp + 2] & 0xff);// B\r
99                         break;\r
100                 case BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
101                         o_rgb[0] = (ref[bp + 2] & 0xff);// B\r
102                         o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
103                         o_rgb[2] = (ref[bp + 0] & 0xff);// R\r
104                         break;\r
105                 default:\r
106                         throw new NyARException();\r
107                 }\r
108                 return;\r
109         }\r
110         public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
111         {\r
112                 int width = this._ref_size.w;\r
113                 byte[] ref = this._ref_buf;\r
114                 int bp;\r
115                 switch(this._buf_type){\r
116                 case BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
117                         for (int i = i_num - 1; i >= 0; i--) {\r
118                                 bp = (i_x[i] + i_y[i] * width) * 3;\r
119                                 o_rgb[i * 3 + 0] = (ref[bp + 0] & 0xff);// R\r
120                                 o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
121                                 o_rgb[i * 3 + 2] = (ref[bp + 2] & 0xff);// B\r
122                         }\r
123                         break;\r
124                 case BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
125                         for (int i = i_num - 1; i >= 0; i--) {\r
126                                 bp = (i_x[i] + i_y[i] * width) * 3;\r
127                                 o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// B\r
128                                 o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
129                                 o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// R\r
130                         }\r
131                         break;\r
132                 default:\r
133                         throw new NyARException();\r
134                 }\r
135                 return;\r
136         }\r
137         public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
138         {\r
139                 NyARException.notImplement();           \r
140         }\r
141         public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
142         {\r
143                 NyARException.notImplement();           \r
144         }\r
145 \r
146 }\r
147 \r
148 \r
149 \r
150 \r
151 /**\r
152  * ソースがYUVフォーマットのデータをBGR24として扱うピクセルリーダ\r
153  * ソースデータをセットした時に変換します。\r
154  * (将来YUVをそのまま素通りさせるように書き換えるかも)\r
155  */\r
156 class NyARBufferReader_Reader_YUV extends NyARBufferReader_Reader\r
157 {\r
158         \r
159         private YUVToRGB _yuv2rgb;\r
160         private javax.media.Buffer _rgb_buf;\r
161         /**\r
162          * フォーマットアレイから、BGR24フォーマットを探す\r
163          * @param i_formats\r
164          * @return\r
165          */\r
166         private Format pickRGB24Format(Format[] i_formats)\r
167         {\r
168                 for(int i=0;i<i_formats.length;i++){\r
169                         RGBFormat f=(RGBFormat)i_formats[i];\r
170                         if(f.getBitsPerPixel()!=24){\r
171                                 continue;\r
172                         }\r
173                         if(f.getRedMask()!=3 ||f.getGreenMask()!=2 ||f.getBlueMask()!=1 || f.getFlipped()!=0)\r
174                         {\r
175                                 continue;\r
176                         }\r
177                         return f;\r
178                 }\r
179                 return null;\r
180         }\r
181         public NyARBufferReader_Reader_YUV(YUVFormat i_input_format,NyARIntSize i_ref_size) throws NyARException\r
182         {\r
183                 super(i_ref_size,BUFFERFORMAT_BYTE1D_B8G8R8_24);\r
184                 this._yuv2rgb=new YUVToRGB();\r
185                 this._rgb_buf=new javax.media.Buffer();\r
186                 this._ref_buf=null;\r
187                 //24bit-BGRフォーマットのものを探す\r
188                 Format output_format=pickRGB24Format(this._yuv2rgb.getSupportedOutputFormats(i_input_format));\r
189                 if(output_format==null){\r
190                         throw new NyARException();\r
191                 }\r
192                 this._yuv2rgb.setInputFormat(i_input_format);\r
193                 this._yuv2rgb.setOutputFormat(output_format);\r
194                 try{\r
195                         this._yuv2rgb.open();\r
196                 }catch(Exception e){\r
197                         throw new NyARException();\r
198                 }\r
199                 return;\r
200         }\r
201         public void changeBuffer(javax.media.Buffer i_buffer)\r
202         {\r
203                 //エラー出した時のトラップ\r
204                 if(this._yuv2rgb.process(i_buffer, this._rgb_buf)!=YUVToRGB.BUFFER_PROCESSED_OK){\r
205                         System.err.println("YUVToRGB.process error:");\r
206                 }\r
207                 this._ref_buf=(byte[])this._rgb_buf.getData();\r
208                 return;\r
209         }\r
210         public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
211         {\r
212                 //IN :BGRBGR\r
213                 //   :012012\r
214                 final int bp = (i_x + i_y * this._ref_size.w) * 3;\r
215                 final byte[] ref = this._ref_buf;\r
216                 o_rgb[0] = (ref[bp + 2] & 0xff);// R\r
217                 o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
218                 o_rgb[2] = (ref[bp + 0] & 0xff);// B\r
219                 return;\r
220         }\r
221         public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
222         {\r
223                 int bp;\r
224                 final int width = this._ref_size.w;\r
225                 final byte[] ref = this._ref_buf;\r
226                 for (int i = i_num - 1; i >= 0; i--) {\r
227                         bp = (i_x[i] + i_y[i] * width) * 3;\r
228                         o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// R\r
229                         o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
230                         o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// B\r
231                 }\r
232                 return;\r
233         }\r
234         public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
235         {\r
236                 NyARException.notImplement();           \r
237         }\r
238         public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
239         {\r
240                 NyARException.notImplement();           \r
241         }\r
242         \r
243 }\r
244 \r
245 \r
246 /**\r
247  * \r
248  * RGB形式のJMFバッファをラップするNyARRasterです。\r
249  * JMFから得たラスタデータのピクセル並び順を考慮します。\r
250  *\r
251  */\r
252 public class JmfNyARRaster_RGB extends NyARRgbRaster_BasicClass\r
253 {\r
254 \r
255         protected NyARBufferReader_Reader _reader;\r
256         /**\r
257          * i_formatに一致する画素フォーマットの\r
258          * @param i_size\r
259          * @param i_format\r
260          * @throws NyARException\r
261          */\r
262 \r
263 \r
264         public JmfNyARRaster_RGB(NyARIntSize i_ref_size,VideoFormat i_format) throws NyARException\r
265         {\r
266                 super(new NyARIntSize(i_ref_size));             \r
267                 this._reader = createReader(i_format);\r
268         }\r
269         public JmfNyARRaster_RGB(int i_width,int i_height,VideoFormat i_format) throws NyARException\r
270         {\r
271                 super(new NyARIntSize(i_width,i_height));\r
272                 this._reader = createReader(i_format);\r
273         }\r
274         \r
275         /**\r
276          * フォーマットを解析して、マッチするリーダオブジェクトを返します。\r
277          * @param i_fmt\r
278          * ビデオフォーマットを指定します。\r
279          * @return\r
280          * リーダオブジェクト\r
281          * @throws NyARException\r
282          */\r
283         private NyARBufferReader_Reader createReader(VideoFormat i_fmt) throws NyARException\r
284         {\r
285                 // データサイズの確認\r
286                 final Dimension s = i_fmt.getSize();\r
287                 if (!this._size.isEqualSize(s.width, s.height)) {\r
288                         throw new NyARException();\r
289                 }\r
290                 // データ配列の確認\r
291                 if(i_fmt instanceof YUVFormat){\r
292                         //YUVフォーマット\r
293                         return new NyARBufferReader_Reader_YUV((YUVFormat)i_fmt,this._size);                    \r
294                 }else if(i_fmt instanceof RGBFormat){\r
295                         //RGBフォーマット\r
296                         return new NyARBufferReader_Reader_RGB24((RGBFormat)i_fmt,this._size);\r
297                 }else{\r
298                         throw new NyARException();\r
299                 }\r
300         }\r
301 \r
302         /**\r
303          * javax.media.Bufferを分析して、その分析結果をNyARRasterに適合する形で保持します。\r
304          * 関数実行後に外部でi_bufferの内容変更した場合には、再度setBuffer関数を呼び出してください。\r
305          * この関数を実行すると、getRgbPixelReaderで取得したReaderのプロパティが変化することがあります。\r
306          * @param i_buffer\r
307          * RGB形式のデータを格納したjavax.media.Bufferオブジェクトを指定してください。\r
308          * @return i_bufferをラップしたオブジェクトを返します。\r
309          * @throws NyARException\r
310          */\r
311         public void setBuffer(javax.media.Buffer i_buffer) throws NyARException\r
312         {\r
313                 this._reader.changeBuffer(i_buffer);\r
314                 return;\r
315         }\r
316         /**\r
317          * データを持っているかを返します。\r
318          * @return\r
319          */\r
320         public boolean hasData()\r
321         {\r
322                 return this._reader._ref_buf != null;\r
323         }\r
324         public INyARRgbPixelReader getRgbPixelReader()\r
325         {\r
326                 return this._reader;\r
327         }\r
328         public INyARBufferReader getBufferReader()\r
329         {\r
330                 return this._reader;\r
331         }\r
332 }\r
333 \r
334 \r
335 \r