ImageSupport.java 7.44 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.day.image;

import ch.randelshofer.media.jpeg.CMYKJPEGImageReaderSpi;
import com.day.image.DitherOp;
import com.day.image.Layer;
import com.day.imageio.plugins.GIFImageMetadata;
import com.day.imageio.plugins.GIFStreamMetadata;
import com.day.imageio.plugins.GifImageWriterSpi;

import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.spi.IIORegistry;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ImageWriterSpi;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.io.IOException;
import java.util.Iterator;

public class ImageSupport {
    private static final ImageSupport instance;
    private static boolean registered;
    private ImageWriterSpi gifImageWriterSpi;
    private ImageReaderSpi cmykJpegImageReaderSpi;

    protected ImageSupport() {
    }

    static void initialize() {
        ImageSupport.registerImageIOSpi();
    }

    static void getGIFMetaData(Layer layer, ImageReader reader) throws IOException {
        instance.doGetGIFMetaData(layer, reader);
    }

    static ImageWriter getImageWriter(String format) throws IOException {
        if ("gif".equalsIgnoreCase(format)) {
            return instance.getGIFImageWriterSpi().createWriterInstance();
        }
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(format);
        if (!writers.hasNext()) {
            writers = ImageIO.getImageWritersByMIMEType(format);
        }
        if (writers.hasNext()) {
            return writers.next();
        }
        return null;
    }

    static IIOMetadata[] createGIFMetadata(Layer layer, ImageWriter writer, int numCol) {
        return instance.doCreateGIFMetadata(layer, writer, numCol);
    }

    public static BufferedImage coerceData(BufferedImage image, boolean isAlphaPremultiplied) {
        return instance.doCoerceData(image, isAlphaPremultiplied);
    }

    public static void registerImageIOSpi() {
        if (!registered) {
            IIORegistry reg = IIORegistry.getDefaultInstance();
            reg.registerServiceProvider(instance.getGIFImageWriterSpi());
            reg.registerServiceProvider(instance.getCmykJpegImageReaderSpi());
            registered = true;
        }
    }

    public static void deregisterImageIOSpi() {
        if (registered) {
            IIORegistry reg = IIORegistry.getDefaultInstance();
            reg.deregisterServiceProvider(instance.getGIFImageWriterSpi());
            reg.deregisterServiceProvider(instance.getCmykJpegImageReaderSpi());
            registered = false;
        }
    }

    protected void doGetGIFMetaData(Layer layer, ImageReader reader) throws IOException {
        IIOMetadata smd;
        int bgidx;
        IIOMetadata imd;
        try {
            smd = reader.getStreamMetadata();
            imd = reader.getImageMetadata(layer.getImageIndex());
        }
        catch (IIOException iioe) {
            return;
        }
        byte[] globalColorTable = (byte[])ImageSupport.get(smd, "globalColorTable");
        if (globalColorTable != null && (bgidx = 3 * ImageSupport.getInt(smd, "backgroundColorIndex", Integer.MAX_VALUE)) < globalColorTable.length) {
            int r = globalColorTable[bgidx++] + 256 & 255;
            int g = globalColorTable[bgidx++] + 256 & 255;
            int b = globalColorTable[bgidx] + 256 & 255;
            layer.setBackground(new Color(r, g, b));
        }
        if (ImageSupport.getBoolean(imd, "transparentColorFlag", false)) {
            byte[] colTab = (byte[])ImageSupport.get(imd, "localColorTable");
            if (colTab == null && globalColorTable != null) {
                colTab = globalColorTable;
            }
            if (colTab != null) {
                int transidx = 3 * ImageSupport.getInt(imd, "transparentColorIndex", 0);
                int r = colTab[transidx++] + 256 & 255;
                int g = colTab[transidx++] + 256 & 255;
                int b = colTab[transidx++] + 256 & 255;
                layer.setTransparency(new Color(r, g, b, 0));
            }
        }
    }

    protected IIOMetadata[] doCreateGIFMetadata(Layer layer, ImageWriter writer, int numCol) {
        if (numCol <= 0) {
            numCol = 2;
        } else if (numCol > 256) {
            numCol = 256;
        }
        BufferedImage reduced = DitherOp.convertToIndexed(layer.getImage(), numCol, layer.getTransparency(), layer.getBackgroundColor(), null);
        if (reduced != layer.getImage()) {
            layer.setImage(reduced);
        }
        IndexColorModel icm = (IndexColorModel)reduced.getColorModel();
        GIFImageMetadata imd = (GIFImageMetadata)writer.getDefaultImageMetadata(null, null);
        imd.imageLeftPosition = layer.getX() > 0 ? layer.getX() : 0;
        imd.imageTopPosition = layer.getY() > 0 ? layer.getY() : 0;
        imd.imageWidth = layer.getWidth();
        imd.imageHeight = layer.getHeight();
        GIFStreamMetadata smd = (GIFStreamMetadata)writer.getDefaultStreamMetadata(null);
        smd.logicalScreenHeight = layer.getHeight();
        smd.logicalScreenWidth = layer.getWidth();
        if (layer.getTransparency() != null) {
            imd.transparentColorFlag = true;
            imd.transparentColorIndex = icm.getTransparentPixel();
        }
        smd.backgroundColorIndex = layer.getBackgroundColor().equals(layer.getTransparency()) ? icm.getTransparentPixel() : ImageSupport.toIndex(icm, layer.getBackgroundColor().getRGB());
        return new IIOMetadata[]{smd, imd};
    }

    protected BufferedImage doCoerceData(BufferedImage image, boolean isAlphaPremultiplied) {
        image.coerceData(isAlphaPremultiplied);
        return image;
    }

    protected ImageWriterSpi getGIFImageWriterSpi() {
        if (this.gifImageWriterSpi == null) {
            this.gifImageWriterSpi = new GifImageWriterSpi();
        }
        return this.gifImageWriterSpi;
    }

    protected ImageReaderSpi getCmykJpegImageReaderSpi() {
        if (this.cmykJpegImageReaderSpi == null) {
            this.cmykJpegImageReaderSpi = new CMYKJPEGImageReaderSpi();
        }
        return this.cmykJpegImageReaderSpi;
    }

    protected static int toIndex(IndexColorModel icm, int rgb) {
        Object pixel = icm.getDataElements(rgb, null);
        switch (icm.getTransferType()) {
            case 3: {
                return ((int[])pixel)[0];
            }
            case 0: {
                return ((byte[])pixel)[0];
            }
            case 1: {
                return ((short[])pixel)[0];
            }
        }
        return 0;
    }

    private static int getInt(Object object, String name, int defValue) {
        try {
            return object.getClass().getField(name).getInt(object);
        }
        catch (Throwable t) {
            return defValue;
        }
    }

    private static boolean getBoolean(Object object, String name, boolean defValue) {
        try {
            return object.getClass().getField(name).getBoolean(object);
        }
        catch (Throwable t) {
            return defValue;
        }
    }

    private static Object get(Object object, String name) {
        try {
            return object.getClass().getField(name).get(object);
        }
        catch (Throwable t) {
            return null;
        }
    }

    static {
        registered = false;
        instance = new ImageSupport();
        ImageIO.setUseCache(false);
    }
}