FileDocCategorySizeDatePackage
JPEGImageWriter.javaAPI DocAndroid 1.5 API13224Wed May 06 22:41:54 BST 2009org.apache.harmony.x.imageio.plugins.jpeg

JPEGImageWriter

public class JPEGImageWriter extends ImageWriter
author
Rustem V. Rafikov
version
$Revision: 1.3 $

Fields Summary
private static final boolean
DEBUG
private static android.graphics.Bitmap
bm
private static BufferedImage
bufImg
private static RenderedImage
renImg
private long
cinfo
private RenderedImage
image
private Raster
sourceRaster
private WritableRaster
scanRaster
private int
srcXOff
private int
srcYOff
private int
srcWidth
private int
srcHeight
private int
deltaY
private int
deltaX
private ImageOutputStream
ios
Constructors Summary
public JPEGImageWriter(ImageWriterSpi imageWriterSpi)


       
        super(imageWriterSpi);
        //???AWT: cinfo = initCompressionObj();
        cinfo = System.currentTimeMillis();
    
Methods Summary
public javax.imageio.metadata.IIOMetadataconvertImageMetadata(javax.imageio.metadata.IIOMetadata iioMetadata, javax.imageio.ImageTypeSpecifier imageTypeSpecifier, javax.imageio.ImageWriteParam imageWriteParam)

        throw new UnsupportedOperationException("not supported yet");
    
public javax.imageio.metadata.IIOMetadataconvertStreamMetadata(javax.imageio.metadata.IIOMetadata iioMetadata, javax.imageio.ImageWriteParam imageWriteParam)

        throw new UnsupportedOperationException("not supported yet");
    
public voiddispose()

        super.dispose();
        if (cinfo != 0) {
            //???AWT: dispose(cinfo);
            cinfo = 0;
            ios = null;
        }
    
public static android.graphics.BitmapgetBitmap()

        
        return bm;
    
public static java.awt.image.BufferedImagegetBufImage()

        return bufImg;
    
public javax.imageio.metadata.IIOMetadatagetDefaultImageMetadata(javax.imageio.ImageTypeSpecifier imageTypeSpecifier, javax.imageio.ImageWriteParam imageWriteParam)

        throw new UnsupportedOperationException("not supported yet");
    
public javax.imageio.metadata.IIOMetadatagetDefaultStreamMetadata(javax.imageio.ImageWriteParam imageWriteParam)

        throw new UnsupportedOperationException("not supported yet");
    
public javax.imageio.ImageWriteParamgetDefaultWriteParam()

        return new JPEGImageWriteParam(getLocale());
    
private intgetDestinationCSType(java.awt.image.RenderedImage image)
Returns destination color space. (YCbCr[A] for RGB)

param
image
return

        int type = JPEGConsts.JCS_UNKNOW;
        ColorModel cm = image.getColorModel();
        if (null != cm) {
            boolean hasAlpha = cm.hasAlpha();
            ColorSpace cs = cm.getColorSpace();

            switch(cs.getType()) {
                case ColorSpace.TYPE_GRAY:
                    type = JPEGConsts.JCS_GRAYSCALE;
                    break;
               case ColorSpace.TYPE_RGB:
                    type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
                    break;
               case ColorSpace.TYPE_YCbCr:
                    type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
                    break;
               case ColorSpace.TYPE_3CLR:
                     type = hasAlpha ? JPEGConsts.JCS_YCCA : JPEGConsts.JCS_YCC;
                     break;
               case ColorSpace.TYPE_CMYK:
                      type = JPEGConsts.JCS_CMYK;
                      break;
            }
        }
        return type;
    
public static java.awt.image.RenderedImagegetRenImage()

        return renImg;
    
private voidgetScanLine(int scanline)
Callback for getting a next scanline

param
scanline scan line number

        //-- TODO: processImageProgress in ImageWriter
        Raster child = sourceRaster.createChild(srcXOff,
                srcYOff + scanline * deltaY, srcWidth, 1, 0, 0, null);

        scanRaster.setRect(child);
    
private intgetSourceCSType(java.awt.image.RenderedImage image)
Maps color space types to IJG color spaces

param
image
return

        int type = JPEGConsts.JCS_UNKNOW;
        ColorModel cm = image.getColorModel();

        if (null == cm) {
            return type;
        }

        if (cm instanceof IndexColorModel) {
            throw new UnsupportedOperationException("IndexColorModel is not supported yet");
        }

        boolean hasAlpha = cm.hasAlpha();
        ColorSpace cs = cm.getColorSpace();
        switch(cs.getType()) {
            case ColorSpace.TYPE_GRAY:
                type = JPEGConsts.JCS_GRAYSCALE;
                break;
           case ColorSpace.TYPE_RGB:
                type = hasAlpha ? JPEGConsts.JCS_RGBA : JPEGConsts.JCS_RGB;
                break;
           case ColorSpace.TYPE_YCbCr:
                type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
                break;
           case ColorSpace.TYPE_3CLR:
                 type = hasAlpha ? JPEGConsts.JCS_YCCA : JPEGConsts.JCS_YCC;
                 break;
           case ColorSpace.TYPE_CMYK:
                  type = JPEGConsts.JCS_CMYK;
                  break;
        }
        return type;
    
