-/**\r
- * RGB形式のJMFバッファをラップするNyARRasterです。\r
- * JMFから得たラスタデータのピクセル並び順を考慮します。\r
- * (c)2008 A虎@nyatla.jp\r
+/* \r
+ * PROJECT: NyARToolkit JMF utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
* airmail(at)ebony.plala.or.jp\r
- * http://nyatla.jp/\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
*/\r
package jp.nyatla.nyartoolkit.jmf.utils;\r
\r
-\r
-import javax.media.format.RGBFormat;\r
+import javax.media.format.*;\r
+import javax.media.*;\r
import java.awt.Dimension;\r
+import com.sun.media.codec.video.colorspace.*;\r
+\r
import jp.nyatla.nyartoolkit.NyARException;\r
-import jp.nyatla.nyartoolkit.core.raster.NyARRaster;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.raster.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
\r
\r
-public class JmfNyARRaster_RGB implements NyARRaster\r
+\r
+\r
+\r
+/**\r
+ * \r
+ * RGB形式のJMFバッファをラップするNyARRasterです。\r
+ * JMFから得たラスタデータのピクセル並び順を考慮します。\r
+ *\r
+ */\r
+public class JmfNyARRaster_RGB implements INyARRgbRaster\r
{\r
- public final static int PIXEL_ORDER_RGB=1;\r
- public final static int PIXEL_ORDER_BGR=2;\r
- protected int pix_type;\r
- private int red_idx;\r
- private int green_idx;\r
- private int blue_idx;\r
- protected byte[] ref_buf;\r
- protected int width=0;\r
- protected int height=0;\r
-\r
- /**\r
- * RGB形式のJMFバッファをラップするオブジェクトをつくります。\r
- * 生成直後のオブジェクトはデータを持ちません。\r
- * メンバ関数はsetBufferを実行後に使用可能になります。\r
- */\r
- public JmfNyARRaster_RGB(int i_width,int i_height)\r
- {\r
- ref_buf=null;\r
- width=i_width;\r
- height=i_height;\r
- }\r
- /**\r
- * フォーマットを解析して、インスタンスのフォーマットプロパティを初期化します。\r
- * \r
- * @param i_buffer\r
- * @throws NyARException\r
- */\r
- protected void initFormatProperty(RGBFormat i_fmt) throws NyARException\r
- {\r
- //データサイズの確認\r
- Dimension s=i_fmt.getSize();\r
- if(width!=s.width || height !=s.height){\r
- throw new NyARException();\r
- }\r
- //データ配列の確認\r
- red_idx =i_fmt.getRedMask()-1;\r
- green_idx=i_fmt.getGreenMask()-1;\r
- blue_idx =i_fmt.getBlueMask()-1;\r
- \r
- //色配列の特定\r
- if(red_idx==0 && blue_idx==2){\r
- pix_type=PIXEL_ORDER_RGB;\r
- }else if(red_idx==2 && blue_idx==0){\r
- pix_type=PIXEL_ORDER_BGR;\r
- }else{\r
- throw new NyARException("Unknown pixel order.");\r
- } \r
- }\r
- /**\r
- * javax.media.Bufferを分析して、その分析結果をNyARRasterに適合する形で保持します。\r
- * 関数実行後に外部でi_bufferの内容変更した場合には、再度setBuffer関数を呼び出してください。\r
- * @param i_buffer\r
- * RGB形式のデータを格納したjavax.media.Bufferオブジェクトを指定してください。\r
- * @return\r
- * i_bufferをラップしたオブジェクトを返します。\r
- * @throws NyARException\r
- */\r
- public void setBuffer(javax.media.Buffer i_buffer) throws NyARException\r
- {\r
- initFormatProperty((RGBFormat)i_buffer.getFormat());\r
- ref_buf=(byte[])i_buffer.getData();\r
- }\r
- public int getPixelTotal(int i_x,int i_y)\r
- {\r
- int bp=(i_x+i_y*width)*3;\r
- byte[] ref=this.ref_buf;\r
- return (ref[bp] & 0xff)+(ref[bp+1] & 0xff)+(ref[bp+2] & 0xff);\r
- }\r
- public void getPixelTotalRowLine(int i_row,int[] o_line)\r
- {\r
- final byte[] ref=this.ref_buf;\r
- int bp=(i_row+1)*this.width*3-3;\r
- for(int i=this.width-1;i>=0;i--){\r
- o_line[i]=(ref[bp] & 0xff)+(ref[bp+1] & 0xff)+(ref[bp+2] & 0xff);\r
- bp-=3;\r
- }\r
- } \r
- public int getWidth()\r
- {\r
- return width;\r
- }\r
- public int getHeight()\r
- {\r
- return height;\r
- }\r
- public void getPixel(int i_x,int i_y,int[] i_rgb)\r
- {\r
- int bp=(i_x+i_y*this.width)*3;\r
- byte[] ref=this.ref_buf;\r
- i_rgb[0]=(ref[bp+this.red_idx] & 0xff);//R\r
- i_rgb[1]=(ref[bp+this.green_idx] & 0xff);//G\r
- i_rgb[2]=(ref[bp+this.blue_idx] & 0xff);//B\r
- }\r
- /**\r
- * ピクセルの順序タイプを返します。\r
- * @return\r
- * その値\r
- */\r
- public int getPixelOrder()\r
- {\r
- return pix_type;\r
- }\r
- /**\r
- * データを持っているかを返します。\r
- * @return\r
- */\r
- public boolean hasData()\r
- {\r
- return ref_buf!=null;\r
- }\r
- public void getPixelSet(int[] i_x,int i_y[],int i_num,int[] o_rgb)\r
- {\r
- int ri=this.red_idx;\r
- int bi=this.green_idx;\r
- int gi=this.blue_idx;\r
- int width=this.width;\r
- byte[] ref=this.ref_buf;\r
- int bp;\r
- for(int i=i_num-1;i>=0;i--){\r
- bp=(i_x[i]+i_y[i]*width)*3;\r
- o_rgb[i*3+0]=(ref[bp+ri] & 0xff);//R\r
- o_rgb[i*3+1]=(ref[bp+gi] & 0xff);//G\r
- o_rgb[i*3+2]=(ref[bp+bi] & 0xff);//B\r
+ private JmfRGB24RasterHolder _holder;\r
+ protected NyARIntSize _size;\r
+\r
+ /**\r
+ * i_fmtに一致する画素フォーマットのRasterを作成します。\r
+ * このコンストラクタで作成したクラスは、hasBuffer()がfalseを返すことがあります。\r
+ * @param i_width\r
+ * @param i_height\r
+ * @param i_fmt\r
+ * @throws NyARException\r
+ */\r
+ public JmfNyARRaster_RGB(int i_width,int i_height,VideoFormat i_fmt) throws NyARException\r
+ {\r
+ initMember(i_width,i_height,i_fmt);\r
+ }\r
+ /**\r
+ * i_fmtに一致する画素フォーマットのRasterを作成します。\r
+ * このコンストラクタで作成したクラスは、hasBuffer()がfalseを返すことがあります。\r
+ * @param i_size\r
+ * @param i_fmt\r
+ * @throws NyARException\r
+ */\r
+ public JmfNyARRaster_RGB(NyARIntSize i_size,VideoFormat i_fmt) throws NyARException\r
+ {\r
+ initMember(i_size.w,i_size.h,i_fmt);\r
+ }\r
+ private void initMember(int i_width,int i_height,VideoFormat i_fmt) throws NyARException\r
+ {\r
+ this._size= new NyARIntSize(i_width,i_height);\r
+ // データサイズの確認\r
+ final Dimension s = i_fmt.getSize();\r
+ if (!this._size.isEqualSize(s.width,s.height)) {\r
+ throw new NyARException();\r
+ }\r
+ // データ配列の確認\r
+ if(i_fmt instanceof YUVFormat){\r
+ //YUVフォーマット\r
+ this._holder=new NyARGLPixelReader_YUV(this._size,(YUVFormat)i_fmt); \r
+ }else if(i_fmt instanceof RGBFormat){\r
+ //RGBフォーマット\r
+ this._holder=new NyARGLPixelReader_RGB24(this._size,(RGBFormat)i_fmt);\r
+ }else{\r
+ throw new NyARException();\r
+ } \r
+ }\r
+ public void setBuffer(javax.media.Buffer i_buffer) throws NyARException\r
+ {\r
+ this._holder.setMediaBuffer(i_buffer);\r
+ return;\r
+ }\r
+ final public int getWidth()\r
+ {\r
+ return this._size.w;\r
+ }\r
+\r
+ final public int getHeight()\r
+ {\r
+ return this._size.h;\r
+ }\r
+\r
+ final public NyARIntSize getSize()\r
+ {\r
+ return this._size;\r
+ }\r
+ final public int getBufferType()\r
+ {\r
+ return this._holder.buffer_type;\r
+ }\r
+ final public INyARRgbPixelReader getRgbPixelReader()\r
+ {\r
+ return this._holder;\r
+ }\r
+ /**\r
+ * インスタンスがバッファを所有するかを返します。\r
+ * @return\r
+ */ \r
+ final public boolean hasBuffer()\r
+ {\r
+ return this._holder.buffer!=null;\r
+ }\r
+ final public Object getBuffer()\r
+ {\r
+ assert(this._holder.buffer!=null);\r
+ return this._holder.buffer;\r
+ }\r
+ final public boolean isEqualBufferType(int i_type_value)\r
+ {\r
+ return this._holder.buffer_type==i_type_value;\r
+ }\r
+ final public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+ {\r
+ NyARException.notImplement();\r
+ }\r
+ /**\r
+ * @deprecated hasBuffer()関数を使ってください。\r
+ * \r
+ */\r
+ final public boolean hasData()\r
+ {\r
+ return this.hasBuffer();\r
+ }\r
+\r
+}\r
+\r
+\r
+/**\r
+ * JMFと汎用バッファを中継する拡張INyARRgbPixelReader\r
+ * @author nyatla\r
+ *\r
+ */\r
+abstract class JmfRGB24RasterHolder implements INyARRgbPixelReader\r
+{\r
+ public int buffer_type;\r
+ public byte[] buffer;\r
+ public abstract void setMediaBuffer(javax.media.Buffer i_buffer);\r
+}\r
+\r
+/**\r
+ * RGB24フォーマットのデータを扱うピクセルリーダ\r
+ */\r
+class NyARGLPixelReader_RGB24 extends JmfRGB24RasterHolder\r
+{\r
+ protected boolean _is_flipped;\r
+ private NyARIntSize _ref_size;\r
+ public NyARGLPixelReader_RGB24(NyARIntSize i_ref_size,RGBFormat i_input_format) throws NyARException\r
+ {\r
+ this._ref_size=i_ref_size;\r
+ //ピクセルフォーマットを設定(現状は24bitRGBを受けつける。)\r
+ RGBFormat fm=(RGBFormat)i_input_format;\r
+ if(fm.getBitsPerPixel()!=24){\r
+ throw new NyARException();\r
+ }\r
+ int r=fm.getRedMask();\r
+ int b=fm.getBlueMask();\r
+ if(r==1 && b==3){\r
+ this.buffer_type=INyARRaster.BUFFERFORMAT_BYTE1D_R8G8B8_24;\r
+ }else if(r==3 && b==1){\r
+ this.buffer_type=INyARRaster.BUFFERFORMAT_BYTE1D_B8G8R8_24; \r
+ }else{\r
+ throw new NyARException();\r
+ }\r
+ //vertical反転の有無を確認\r
+ this._is_flipped=i_input_format.getFlipped()!=0?true:false;\r
+ this.buffer=new byte[i_ref_size.w*i_ref_size.h*3];\r
+ //RGBフォーマット\r
+ \r
+ return;\r
+ }\r
+ public void setMediaBuffer(javax.media.Buffer i_buffer)\r
+ {\r
+ //vertical反転が必要ならば、反転した画像を作成する。\r
+ byte[] src=(byte[])i_buffer.getData();\r
+ if(this._is_flipped){\r
+ final int length = this._ref_size.w * 3;\r
+ int src_idx = 0;\r
+ int dest_idx = (this._ref_size.h - 1) * length; \r
+ for (int i = 0; i < this._ref_size.h; i++) {\r
+ System.arraycopy(src,src_idx, this.buffer, dest_idx, length);\r
+ src_idx += length;\r
+ dest_idx -= length;\r
+ }\r
+ }else{\r
+ System.arraycopy(src,0,this.buffer,0,this.buffer.length);\r
+ this.buffer=(byte[])i_buffer.getData();\r
+ }\r
+ return;\r
+ }\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
+ {\r
+ int bp = (i_x + i_y * this._ref_size.w) * 3;\r
+ byte[] ref = this.buffer;\r
+ switch(this.buffer_type){\r
+ case INyARRaster.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ o_rgb[0] = (ref[bp + 0] & 0xff);// R\r
+ o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[2] = (ref[bp + 2] & 0xff);// B\r
+ break;\r
+ case INyARRaster.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ o_rgb[0] = (ref[bp + 2] & 0xff);// B\r
+ o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[2] = (ref[bp + 0] & 0xff);// R\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ return;\r
+ }\r
+ public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
+ {\r
+ int width = this._ref_size.w;\r
+ byte[] ref = this.buffer;\r
+ int bp;\r
+ switch(this.buffer_type){\r
+ case INyARRaster.BUFFERFORMAT_BYTE1D_R8G8B8_24:\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ bp = (i_x[i] + i_y[i] * width) * 3;\r
+ o_rgb[i * 3 + 0] = (ref[bp + 0] & 0xff);// R\r
+ o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[i * 3 + 2] = (ref[bp + 2] & 0xff);// B\r
+ }\r
+ break;\r
+ case INyARRaster.BUFFERFORMAT_BYTE1D_B8G8R8_24:\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ bp = (i_x[i] + i_y[i] * width) * 3;\r
+ o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// B\r
+ o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// R\r
+ }\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ return;\r
+ }\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ public void switchBuffer(Object i_ref_object) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * ソースがYUVフォーマットのデータをBGR24として扱うピクセルリーダ\r
+ * ソースデータをセットした時に変換します。\r
+ * (将来YUVをそのまま素通りさせるように書き換えるかも)\r
+ */\r
+class NyARGLPixelReader_YUV extends JmfRGB24RasterHolder\r
+{\r
+ private NyARIntSize _ref_size; \r
+ private YUVToRGB _yuv2rgb;\r
+\r
+ private javax.media.Buffer _rgb_buf;\r
+ /**\r
+ * フォーマットアレイから、BGR24フォーマットを探す\r
+ * @param i_formats\r
+ * @return\r
+ */\r
+ private Format pickRGB24Format(Format[] i_formats)\r
+ {\r
+ for(int i=0;i<i_formats.length;i++){\r
+ RGBFormat f=(RGBFormat)i_formats[i];\r
+ if(f.getBitsPerPixel()!=24){\r
+ continue;\r
+ }\r
+ if(f.getRedMask()!=3 ||f.getGreenMask()!=2 ||f.getBlueMask()!=1 || f.getFlipped()!=0)\r
+ {\r
+ continue;\r
+ }\r
+ return f;\r
+ }\r
+ return null;\r
+ }\r
+ public NyARGLPixelReader_YUV(NyARIntSize i_ref_size,YUVFormat i_input_format) throws NyARException\r
+ {\r
+ this._ref_size=i_ref_size;\r
+ this.buffer_type=INyARRaster.BUFFERFORMAT_BYTE1D_B8G8R8_24;\r
+ this.buffer=null;\r
+ this._yuv2rgb=new YUVToRGB();\r
+ this._rgb_buf=new javax.media.Buffer();\r
+ //24bit-BGRフォーマットのものを探す\r
+ Format output_format=pickRGB24Format(this._yuv2rgb.getSupportedOutputFormats(i_input_format));\r
+ if(output_format==null){\r
+ throw new NyARException();\r
+ }\r
+ this._yuv2rgb.setInputFormat(i_input_format);\r
+ this._yuv2rgb.setOutputFormat(output_format);\r
+ try{\r
+ this._yuv2rgb.open();\r
+ }catch(Exception e){\r
+ throw new NyARException();\r
+ }\r
+ return;\r
+ }\r
+ public void setMediaBuffer(javax.media.Buffer i_buffer)\r
+ {\r
+ //エラー出した時のトラップ\r
+ if(this._yuv2rgb.process(i_buffer, this._rgb_buf)!=YUVToRGB.BUFFER_PROCESSED_OK){\r
+ System.err.println("YUVToRGB.process error:");\r
+ }\r
+ this.buffer=(byte[])this._rgb_buf.getData();\r
+ return;\r
+ }\r
+ public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
+ {\r
+ //IN :BGRBGR\r
+ // :012012\r
+ final int bp = (i_x + i_y * this._ref_size.w) * 3;\r
+ final byte[] ref = this.buffer;\r
+ o_rgb[0] = (ref[bp + 2] & 0xff);// R\r
+ o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[2] = (ref[bp + 0] & 0xff);// B\r
+ return;\r
+ }\r
+ public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
+ {\r
+ int bp;\r
+ final int width = this._ref_size.w;\r
+ final byte[] ref = this.buffer;\r
+ for (int i = i_num - 1; i >= 0; i--) {\r
+ bp = (i_x[i] + i_y[i] * width) * 3;\r
+ o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// R\r
+ o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
+ o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// B\r
+ }\r
+ return;\r
+ }\r
+ public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
+ }\r
+ public void switchBuffer(Object i_ref_object) throws NyARException\r
+ {\r
+ NyARException.notImplement(); \r
} \r
- return;\r
- }\r
}\r
+\r