Package com.t4l.jmf

Source Code of com.t4l.jmf.CustomByteArrayOutputStream

package com.t4l.jmf;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.media.Buffer;
import javax.media.Codec;
import javax.media.Format;
import javax.media.PlugIn;
import javax.media.ResourceUnavailableException;
import javax.media.format.JPEGFormat;
import javax.media.format.RGBFormat;
import javax.media.format.VideoFormat;

import net.sf.fmj.utility.LoggerSingleton;

/**
* This type of MOV file just stores frames as a series of JPEG
* images.
* This codec uses ImageIO classes to convert from the jpeg VideoFormat
* to RGBFormats.
* @author Jeremy Wood
*/
public class JPEGEncoder implements Codec {
  private static final Logger logger = LoggerSingleton.logger;

  private static final VideoFormat jpegFormat = new JPEGFormat();
  private static final RGBFormat rgbFormat = new RGBFormat(null, -1, Format.intArray, -1.f, -1, -1, -1, -1);
 

  public Format[] getSupportedInputFormats() {
    return new VideoFormat[] { rgbFormat };
  }

  public Format[] getSupportedOutputFormats(Format input) {
    if (input == null)
      return new VideoFormat[] { jpegFormat };

    if(input.relax().matches(rgbFormat)) {
      final VideoFormat inputVideoFormat = (VideoFormat) input;
      return new VideoFormat[] { new JPEGFormat(inputVideoFormat.getSize(), -1, Format.byteArray, inputVideoFormat.getFrameRate(), -1, -1) };
    }
    return new Format[] {};
  }

  public int process(Buffer input, Buffer output) {
    Format inputFormat = input.getFormat();
    Format outputFormat = output.getFormat();
   
    if(inputFormat.relax().matches(rgbFormat) && outputFormat.relax().matches(jpegFormat)) {
      return processRGBtoJPEG(input,output);
    }
    return PlugIn.BUFFER_PROCESSED_FAILED;
  }
  static Hashtable imageTable = new Hashtable();
  protected int processRGBtoJPEG(Buffer input,Buffer output) {
    synchronized(imageTable) {
      try {
        RGBFormat inputFormat = (RGBFormat)input.getFormat();
        VideoFormat outputFormat = (VideoFormat)output.getFormat();
       
        if(outputFormat==null) {
          int width = inputFormat.getSize().width;
          int height = inputFormat.getSize().height;
          outputFormat = new JPEGFormat(
              new Dimension(width,height),
              width*height+200, //surely this is the max size, right?
              Format.byteArray,
              inputFormat.getFrameRate(),
              -1// TODO: specify quality
              -1); // TODO: specify decimation
          output.setFormat(outputFormat);
        }
       
        int[] data = (int[])input.getData();
       
        Dimension d = inputFormat.getSize();
        BufferedImage dest = (BufferedImage)imageTable.get(d);
        if(dest==null) {
          dest = new BufferedImage(d.width,d.height,BufferedImage.TYPE_INT_RGB);
        }
        RGBConverter.populateImage(data, input.getOffset(), dest, inputFormat);
       
        byte[] bytes;

        Object obj = output.getData();
        if(obj instanceof byte[]) {
          bytes = (byte[])obj;
        } else {
          bytes = new byte[d.width*d.height+200];
          output.setData(bytes);
        }
       
        int length = writeJPEG(dest, bytes);
       
        imageTable.put(d, dest);
       
        output.setLength(length);
       
        output.setDiscard(input.isDiscard());
        output.setDuration(input.getDuration());
        output.setEOM(input.isEOM());
        output.setFlags(input.getFlags()); //is this correct?
        output.setHeader(null);
        output.setTimeStamp(input.getTimeStamp());
        output.setSequenceNumber(input.getSequenceNumber());
        output.setOffset(0);
        return PlugIn.BUFFER_PROCESSED_OK;
      } catch(Throwable t) {
        logger.log(Level.WARNING, "" + t, t);
        return PlugIn.BUFFER_PROCESSED_FAILED;
      }
    }
  }
 

  /**
   *
   * @param image
   * @param data
   * @return the number if bytes written in the array
   * @throws IOException
   */
  protected static int writeJPEG(BufferedImage image,byte[] data) throws IOException {
    ImageWriter iw = (ImageWriter)ImageIO.getImageWritersByMIMEType("image/jpeg").next();
    ImageWriteParam iwParam = iw.getDefaultWriteParam();
    float quality = .8f;
    iwParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    iwParam.setCompressionQuality(quality);
    CustomByteArrayOutputStream out = new CustomByteArrayOutputStream(data);
    iw.setOutput(out);
   
    IIOImage img = new IIOImage(image, null, null);
   
    iw.write(null, img, iwParam);
    return out.getBytesWritten();
  }

  public Format setInputFormat(Format f) {
    //we don't do anything here; just return positive feedback that we
    //can in fact handle whatever it gives us
    if(f.relax().matches(rgbFormat)) {
      return f;
    }
    return null;
  }

  public Format setOutputFormat(Format f) {
    //we don't do anything here; just return positive feedback that we
    //can in fact handle whatever it gives us
    if(f.relax().matches(jpegFormat)) {
      return f;
    }
    return null;
  }

  public void close() {
    synchronized(imageTable) {
      imageTable.clear();
    }
  }

  public String getName() {
    return "JPEG Encoder";
  }

  public void open() throws ResourceUnavailableException {}

  public void reset() {}

  public Object getControl(String controlType) {
    return null;
  }

  public Object[] getControls() {
    return new String[] {};
  }
}

class CustomByteArrayOutputStream extends OutputStream {
  int ctr = 0;
  byte[] data;
 
  public CustomByteArrayOutputStream(byte[] b) {
    data = b;
  }
 
  public int getBytesWritten() {
    return ctr;
  }

  public void write(byte[] b, int offset, int len) throws IOException {
    System.arraycopy(data,ctr,b,offset,len);
    ctr+=len;
  }

  public void write(byte[] b) throws IOException {
    write(b,0,b.length);
  }

  public void write(int b) throws IOException {
    data[ctr] = (byte)b;
    ctr++;
  }
}
TOP

Related Classes of com.t4l.jmf.CustomByteArrayOutputStream

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.