Package hipi.image.io

Source Code of hipi.image.io.JPEGImageUtil

package hipi.image.io;

import hipi.image.FloatImage;
import hipi.image.ImageHeader;
import hipi.image.ImageHeader.ImageType;

import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;

import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;

public class JPEGImageUtil implements ImageDecoder, ImageEncoder {
 
  private static final JPEGImageUtil static_object = new JPEGImageUtil();
 
  public static JPEGImageUtil getInstance() {
    return static_object;
  }

  @SuppressWarnings("rawtypes")
  public ImageHeader decodeImageHeader(InputStream is) throws IOException {
    ImageHeader header = new ImageHeader(ImageType.JPEG_IMAGE);
    try {
      DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
      dis.mark(Integer.MAX_VALUE);
      short magic = dis.readShort();
      if (magic != -40)
        return null;
      byte[] data = new byte[6];
      // read in each block to find width / height / bitDepth
      for (;;) {
        dis.read(data, 0, 4);
        if ((data[0] & 0xff) != 0xff)
          return null;
        if ((data[1] & 0xff) == 0x01 || ((data[1] & 0xff) >= 0xd0 && (data[1] & 0xff) <= 0xd7))
          continue;
        long length = (((data[2] & 0xff) << 8) | (data[3] & 0xff)) - 2;
        if ((data[1] & 0xff) != 0xc0) {
          while (length > 0) {
            long skipped = dis.skip(length);
            if (skipped == 0)
              break;
            length -= skipped;
          }
        } else {
          dis.read(data);
          header.height = ((data[1] & 0xff) << 8) | (data[2] & 0xff);
          header.width = ((data[3] & 0xff) << 8) | (data[4] & 0xff);
          header.bitDepth = data[0] & 0xff;
          break;
        }
      }
      dis.reset();
      MetadataReader reader = new MetadataReader(dis);
      Metadata metadata = reader.extract();
      Iterator directories = metadata.getDirectoryIterator();
      while (directories.hasNext()) {
        Directory directory = (Directory)directories.next();
        Iterator tags = directory.getTagIterator();
        while (tags.hasNext()) {
          Tag tag = (Tag)tags.next();
          header.addEXIFInformation(tag.getTagName(), tag.getDescription());
        }
      }
    } catch (Exception e) {
    }
    return header;
  }

  public FloatImage decodeImage(InputStream is) throws IOException {
    ImageInputStream iis = ImageIO.createImageInputStream(is);
    Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("jpeg");
    ImageReader reader = readers.next();
    if (!reader.canReadRaster()) {
      while (readers.hasNext()) {
        reader = readers.next();
        if (reader.canReadRaster())
          break;
      }
    }
    reader.setInput(iis);
    Raster raster = reader.readRaster(0, new ImageReadParam());
    DataBuffer dataBuffer = raster.getDataBuffer();
    int w = raster.getWidth();
    int h = raster.getHeight();
    float[] pels = new float[w * h * 3];
    if (raster.getNumBands() == 4) {
      for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++) {
          int Y = dataBuffer.getElem(i * w * 4 + j * 4);
          int Cr = dataBuffer.getElem(i * w * 4 + j * 4 + 1);
          int Cb = dataBuffer.getElem(i * w * 4 + j * 4 + 2);
          int c = (int)Math.min(Math.max(Y + 1.772 * (Cb - 128), 0), 255);
          int m = (int)Math.min(Math.max(Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128), 0), 255);
          int y = (int)Math.min(Math.max(Y + 1.402 * (Cr - 128), 0), 255);
          int k = dataBuffer.getElem(i * w * 4 + j * 4 + 3);
          pels[i* w * 3 + j * 3] = (float) ((k - (c * k >> 8)) / 255.0);
          pels[i* w * 3 + j * 3 + 1] = (float) ((k - (m * k >> 8)) / 255.0);
          pels[i* w * 3 + j * 3 + 2] = (float) ((k - (y * k >> 8)) / 255.0);
        }
    } else if (raster.getNumBands() == 3) {
      for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++) {
          int Y = dataBuffer.getElem(i * w * 3 + j * 3);
          int Cr = dataBuffer.getElem(i * w * 3 + j * 3 + 1);
          int Cb = dataBuffer.getElem(i * w * 3 + j * 3 + 2);
          pels[i* w * 3 + j * 3] = (float) ((Math.min(Math.max(Y + 1.772f * (Cb - 128), 0), 255)) / 255.0);
          pels[i* w * 3 + j * 3 + 1] = (float) ((Math.min(Math.max(Y - 0.34414f * (Cb - 128) - 0.71414f * (Cr - 128), 0), 255)) / 255.0);
          pels[i* w * 3 + j * 3 + 2] = (float) ((Math.min(Math.max(Y + 1.402f * (Cr - 128), 0), 255)) / 255.0);
        }
    } else if (raster.getNumBands() == 1) {
      for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++) {
          int Y = dataBuffer.getElem(i * w + j);
          pels[i* w * 3 + j * 3] = (float) (Y / 255.0);
          pels[i* w * 3 + j * 3 + 1] = (float) (Y / 255.0);
          pels[i* w * 3 + j * 3 + 2] = (float) (Y / 255.0);
        }
    }
    FloatImage image = new FloatImage(w, h, 3, pels);
    return image;
  }

  public void encodeImage(FloatImage image, ImageHeader header, OutputStream os)
      throws IOException {
    ImageOutputStream ios = ImageIO.createImageOutputStream(os);
    Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpeg");
    ImageWriter writer = writers.next();
    writer.setOutput(ios);
    BufferedImage bufferedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
    float[] data = image.getData();
    int[] rgb = new int[image.getWidth() * image.getHeight()];
    for (int i = 0; i < image.getWidth() * image.getHeight(); i++)
    {
      int r = Math.min(Math.max((int)(data[i * 3] * 255), 0), 255);
      int g = Math.min(Math.max((int)(data[i * 3 + 1] * 255), 0), 255);
      int b = Math.min(Math.max((int)(data[i * 3 + 2] * 255), 0), 255);
      rgb[i] = r << 16 | g << 8 | b;
    }
    bufferedImage.setRGB(0, 0, image.getWidth(), image.getHeight(), rgb, 0, image.getWidth());
    IIOImage iioImage = new IIOImage(bufferedImage, null, null);
    ImageWriteParam param = writer.getDefaultWriteParam();
    writer.write(null, iioImage, param);
  }

  public ImageHeader createSimpleHeader(FloatImage image) {
    return new ImageHeader(ImageType.JPEG_IMAGE);
  }

}
TOP

Related Classes of hipi.image.io.JPEGImageUtil

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.