Package net.sf.fmj.media.util

Source Code of net.sf.fmj.media.util.BufferToImage

package net.sf.fmj.media.util;

import java.awt.Point;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.ComponentSampleModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferUShort;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.WritableRaster;

import javax.media.Buffer;
import javax.media.Format;
import javax.media.format.RGBFormat;
import javax.media.format.VideoFormat;

/**
* Implementation of javax.media.util.BufferToImage.
* In progress
* @author Ken Larson
*
*/
public class BufferToImage
{
 
  // TODO: support new methods to create MemoryImageSource
  // TODO: optimize!
//  private final VideoFormat format;
//  private final int w;
//  private final int h;
//  private final Class dataType;
 
 
  public BufferToImage(VideoFormat format)
  { 
    if (format.getSize() == null)
      throw new NullPointerException()// this is what JMF does.
    // TODO: we should be able to get this info up front, and do some optimization
    // for down below.
   
    // TODO: in some cases, the size of the format might not be known up front?
    // this happens with the fleck bass solo video, with the JMF unknown handler.
//    this.format = format;
// 
//    w = format.getSize().width;
//    h = format.getSize().height;
//    dataType = format.getDataType();
  }

  public java.awt.Image createImage(Buffer buffer)
  {
    return createBufferedImage(buffer);
  }
 
  public BufferedImage createBufferedImage(Buffer buffer)
  { 
    final VideoFormat format;
    final int w;
    final int h;
    final Class dataType;
   
    format = (VideoFormat) buffer.getFormat();
   
    w = format.getSize().width;
    h = format.getSize().height;
    dataType = format.getDataType();
   
    if (format instanceof RGBFormat)
    {
      final RGBFormat rgbFormat = (RGBFormat) format;
      final int bitsPerPixel = rgbFormat.getBitsPerPixel();
      final int redMask = rgbFormat.getRedMask();
      final int greenMask = rgbFormat.getGreenMask();
      final int blueMask = rgbFormat.getBlueMask();
      final int lineStride = rgbFormat.getLineStride();
      final int pixelStride = rgbFormat.getPixelStride();
      final boolean flipped = rgbFormat.getFlipped() == 1;
     
      // TODO: check for -1s
     
      if (dataType == Format.byteArray)
      {
        final byte[] bytes = (byte[]) buffer.getData();
        if (bitsPerPixel == 24)
        {
          // this is much faster than iterating through the pixels.
          // if we create a writable raster and then construct a buffered image,
          // no new array is created and no data is copied.
          // TODO: optimize other cases.
          final DataBufferByte db = new DataBufferByte(new byte[][] {bytes}, bytes.length);
          final ComponentSampleModel sm = new ComponentSampleModel(DataBuffer.TYPE_BYTE, w, h, pixelStride, lineStride, new int[] {redMask - 1, greenMask -1, blueMask -1});
          final WritableRaster r = Raster.createWritableRaster(sm, db, new Point(0, 0));
          // construction borrowed from BufferedImage constructor, for BufferedImage.TYPE_3BYTE_BGR
                  final ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
                  int[] nBits = {8, 8, 8};
                  //int[] bOffs = {2, 1, 0};
                  final ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
                                                       Transparency.OPAQUE,
                                                       DataBuffer.TYPE_BYTE);
                  final BufferedImage bi = new BufferedImage(colorModel, r, false, null);
          return bi;
        }
        else if (bitsPerPixel == 32)
        {
          final DataBufferByte db = new DataBufferByte(new byte[][] {bytes}, bytes.length);
          final ComponentSampleModel sm = new ComponentSampleModel(DataBuffer.TYPE_BYTE, w, h, pixelStride, lineStride, new int[] {redMask - 1, greenMask -1, blueMask -1, 3})// TODO: what to do with alpha?
          final WritableRaster r = Raster.createWritableRaster(sm, db, new Point(0, 0));
          // construction borrowed from BufferedImage constructor, for BufferedImage.TYPE_4BYTE_ABGR
                  final ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
                  int[] nBits = {8, 8, 8, 8};
                  //int[] bOffs = {3, 2, 1, 0};
                  final ColorModel colorModel = new ComponentColorModel(cs, nBits, true, false,
                                                       Transparency.TRANSLUCENT,
                                                       DataBuffer.TYPE_BYTE);
                  final BufferedImage bi = new BufferedImage(colorModel, r, false, null);
          return bi;
        }
        else if (bitsPerPixel == 8)
        {
          final DataBufferByte db = new DataBufferByte(new byte[][] {bytes}, bytes.length);
          final SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE, w, h, lineStride, new int[] {redMask, greenMask, blueMask});
          final WritableRaster r = Raster.createWritableRaster(sm, db, new Point(0, 0));
                  final ColorModel colorModel = new DirectColorModel(bitsPerPixel, redMask, greenMask, blueMask);
                  final BufferedImage bi = new BufferedImage(colorModel, r, false, null);
          return bi;
        }
        else
        {
          final BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
          final int [] pixels = new int[w * h];
          int pixelIndex = 0;
          int lineOffset = 0;
          if (flipped)
            lineOffset = (h - 1) * lineStride;
         
          for (int y = 0; y < h; ++y)
          {
            int off = lineOffset;
            for (int x = 0; x < w; ++x)
            {
              final byte r = bytes[off + redMask - 1];
              final byte g = bytes[off + greenMask - 1];
              final byte b = bytes[off + blueMask - 1];
              int pixel = 0;
              pixel += r & 0xff// red
              pixel *= 256;
              pixel += g & 0xff; // green
              pixel *= 256;
              pixel += b & 0xff// blue
              pixels[pixelIndex++] = pixel;
              off += pixelStride;
            }
            if (flipped)
              lineOffset -= lineStride;
            else
              lineOffset += lineStride;
          }
         
          bi.setRGB(0,0,w,h,pixels,0,w);
          return bi;
        }

       
      }else if (dataType == Format.shortArray) {
        final short[] shorts = (short[]) buffer.getData();
        if (bitsPerPixel == 16)
        {
          final DataBufferUShort db = new DataBufferUShort(new short[][] {shorts}, shorts.length);
          final SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_USHORT, w, h, lineStride, new int[] {redMask, greenMask, blueMask});
          final WritableRaster r = Raster.createWritableRaster(sm, db, new Point(0, 0));
                  final ColorModel colorModel = new DirectColorModel(bitsPerPixel, redMask, greenMask, blueMask);
                  final BufferedImage bi = new BufferedImage(colorModel, r, false, null);
          return bi;
        }else{
          throw new UnsupportedOperationException()// TODO
        }
      }
      else if (dataType == Format.intArray)
      {
//        if (true)
        {
          // optimized, don't copy data or iterate through pixels:
          final int[] bytes = (int[]) buffer.getData();
          final DataBufferInt db = new DataBufferInt(new int[][] {bytes}, bytes.length);
          final SinglePixelPackedSampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, w, h, new int[] {redMask, greenMask, blueMask});
          final WritableRaster r = Raster.createWritableRaster(sm, db, new Point(0, 0));
         
                  final ColorModel colorModel = new DirectColorModel(24,
                            redMask,   // Red
                            greenMask,  // Green
                            blueMask,   // Blue
                            0x0         // Alpha
                            );
                  final BufferedImage bi = new BufferedImage(colorModel, r, false, null);
          return bi;
                 
        }
