2 * PROJECT: NyARToolkit JMF utilities.
\r
3 * --------------------------------------------------------------------------------
\r
5 * Copyright (c) 2008 nyatla
\r
6 * airmail(at)ebony.plala.or.jp
\r
7 * http://nyatla.jp/nyartoolkit/
\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
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
27 package jp.nyatla.nyartoolkit.jmf.utils;
\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
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
46 * RGB形式のJMFバッファをラップするNyARRasterです。
\r
47 * JMFから得たラスタデータのピクセル並び順を考慮します。
\r
50 public class JmfNyARRaster_RGB implements INyARRgbRaster
\r
52 private JmfRGB24RasterHolder _holder;
\r
53 protected NyARIntSize _size;
\r
56 * i_fmtに一致する画素フォーマットのRasterを作成します。
\r
57 * このコンストラクタで作成したクラスは、hasBuffer()がfalseを返すことがあります。
\r
61 * @throws NyARException
\r
63 public JmfNyARRaster_RGB(int i_width,int i_height,VideoFormat i_fmt) throws NyARException
\r
65 initMember(i_width,i_height,i_fmt);
\r
68 * i_fmtに一致する画素フォーマットのRasterを作成します。
\r
69 * このコンストラクタで作成したクラスは、hasBuffer()がfalseを返すことがあります。
\r
72 * @throws NyARException
\r
74 public JmfNyARRaster_RGB(NyARIntSize i_size,VideoFormat i_fmt) throws NyARException
\r
76 initMember(i_size.w,i_size.h,i_fmt);
\r
78 private void initMember(int i_width,int i_height,VideoFormat i_fmt) throws NyARException
\r
80 this._size= new NyARIntSize(i_width,i_height);
\r
82 final Dimension s = i_fmt.getSize();
\r
83 if (!this._size.isEqualSize(s.width,s.height)) {
\r
84 throw new NyARException();
\r
87 if(i_fmt instanceof YUVFormat){
\r
89 this._holder=new NyARGLPixelReader_YUV(this._size,(YUVFormat)i_fmt);
\r
90 }else if(i_fmt instanceof RGBFormat){
\r
92 this._holder=new NyARGLPixelReader_RGB24(this._size,(RGBFormat)i_fmt);
\r
94 throw new NyARException();
\r
97 public void setBuffer(javax.media.Buffer i_buffer) throws NyARException
\r
99 this._holder.setMediaBuffer(i_buffer);
\r
102 final public int getWidth()
\r
104 return this._size.w;
\r
107 final public int getHeight()
\r
109 return this._size.h;
\r
112 final public NyARIntSize getSize()
\r
116 final public int getBufferType()
\r
118 return this._holder.buffer_type;
\r
120 final public INyARRgbPixelReader getRgbPixelReader()
\r
122 return this._holder;
\r
125 * インスタンスがバッファを所有するかを返します。
\r
128 final public boolean hasBuffer()
\r
130 return this._holder.buffer!=null;
\r
132 final public Object getBuffer()
\r
134 assert(this._holder.buffer!=null);
\r
135 return this._holder.buffer;
\r
137 final public boolean isEqualBufferType(int i_type_value)
\r
139 return this._holder.buffer_type==i_type_value;
\r
141 final public void wrapBuffer(Object i_ref_buf) throws NyARException
\r
143 NyARException.notImplement();
\r
146 * @deprecated hasBuffer()関数を使ってください。
\r
149 final public boolean hasData()
\r
151 return this.hasBuffer();
\r
158 * JMFと汎用バッファを中継する拡張INyARRgbPixelReader
\r
162 abstract class JmfRGB24RasterHolder implements INyARRgbPixelReader
\r
164 public int buffer_type;
\r
165 public byte[] buffer;
\r
166 public abstract void setMediaBuffer(javax.media.Buffer i_buffer);
\r
170 * RGB24フォーマットのデータを扱うピクセルリーダ
\r
172 class NyARGLPixelReader_RGB24 extends JmfRGB24RasterHolder
\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
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
184 int r=fm.getRedMask();
\r
185 int b=fm.getBlueMask();
\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
191 throw new NyARException();
\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
200 public void setMediaBuffer(javax.media.Buffer i_buffer)
\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
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
211 dest_idx -= length;
\r
214 System.arraycopy(src,0,this.buffer,0,this.buffer.length);
\r
215 this.buffer=(byte[])i_buffer.getData();
\r
219 public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException
\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
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
235 throw new NyARException();
\r
239 public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException
\r
241 int width = this._ref_size.w;
\r
242 byte[] ref = this.buffer;
\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
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
262 throw new NyARException();
\r
266 public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException
\r
268 NyARException.notImplement();
\r
270 public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException
\r
272 NyARException.notImplement();
\r
274 public void switchBuffer(Object i_ref_object) throws NyARException
\r
276 NyARException.notImplement();
\r
285 * ソースがYUVフォーマットのデータをBGR24として扱うピクセルリーダ
\r
286 * ソースデータをセットした時に変換します。
\r
287 * (将来YUVをそのまま素通りさせるように書き換えるかも)
\r
289 class NyARGLPixelReader_YUV extends JmfRGB24RasterHolder
\r
291 private NyARIntSize _ref_size;
\r
292 private YUVToRGB _yuv2rgb;
\r
294 private javax.media.Buffer _rgb_buf;
\r
296 * フォーマットアレイから、BGR24フォーマットを探す
\r
300 private Format pickRGB24Format(Format[] i_formats)
\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
307 if(f.getRedMask()!=3 ||f.getGreenMask()!=2 ||f.getBlueMask()!=1 || f.getFlipped()!=0)
\r
315 public NyARGLPixelReader_YUV(NyARIntSize i_ref_size,YUVFormat i_input_format) throws NyARException
\r
317 this._ref_size=i_ref_size;
\r
318 this.buffer_type=NyARBufferType.BYTE1D_B8G8R8_24;
\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
327 this._yuv2rgb.setInputFormat(i_input_format);
\r
328 this._yuv2rgb.setOutputFormat(output_format);
\r
330 this._yuv2rgb.open();
\r
331 }catch(Exception e){
\r
332 throw new NyARException();
\r
336 public void setMediaBuffer(javax.media.Buffer i_buffer)
\r
339 if(this._yuv2rgb.process(i_buffer, this._rgb_buf)!=YUVToRGB.BUFFER_PROCESSED_OK){
\r
340 System.err.println("YUVToRGB.process error:");
\r
342 this.buffer=(byte[])this._rgb_buf.getData();
\r
345 public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException
\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
356 public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException
\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
369 public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException
\r
371 NyARException.notImplement();
\r
373 public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException
\r
375 NyARException.notImplement();
\r
377 public void switchBuffer(Object i_ref_object) throws NyARException
\r
379 NyARException.notImplement();
\r