You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
8.0 KiB
220 lines
8.0 KiB
5 years ago
|
package com.fr.third.JAI;
|
||
|
/*
|
||
|
* Copyright (c) 2001 Sun Microsystems, Inc. All Rights Reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are met:
|
||
|
*
|
||
|
* -Redistributions of source code must retain the above copyright notice, this
|
||
|
* list of conditions and the following disclaimer.
|
||
|
*
|
||
|
* -Redistribution in binary form must reproduct the above copyright notice,
|
||
|
* this list of conditions and the following disclaimer in the documentation
|
||
|
* and/or other materials provided with the distribution.
|
||
|
*
|
||
|
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
|
||
|
* be used to endorse or promote products derived from this software without
|
||
|
* specific prior written permission.
|
||
|
*
|
||
|
* This software is provided "AS IS," without a warranty of any kind. ALL
|
||
|
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
|
||
|
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
|
||
|
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
|
||
|
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
||
|
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
|
||
|
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
|
||
|
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
|
||
|
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
|
||
|
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
|
||
|
* POSSIBILITY OF SUCH DAMAGES.
|
||
|
*
|
||
|
* You acknowledge that Software is not designed,licensed or intended for use in
|
||
|
* the design, construction, operation or maintenance of any nuclear facility.
|
||
|
*/
|
||
|
import java.awt.Point;
|
||
|
import java.awt.color.ColorSpace;
|
||
|
import java.awt.image.BufferedImage;
|
||
|
import java.awt.image.ColorModel;
|
||
|
import java.awt.image.IndexColorModel;
|
||
|
import java.awt.image.DataBuffer;
|
||
|
import java.awt.image.WritableRaster;
|
||
|
import java.awt.image.RenderedImage;
|
||
|
import java.awt.image.SampleModel;
|
||
|
import java.io.IOException;
|
||
|
import java.io.OutputStream;
|
||
|
|
||
|
//
|
||
|
// Need these classes since we are currently using the
|
||
|
// Java2D JpegEncoder for our Jpeg Implementation.
|
||
|
//
|
||
|
import com.sun.image.codec.jpeg.JPEGQTable;
|
||
|
import com.sun.image.codec.jpeg.JPEGDecodeParam;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* An ImageEncoder for the JPEG (JFIF) file format.
|
||
|
*
|
||
|
* The common cases of single band grayscale and three or four band RGB images
|
||
|
* are handled so as to minimize the amount of information required of the
|
||
|
* programmer. See the comments pertaining to the constructor and the
|
||
|
* <code>writeToStream()</code> method for more detailed information.
|
||
|
*
|
||
|
*/
|
||
|
public class JPEGImageEncoder extends ImageEncoderImpl {
|
||
|
|
||
|
private JPEGEncodeParam jaiEP = null;
|
||
|
|
||
|
public JPEGImageEncoder(OutputStream output,
|
||
|
ImageEncodeParam param) {
|
||
|
super(output, param);
|
||
|
if (param != null) {
|
||
|
jaiEP = (JPEGEncodeParam)param;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Go through the settable encoding parameters and see
|
||
|
// if any of them have been set. If so, transfer then to the
|
||
|
// com.sun.image.codec.jpeg.JPEGEncodeParam object.
|
||
|
//
|
||
|
static void modifyEncodeParam(JPEGEncodeParam jaiEP,
|
||
|
com.sun.image.codec.jpeg.JPEGEncodeParam j2dEP,
|
||
|
int nbands) {
|
||
|
|
||
|
int val;
|
||
|
int[] qTab;
|
||
|
for(int i=0; i<nbands; i++) {
|
||
|
//
|
||
|
// If subsampling factors were set, apply them
|
||
|
//
|
||
|
val = jaiEP.getHorizontalSubsampling(i);
|
||
|
j2dEP.setHorizontalSubsampling(i, val);
|
||
|
|
||
|
val = jaiEP.getVerticalSubsampling(i);
|
||
|
j2dEP.setVerticalSubsampling(i, val);
|
||
|
|
||
|
//
|
||
|
// If new Q factors were supplied, apply them
|
||
|
//
|
||
|
if (jaiEP.isQTableSet(i)) {
|
||
|
qTab = jaiEP.getQTable(i);
|
||
|
val = jaiEP.getQTableSlot(i);
|
||
|
j2dEP.setQTableComponentMapping(i, val);
|
||
|
j2dEP.setQTable(val, new JPEGQTable(qTab));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Apply new quality, if set
|
||
|
if (jaiEP.isQualitySet()) {
|
||
|
float fval = jaiEP.getQuality();
|
||
|
j2dEP.setQuality(fval, true);
|
||
|
}
|
||
|
|
||
|
// Apply new restart interval, if set
|
||
|
val = jaiEP.getRestartInterval();
|
||
|
j2dEP.setRestartInterval(val);
|
||
|
|
||
|
// Write a tables-only abbreviated JPEG file
|
||
|
if (jaiEP.getWriteTablesOnly() == true) {
|
||
|
j2dEP.setImageInfoValid(false);
|
||
|
j2dEP.setTableInfoValid(true);
|
||
|
}
|
||
|
|
||
|
// Write an image-only abbreviated JPEG file
|
||
|
if (jaiEP.getWriteImageOnly() == true) {
|
||
|
j2dEP.setTableInfoValid(false);
|
||
|
j2dEP.setImageInfoValid(true);
|
||
|
}
|
||
|
|
||
|
// Write the JFIF (APP0) marker
|
||
|
if (jaiEP.getWriteJFIFHeader() == false) {
|
||
|
j2dEP.setMarkerData(
|
||
|
com.sun.image.codec.jpeg.JPEGDecodeParam.APP0_MARKER, null);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Encodes a RenderedImage and writes the output to the
|
||
|
* OutputStream associated with this ImageEncoder.
|
||
|
*/
|
||
|
public void encode(RenderedImage im) throws IOException {
|
||
|
//
|
||
|
// Check data type and band count compatibility.
|
||
|
// This implementation handles only 1 and 3 band source images.
|
||
|
//
|
||
|
SampleModel sampleModel = im.getSampleModel();
|
||
|
ColorModel colorModel = im.getColorModel();
|
||
|
|
||
|
// Must be a 1 or 3 component BYTE image
|
||
|
int numBands = colorModel.getNumColorComponents();
|
||
|
int transType = sampleModel.getTransferType();
|
||
|
if ((transType != DataBuffer.TYPE_BYTE) ||
|
||
|
((numBands != 1) && (numBands != 3) )) {
|
||
|
throw new RuntimeException(JaiI18N.getString("JPEGImageEncoder0"));
|
||
|
}
|
||
|
|
||
|
// Must be GRAY or RGB
|
||
|
int cspaceType = colorModel.getColorSpace().getType();
|
||
|
if (cspaceType != ColorSpace.TYPE_GRAY &&
|
||
|
cspaceType != ColorSpace.TYPE_RGB) {
|
||
|
throw new Error(JaiI18N.getString("JPEGImageEncoder1"));
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create a BufferedImage to be encoded.
|
||
|
// The JPEG interfaces really need a whole image.
|
||
|
//
|
||
|
WritableRaster wRas;
|
||
|
BufferedImage bi;
|
||
|
|
||
|
//
|
||
|
// Get a contiguous raster. Jpeg compression can't work
|
||
|
// on tiled data in most cases.
|
||
|
// Also need to be sure that the raster doesn't have a
|
||
|
// non-zero origin, since BufferedImage won't accept that.
|
||
|
// (Bug ID 4253990)
|
||
|
//
|
||
|
wRas = (WritableRaster)im.getData();
|
||
|
if (wRas.getMinX() != 0 || wRas.getMinY() != 0) {
|
||
|
wRas = wRas.createWritableTranslatedChild(0, 0);
|
||
|
}
|
||
|
|
||
|
// First create the Java2D encodeParam based on the BufferedImage
|
||
|
com.sun.image.codec.jpeg.JPEGEncodeParam j2dEP = null;
|
||
|
if (colorModel instanceof IndexColorModel) {
|
||
|
//
|
||
|
// Need to expand the indexed data to components.
|
||
|
// The convertToIntDiscrete method is used to perform this.
|
||
|
//
|
||
|
IndexColorModel icm = (IndexColorModel)colorModel;
|
||
|
bi = icm.convertToIntDiscrete(wRas, false);
|
||
|
j2dEP = com.sun.image.codec.jpeg.JPEGCodec.getDefaultJPEGEncodeParam(bi);
|
||
|
} else {
|
||
|
bi = new BufferedImage(colorModel, wRas, false, null);
|
||
|
j2dEP = com.sun.image.codec.jpeg.JPEGCodec.getDefaultJPEGEncodeParam(bi);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Now modify the Java2D encodeParam based on the options set
|
||
|
// in the JAI encodeParam object.
|
||
|
if (jaiEP != null) {
|
||
|
modifyEncodeParam(jaiEP, j2dEP, numBands);
|
||
|
}
|
||
|
|
||
|
// Now create the encoder with the modified Java2D encodeParam
|
||
|
com.sun.image.codec.jpeg.JPEGImageEncoder encoder;
|
||
|
encoder = com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(
|
||
|
output, j2dEP);
|
||
|
|
||
|
try {
|
||
|
// Write the image data.
|
||
|
encoder.encode(bi);
|
||
|
} catch(IOException e) {
|
||
|
throw new RuntimeException(e.getMessage());
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|