//        else
//        {
//          // old way, slow:
//          final int[] bytes = (int[]) buffer.getData();
//          {
//            final int bufferedImageType;
//            if (redMask < greenMask)
//              bufferedImageType = BufferedImage.TYPE_INT_BGR;
//            else
//              bufferedImageType = BufferedImage.TYPE_INT_RGB;
//             
//            final BufferedImage bi = new BufferedImage(w, h, bufferedImageType);
//            final int [] pixels = new int[w * h];
//            int pixelIndex = 0;
//            int lineOffset = 0;
//            if (flipped)
//              lineOffset = (h - 1) * lineStride;
//           
//            for (int y = 0; y < h; ++y)
//            {
//              int off = lineOffset;
//              for (int x = 0; x < w; ++x)
//              {
//                int srcpixel = bytes[off];
//                final byte r = (byte) ((srcpixel & redMask) >> shiftValue(redMask));
//                final byte g = (byte) ((srcpixel & greenMask) >> shiftValue(greenMask));
//                final byte b = (byte) ((srcpixel & blueMask) >> shiftValue(blueMask));
//               
//                int pixel = 0;
//                pixel += r & 0xff;  // red
//                pixel *= 256;
//                pixel += g & 0xff; // green
//                pixel *= 256;
//                pixel += b & 0xff;  // blue
//                pixels[pixelIndex++] = pixel;
//                off += pixelStride;
//              }
//              if (flipped)
//                lineOffset -= lineStride;
//              else
//                lineOffset += lineStride;
//            }
//           
//            bi.setRGB(0,0,w,h,pixels,0,w);
//            return bi;
//          }
//        }
      }
      else
      {
        throw new UnsupportedOperationException()// TODO
      }
     
    }
    else
      throw new UnsupportedOperationException()// TODO
  }
 
//  private static int shiftValue(int mask)
//  {
//    if (mask == 0xFF)
//      return 0;
//    else if (mask == 0xFF00)
//      return 8;
//    else if (mask == 0xFF0000)
//      return 16;
//    else
//      throw new IllegalArgumentException("mask=" + mask); // TODO
//   
//  }
}
TOP

Related Classes of net.sf.fmj.media.util.BufferToImage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.