public voidsetOutput(java.lang.Object output)

        super.setOutput(output);
        ios = (ImageOutputStream) output;
        //???AWT: setIOS(ios, cinfo);
        sourceRaster = null;
        scanRaster = null;
        srcXOff = 0;
        srcYOff = 0;
        srcWidth = 0;
        srcHeight = 0;
        deltaY = 1;
    
public voidwrite(javax.imageio.metadata.IIOMetadata iioMetadata, javax.imageio.IIOImage iioImage, javax.imageio.ImageWriteParam param)

        //???AWT
        /*
        System.loadLibrary("jpegencoder");
        initWriterIds(ImageOutputStream.class);
        */
    

        if (ios == null) {
            throw new IllegalArgumentException("ios == null");
        }
        if (iioImage == null) {
            throw new IllegalArgumentException("Image equals null");
        }

        RenderedImage img = null;
        if (!iioImage.hasRaster()) {
            img = iioImage.getRenderedImage();
            if (img instanceof BufferedImage) {
                sourceRaster = ((BufferedImage) img).getRaster();
            } else {
                sourceRaster = img.getData();
            }
        } else {
            sourceRaster = iioImage.getRaster();
        }
        
        // AWT???: Debugging
        if (DEBUG) {
            if( img==null ) {
                System.out.println("****J: Image is NULL");
            } else {
                renImg = img;
                bufImg = (BufferedImage)img;
            }
        }

        int numBands = sourceRaster.getNumBands();
        int sourceIJGCs = img == null ? JPEGConsts.JCS_UNKNOW : getSourceCSType(img);

        srcWidth = sourceRaster.getWidth();
        srcHeight = sourceRaster.getHeight();

        int destWidth = srcWidth;
        int destHeight = srcHeight;

        boolean progressive = false;
         
        if (param != null) {
            Rectangle reg = param.getSourceRegion();
            if (reg != null) {
                srcXOff = reg.x;
                srcYOff = reg.y;

                srcWidth = reg.width + srcXOff > srcWidth
                        ? srcWidth - srcXOff
                        : reg.width;
                srcHeight = reg.height + srcYOff > srcHeight
                        ? srcHeight - srcYOff
                        : reg.height;
            }

            //-- TODO uncomment when JPEGImageWriteParam be implemented
            //-- Only default progressive mode yet
            // progressive = param.getProgressiveMode() ==  ImageWriteParam.MODE_DEFAULT;

            //-- def is 1
            deltaX = param.getSourceXSubsampling();
            deltaY = param.getSourceYSubsampling();

            //-- def is 0
            int offsetX = param.getSubsamplingXOffset();
            int offsetY = param.getSubsamplingYOffset();

            srcXOff += offsetX;
            srcYOff += offsetY;
            srcWidth -= offsetX;
            srcHeight -= offsetY;

            destWidth = (srcWidth + deltaX - 1) / deltaX;
            destHeight = (srcHeight + deltaY - 1) / deltaY;
        }

        //-- default DQTs (see JPEGQTable java doc and JPEG spec K1 & K2 tables)
        //-- at http://www.w3.org/Graphics/JPEG/itu-t81.pdf
        //-- Only figuring out how to set DQT in IJG library for future metadata
        //-- support. IJG def tables are the same.
        //JPEGQTable[] dqt = new JPEGQTable[2];
//        int[][] dqt = null;
//        int[][] dqt = new int[2][];
//        dqt[0] = JPEGQTable.K1Div2Luminance.getTable();
//        dqt[1] = JPEGQTable.K2Div2Chrominance.getTable();
        
        //???AWT: I think we don't need this amymore
        /*
        //-- using default color space
        //-- TODO: Take destination cs from param or use default if there is no cs
        int destIJGCs = img == null ? JPEGConsts.JCS_UNKNOW : getDestinationCSType(img);

        DataBufferByte dbuffer = new DataBufferByte(numBands * srcWidth);

        scanRaster = Raster.createInterleavedRaster(dbuffer, srcWidth, 1,
                numBands * srcWidth, numBands, JPEGConsts.BAND_OFFSETS[numBands], null);

        encode(dbuffer.getData(), srcWidth, destWidth, destHeight, deltaX,
                sourceIJGCs, destIJGCs, numBands, progressive,
                null, cinfo);
        */
        
        SampleModel model = sourceRaster.getSampleModel();
        
        if (model instanceof SinglePixelPackedSampleModel) {
            DataBufferInt ibuf = (DataBufferInt)sourceRaster.getDataBuffer();
            int[] pixels = ibuf.getData();
            
            // Create a bitmap with the pixel
            bm = Bitmap.createBitmap(pixels, srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
            
            // Use Bitmap.compress() to write the image
            ImageOutputStreamWrapper iosw = new ImageOutputStreamWrapper(ios);
            bm.compress(CompressFormat.JPEG, 100, iosw);
        } else {
            // ???AWT: Add support for other color models
            throw new RuntimeException("Color model not supported yet");
        }