Package flex2.compiler.media

Source Code of flex2.compiler.media.LosslessImageTranscoder$QualityRequiresCompression

/*
*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*/

package flex2.compiler.media;

import flash.graphics.images.LosslessImage;
import flash.swf.builder.tags.DefineBitsLosslessBuilder;
import flash.swf.tags.DefineBitsJPEG3;
import flash.swf.tags.DefineBitsLossless;
import flash.swf.tags.DefineSprite;
import flex2.compiler.TranscoderException;
import flex2.compiler.io.VirtualFile;
import flex2.compiler.util.MimeMappings;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.io.ByteArrayOutputStream;
import java.util.Map;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.MemoryCacheImageOutputStream;

/**
* Transcodes lossless images (GIF and PNG) into DefineBitsLossless
* SWF tags.  Compression with quality is supported.  For compression,
* we convert images to JPEG, then transcode them into DefineBitsJPEG3
* SWF tags.
*
* @author Roger Gonzalez
* @author Joa Ebert
* @author Paul Reilly
*/
public class LosslessImageTranscoder extends ImageTranscoder
{
    public static final String COMPRESSION = "compression";
    public static final String QUALITY = "quality";

    public LosslessImageTranscoder()
    {
        super(new String[]{MimeMappings.GIF, MimeMappings.PNG}, DefineSprite.class, true);
    }

    public boolean isSupportedAttribute(String attr)
    {
        return (COMPRESSION.equals(attr) ||
                QUALITY.equals(attr) ||
                super.isSupportedAttribute(attr));
    }

    public ImageInfo getImage(VirtualFile sourceFile, Map<String, Object> args)
        throws TranscoderException
    {
        ImageInfo info = new ImageInfo();

        try
        {
            LosslessImage image = new LosslessImage(sourceFile.getName(),
                                                    sourceFile.getInputStream(),
                                                    sourceFile.getLastModified());
       
            // If compression is true, use JPEG compression.  Otherwise, use the lossless format.
            if (args.containsKey(COMPRESSION) && Boolean.parseBoolean((String) args.get(COMPRESSION)))
            {
                // We use DefineBitsJPEG3, because it supports an alpha channel
                DefineBitsJPEG3 defineBits = new DefineBitsJPEG3();
                int imageSize = image.getWidth() * image.getHeight();
                byte[] alphaData = new byte[imageSize];
                int[] pixels = image.getPixels();
                BufferedImage bufferedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);

                bufferedImage.setRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());

                for (int i = 0; i < imageSize; ++i)
                {
                    alphaData[i] = (byte) ((pixels[i] >> 24) & 0xff);
                }

                float quality = 1.0f;

                if (args.containsKey(QUALITY))
                {
                    try
                    {
                        String qualityString = (String) args.get(QUALITY);
                        double qualityPercentage = Double.parseDouble(qualityString);

                        // quality must be a number between 0 and 100.
                        if (qualityPercentage < 0 || qualityPercentage > 100)
                        {
                            throw new InvalidQuality();
                        }

                        quality = (float)(qualityPercentage / 100.0);
                    }
                    catch (NumberFormatException numberFormatException)
                    {
                        throw new InvalidQuality();
                    }
                }

                defineBits.data = bufferedImageToJPEG(bufferedImage, quality);
                defineBits.alphaDataOffset = alphaData.length;
                defineBits.alphaData = alphaData;

                info.defineBits = defineBits;
            }
            else
            {
                // quality doesn't make sense without compression.
                if (args.containsKey(QUALITY))
                {
                    throw new QualityRequiresCompression();
                }

                DefineBitsLossless defineBits = DefineBitsLosslessBuilder.build(image.getPixels(), image.getWidth(), image.getHeight());
                info.defineBits = defineBits;
            }

            info.width = image.getWidth();
            info.height = image.getHeight();
        }
        catch (TranscoderException transcoderException)
        {
            throw transcoderException;
        }
        catch (Exception exception)
        {
            throw new ExceptionWhileTranscoding(exception);
        }

        return info;
    }

    private static byte[] bufferedImageToJPEG(BufferedImage bufferedImage, float quality)
        throws Exception
    {
        ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
        ImageWriteParam writeParam = writer.getDefaultWriteParam();
        ColorModel colorModel = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
        ImageTypeSpecifier imageTypeSpecifier =
            new ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(1, 1)/*ignored*/);
        writeParam.setDestinationType(imageTypeSpecifier);
        writeParam.setSourceBands(new int[] {0, 1, 2});
        writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        writeParam.setCompressionQuality(quality);

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        writer.setOutput(new MemoryCacheImageOutputStream(buffer));

        IIOImage ioImage = new IIOImage(bufferedImage, null, null);

        writer.write(null, ioImage, writeParam);
        writer.dispose();

        return buffer.toByteArray();
    }

    public static class InvalidQuality extends TranscoderException
    {
        private static final long serialVersionUID = 6347969168361169993L;

        public InvalidQuality()
        {
        }
    }

    public static class QualityRequiresCompression extends TranscoderException
    {
        private static final long serialVersionUID = 6347969168361169994L;

        public QualityRequiresCompression()
        {
        }
    }
}
TOP

Related Classes of flex2.compiler.media.LosslessImageTranscoder$QualityRequiresCompression

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.