Animation.java 5.55 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.day.image;

import com.day.image.ImageSupport;
import com.day.image.Layer;
import com.day.imageio.plugins.GIFImageMetadata;
import com.day.imageio.plugins.GIFStreamMetadata;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageOutputStream;

public class Animation {
    public static int DISPOSAL_NONE = 0;
    public static int DISPOSAL_NO = 1;
    public static int DISPOSAL_BACKGROUND = 2;
    public static int DISPOSAL_PREVIOUS = 4;
    private List layers = new ArrayList();
    private int loops;
    private int defaultDisposal;
    private int bgColor;

    public Animation(int loops, int defaultDisposal, int bgColor) {
        this.loops = loops;
        this.defaultDisposal = defaultDisposal;
        this.bgColor = bgColor & 16777215;
    }

    public Animation(int loops) {
        this(loops, DISPOSAL_BACKGROUND, -1);
    }

    public Animation() {
        this(0, DISPOSAL_BACKGROUND, -1);
    }

    public void setLoops(int loops) {
        this.loops = loops;
    }

    public int getLoops() {
        return this.loops;
    }

    public void setDefaultDisposal(int defaultDisposal) {
        this.defaultDisposal = defaultDisposal;
    }

    public int getDefaultDisposal() {
        return this.defaultDisposal;
    }

    public void setBackgroundColor(int bgColor) {
        this.bgColor = bgColor & 16777215;
    }

    public int getBackgroundColor() {
        return this.bgColor;
    }

    public void addLayer(Layer layer, int delay) {
        this.addLayer(layer, delay, this.defaultDisposal);
    }

    public void addLayer(Layer layer, int delay, int disposal) {
        this.layers.add(new Patch(layer, delay, disposal));
    }

    public Layer removeLayer(int idx) {
        Patch p = (Patch)this.layers.remove(idx);
        return p != null ? p.getLayer() : null;
    }

    public Layer removeLayer(Layer layer) {
        for (Patch patch : this.layers) {
            if (patch.getLayer() != layer) continue;
            this.layers.remove(patch);
            return layer;
        }
        return null;
    }

    public void write(String mimeType, int numColors, OutputStream outs) throws IOException {
        if (mimeType == null || mimeType.toLowerCase().indexOf("gif") < 0) {
            throw new IllegalArgumentException("image/gif support only");
        }
        if (outs == null) {
            throw new NullPointerException("outs");
        }
        if (numColors < 2 || numColors > 256) {
            numColors = 256;
        }
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByMIMEType(mimeType);
        ImageWriter writer = writers.next();
        ImageOutputStream ios = ImageIO.createImageOutputStream(outs);
        writer.setOutput(ios);
        IIOMetadata streamMetadata = this.getStreamMetaData(writer);
        IIOMetadata imageMetadata = null;
        for (Patch patch : this.layers) {
            Layer layer = patch.getLayer();
            IIOMetadata[] gifMeta = ImageSupport.createGIFMetadata(layer, writer, numColors);
            imageMetadata = gifMeta[1] != null ? gifMeta[1] : writer.getDefaultImageMetadata(null, null);
            GIFImageMetadata gifIM = (GIFImageMetadata)imageMetadata;
            gifIM.delayTime = patch.getDelay();
            gifIM.disposalMethod = patch.getDisposal();
            IIOImage image = new IIOImage(layer.getImage(), null, imageMetadata);
            writer.write(streamMetadata, image, null);
        }
        writer.dispose();
        ios.close();
        outs.flush();
    }

    public String toString() {
        return "Animation : loops=" + this.loops + ", defaultDisposal=" + this.defaultDisposal + ", patches:" + this.layers.size();
    }

    private IIOMetadata getStreamMetaData(ImageWriter writer) {
        int height = 0;
        int width = 0;
        long bgcolor = this.bgColor;
        for (Patch patch : this.layers) {
            Layer l = patch.getLayer();
            if (width < l.getWidth()) {
                width = l.getWidth();
            }
            if (height < l.getHeight()) {
                height = l.getHeight();
            }
            if (bgcolor != -1) continue;
            bgcolor = l.getBackgroundColor().getRGB();
        }
        GIFStreamMetadata streamMetadata = (GIFStreamMetadata)writer.getDefaultStreamMetadata(null);
        streamMetadata.logicalScreenHeight = height;
        streamMetadata.logicalScreenWidth = width;
        streamMetadata.backgroundColorIndex = (int)bgcolor;
        if (this.loops >= 0) {
            streamMetadata.setLoops(this.loops);
        }
        return streamMetadata;
    }

    static {
        ImageSupport.initialize();
    }

    private static class Patch {
        private final int delay;
        private final int disposal;
        private final Layer layer;

        public Patch(Layer layer, int delay, int disposal) {
            this.layer = layer;
            this.delay = delay;
            this.disposal = disposal;
        }

        public int getDelay() {
            return this.delay;
        }

        public int getDisposal() {
            return this.disposal;
        }

        public Layer getLayer() {
            return this.layer;
        }
    }

}