OSDN Git Service

[TAG]NyARToolkit/2.3.0
[nyartoolkit-and/nyartoolkit-and.git] / tags / 2.3.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.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 \r
138 }\r
139 \r
140 \r
141 \r
142 \r
143 /**\r
144  * ソースがYUVフォーマットのデータをBGR24として扱うピクセルリーダ\r
145  * ソースデータをセットした時に変換します。\r
146  * (将来YUVをそのまま素通りさせるように書き換えるかも)\r
147  */\r
148 class NyARBufferReader_Reader_YUV extends NyARBufferReader_Reader\r
149 {\r
150         \r
151         private YUVToRGB _yuv2rgb;\r
152         private javax.media.Buffer _rgb_buf;\r
153         /**\r
154          * フォーマットアレイから、BGR24フォーマットを探す\r
155          * @param i_formats\r
156          * @return\r
157          */\r
158         private Format pickRGB24Format(Format[] i_formats)\r
159         {\r
160                 for(int i=0;i<i_formats.length;i++){\r
161                         RGBFormat f=(RGBFormat)i_formats[i];\r
162                         if(f.getBitsPerPixel()!=24){\r
163                                 continue;\r
164                         }\r
165                         if(f.getRedMask()!=3 ||f.getGreenMask()!=2 ||f.getBlueMask()!=1 || f.getFlipped()!=0)\r
166                         {\r
167                                 continue;\r
168                         }\r
169                         return f;\r
170                 }\r
171                 return null;\r
172         }\r
173         public NyARBufferReader_Reader_YUV(YUVFormat i_input_format,NyARIntSize i_ref_size) throws NyARException\r
174         {\r
175                 super(i_ref_size,BUFFERFORMAT_BYTE1D_B8G8R8_24);\r
176                 this._yuv2rgb=new YUVToRGB();\r
177                 this._rgb_buf=new javax.media.Buffer();\r
178                 this._ref_buf=null;\r
179                 //24bit-BGRフォーマットのものを探す\r
180                 Format output_format=pickRGB24Format(this._yuv2rgb.getSupportedOutputFormats(i_input_format));\r
181                 if(output_format==null){\r
182                         throw new NyARException();\r
183                 }\r
184                 this._yuv2rgb.setInputFormat(i_input_format);\r
185                 this._yuv2rgb.setOutputFormat(output_format);\r
186                 try{\r
187                         this._yuv2rgb.open();\r
188                 }catch(Exception e){\r
189                         throw new NyARException();\r
190                 }\r
191                 return;\r
192         }\r
193         public void changeBuffer(javax.media.Buffer i_buffer)\r
194         {\r
195                 //エラー出した時のトラップ\r
196                 if(this._yuv2rgb.process(i_buffer, this._rgb_buf)!=YUVToRGB.BUFFER_PROCESSED_OK){\r
197                         System.err.println("YUVToRGB.process error:");\r
198                 }\r
199                 this._ref_buf=(byte[])this._rgb_buf.getData();\r
200                 return;\r
201         }\r
202         public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
203         {\r
204                 //IN :BGRBGR\r
205                 //   :012012\r
206                 final int bp = (i_x + i_y * this._ref_size.w) * 3;\r
207                 final byte[] ref = this._ref_buf;\r
208                 o_rgb[0] = (ref[bp + 2] & 0xff);// R\r
209                 o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
210                 o_rgb[2] = (ref[bp + 0] & 0xff);// B\r
211                 return;\r
212         }\r
213         public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
214         {\r
215                 int bp;\r
216                 final int width = this._ref_size.w;\r
217                 final byte[] ref = this._ref_buf;\r
218                 for (int i = i_num - 1; i >= 0; i--) {\r
219                         bp = (i_x[i] + i_y[i] * width) * 3;\r
220                         o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// R\r
221                         o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
222                         o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// B\r
223                 }\r
224                 return;\r
225         }\r
226 }\r
227 \r
228 \r
229 /**\r
230  * \r
231  * RGB形式のJMFバッファをラップするNyARRasterです。\r
232  * JMFから得たラスタデータのピクセル並び順を考慮します。\r
233  *\r
234  */\r
235 public class JmfNyARRaster_RGB extends NyARRgbRaster_BasicClass\r
236 {\r
237 \r
238         protected NyARBufferReader_Reader _reader;\r
239         /**\r
240          * i_formatに一致する画素フォーマットの\r
241          * @param i_size\r
242          * @param i_format\r
243          * @throws NyARException\r
244          */\r
245 \r
246 \r
247         public JmfNyARRaster_RGB(NyARIntSize i_ref_size,VideoFormat i_format) throws NyARException\r
248         {\r
249                 super(new NyARIntSize(i_ref_size));             \r
250                 this._reader = createReader(i_format);\r
251         }\r
252         public JmfNyARRaster_RGB(int i_width,int i_height,VideoFormat i_format) throws NyARException\r
253         {\r
254                 super(new NyARIntSize(i_width,i_height));\r
255                 this._reader = createReader(i_format);\r
256         }\r
257         \r
258         /**\r
259          * フォーマットを解析して、マッチするリーダオブジェクトを返します。\r
260          * @param i_fmt\r
261          * ビデオフォーマットを指定します。\r
262          * @return\r
263          * リーダオブジェクト\r
264          * @throws NyARException\r
265          */\r
266         private NyARBufferReader_Reader createReader(VideoFormat i_fmt) throws NyARException\r
267         {\r
268                 // データサイズの確認\r
269                 final Dimension s = i_fmt.getSize();\r
270                 if (!this._size.isEqualSize(s.width, s.height)) {\r
271                         throw new NyARException();\r
272                 }\r
273                 // データ配列の確認\r
274                 if(i_fmt instanceof YUVFormat){\r
275                         //YUVフォーマット\r
276                         return new NyARBufferReader_Reader_YUV((YUVFormat)i_fmt,this._size);                    \r
277                 }else if(i_fmt instanceof RGBFormat){\r
278                         //RGBフォーマット\r
279                         return new NyARBufferReader_Reader_RGB24((RGBFormat)i_fmt,this._size);\r
280                 }else{\r
281                         throw new NyARException();\r
282                 }\r
283         }\r
284 \r
285         /**\r
286          * javax.media.Bufferを分析して、その分析結果をNyARRasterに適合する形で保持します。\r
287          * 関数実行後に外部でi_bufferの内容変更した場合には、再度setBuffer関数を呼び出してください。\r
288          * この関数を実行すると、getRgbPixelReaderで取得したReaderのプロパティが変化することがあります。\r
289          * @param i_buffer\r
290          * RGB形式のデータを格納したjavax.media.Bufferオブジェクトを指定してください。\r
291          * @return i_bufferをラップしたオブジェクトを返します。\r
292          * @throws NyARException\r
293          */\r
294         public void setBuffer(javax.media.Buffer i_buffer) throws NyARException\r
295         {\r
296                 this._reader.changeBuffer(i_buffer);\r
297                 return;\r
298         }\r
299         /**\r
300          * データを持っているかを返します。\r
301          * @return\r
302          */\r
303         public boolean hasData()\r
304         {\r
305                 return this._reader._ref_buf != null;\r
306         }\r
307         public INyARRgbPixelReader getRgbPixelReader()\r
308         {\r
309                 return this._reader;\r
310         }\r
311         public INyARBufferReader getBufferReader()\r
312         {\r
313                 return this._reader;\r
314         }\r
315 }\r
316 \r
317 \r
318 \r