IppRaster.java 10.7 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.scene7.is.ipp.messages;

import com.scene7.is.ipp.messages.Ipp;
import com.scene7.is.ipp.messages.IppByteArray;
import com.scene7.is.ipp.messages.IppEncodingType;
import com.scene7.is.ipp.messages.IppFormatType;
import com.scene7.is.ipp.messages.IppInt;
import com.scene7.is.ipp.messages.IppPixelType;
import com.scene7.is.ipp.messages.Offset;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Writer;
import java.util.Hashtable;
import javax.imageio.ImageIO;

public class IppRaster {
    private BufferedImage image_;
    private int xDim_;
    private int yDim_;
    private int pixelType_;
    private int format_;
    private int encoding_;
    private byte[] data_;

    public IppRaster(int xDim, int yDim, int pixelType, int format, int encoding, byte[] data, int offset, int length) {
        this.xDim_ = xDim;
        this.yDim_ = yDim;
        this.pixelType_ = pixelType;
        this.format_ = format;
        this.encoding_ = encoding;
        this.data_ = data;
        this.image_ = null;
        this.data_ = new byte[length];
        System.arraycopy(data, offset, this.data_, 0, length);
    }

    public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("[");
        buffer.append("xDim: ").append(String.valueOf(this.xDim_)).append(" ");
        buffer.append("yDim: ").append(String.valueOf(this.yDim_)).append(" ");
        buffer.append("pixelType: ").append(String.valueOf(this.pixelType_)).append(" ");
        buffer.append("format: ").append(String.valueOf(this.format_)).append(" ");
        buffer.append("encoding: ").append(String.valueOf(this.encoding_)).append(" ");
        buffer.append("data: ").append(String.valueOf(this.data_)).append(" ");
        buffer.append("]");
        return buffer.toString();
    }

    public static IppRaster Unstuff(byte[] arr, Offset arrayPos) {
        Ipp.Assert((arrayPos.val & 3) == 0, "IppRaster align");
        int xDim = IppInt.Unstuff(arr, arrayPos);
        int yDim = IppInt.Unstuff(arr, arrayPos);
        int pixelType = IppInt.Unstuff(arr, arrayPos);
        int format = IppInt.Unstuff(arr, arrayPos);
        int encoding = IppInt.Unstuff(arr, arrayPos);
        int length = IppInt.Unstuff(arr, arrayPos);
        int offset = IppInt.Unstuff(arr, arrayPos);
        return new IppRaster(xDim, yDim, pixelType, format, encoding, arr, offset, length);
    }

    public static IppRaster[] UnstuffArray(byte[] arr, Offset arrayPos) {
        Ipp.Assert((arrayPos.val & 3) == 0, "IppRaster alignemt");
        int count = IppInt.Unstuff(arr, arrayPos);
        int size = IppInt.Unstuff(arr, arrayPos);
        Ipp.Assert(count == 0 || size >= 28, "IppRaster count");
        Offset roff = new Offset(IppInt.Unstuff(arr, arrayPos));
        Offset loff = new Offset(roff.val);
        IppRaster[] result = new IppRaster[count];
        for (int i = 0; i < count; ++i) {
            loff.val = roff.val;
            result[i] = IppRaster.Unstuff(arr, loff);
            roff.val += size;
        }
        return result;
    }

    public static IppRaster[] UnstuffFixedArray(byte[] arr, Offset arrayPos, int count) {
        IppRaster[] result = new IppRaster[count];
        for (int i = 0; i < count; ++i) {
            result[i] = IppRaster.Unstuff(arr, arrayPos);
        }
        return result;
    }

    public static void Stuff(byte[] arr, Offset arrayPos, Offset varPos, IppRaster val) {
        Ipp.Assert((arrayPos.val & 3) == 0, "IppRaster align");
        if (val != null) {
            IppInt.Stuff(arr, arrayPos, varPos, val.xDim());
            IppInt.Stuff(arr, arrayPos, varPos, val.yDim());
            IppInt.Stuff(arr, arrayPos, varPos, val.pixelType());
            IppInt.Stuff(arr, arrayPos, varPos, val.format());
            IppInt.Stuff(arr, arrayPos, varPos, val.encoding());
            IppByteArray.Stuff(arr, arrayPos, varPos, val.data());
        } else {
            Ipp.StuffNullBytes(arr, arrayPos, 28);
        }
    }

    public static void StuffArray(byte[] arr, Offset arrayPos, Offset varPos, IppRaster[] val) {
        Ipp.Assert((arrayPos.val & 3) == 0, "IppRaster stuffarray align");
        int len = val != null ? val.length : 0;
        IppInt.Stuff(arr, arrayPos, varPos, len);
        IppInt.Stuff(arr, arrayPos, varPos, 28);
        Ipp.StuffOffset(arr, arrayPos, varPos, len > 0 ? 4 : 1);
        Offset varvarPos = new Offset(varPos.val + 28 * len);
        for (int i = 0; i < len; ++i) {
            IppRaster.Stuff(arr, varPos, varvarPos, val[i]);
        }
        varPos.val = varvarPos.val;
    }

    public static void StuffFixedArray(byte[] arr, Offset arrayPos, Offset varPos, int count, IppRaster[] val) {
        Ipp.Assert(val.length == count, "IppRaster count");
        for (int i = 0; i < count; ++i) {
            IppRaster.Stuff(arr, arrayPos, varPos, val[i]);
        }
    }

    public static void Print(Writer tf, String label, IppRaster it) throws IOException {
        String ll = label + "IppRaster: ";
        if (it == null) {
            tf.write(ll + "NULL!!\n");
            return;
        }
        tf.write(ll + "\n");
        IppInt.Print(tf, ll + "xDim: ", it.xDim());
        IppInt.Print(tf, ll + "yDim: ", it.yDim());
        IppPixelType.Print(tf, ll + "pixelType: ", it.pixelType());
        IppFormatType.Print(tf, ll + "format: ", it.format());
        IppEncodingType.Print(tf, ll + "encoding: ", it.encoding());
    }

    public static void PrintArray(Writer tf, String label, IppRaster[] it) throws IOException {
        String ll = label + "IppRaster Array, length: ";
        tf.write(ll);
        if (it == null) {
            tf.write("NULL!!!\n");
            return;
        }
        tf.write("" + it.length + "\n");
        for (int i = 0; i < it.length; ++i) {
            ll = label + "IppRaster[" + String.valueOf(i) + "]: ";
            IppRaster.Print(tf, ll, it[i]);
        }
    }

    public void adjustVarPos(Offset varPos) {
        varPos.val += this.data_.length;
    }

    public int xDim() {
        return this.xDim_;
    }

    public int yDim() {
        return this.yDim_;
    }

    public int pixelType() {
        return this.pixelType_;
    }

    public int format() {
        return this.format_;
    }

    public int encoding() {
        return this.encoding_;
    }

    public byte[] data() {
        return this.data_;
    }

    public BufferedImage getImage() {
        try {
            return IppRaster.processImagePixels(this.data_, this.xDim_, this.yDim_, this.pixelType_, this.encoding_);
        }
        catch (IOException e) {
            return null;
        }
    }

    private static BufferedImage processImagePixels(byte[] arr, int width, int height, int pixelType, int pixelEncoding) throws IOException {
        switch (pixelType) {
            case 131074: {
                switch (pixelEncoding) {
                    case 131073: {
                        return IppRaster.processRawRGBImage(arr, width, height);
                    }
                    case 131074: {
                        return IppRaster.createSolidRGBImage(arr, width, height);
                    }
                    case 131075: {
                        return IppRaster.processJpegImage(arr);
                    }
                }
                System.out.println("Unsupported compression type");
                Ipp.Assert(false, "IppRaster RGB default");
                break;
            }
            case 131073: {
                switch (pixelEncoding) {
                    case 131073: {
                        return IppRaster.processRawBWImage(arr, width, height);
                    }
                    case 131074: {
                        return IppRaster.createSolidBWImage(arr, width, height);
                    }
                    case 131075: {
                        return IppRaster.processJpegImage(arr);
                    }
                }
                System.out.println("Unsupported compression type");
                Ipp.Assert(false, "IppRaster BW default");
                break;
            }
            default: {
                System.out.println("Unsupported pixeltype received (" + Integer.toString(pixelType) + ")");
                Ipp.Assert(false, "IppRaster CMYK default");
            }
        }
        return null;
    }

    private static BufferedImage createImage(byte[] rawData, ColorSpace colorspace, int width, int height, int pixelStride, int[] bandOffsets, int[] bits) {
        DataBufferByte db = new DataBufferByte(rawData, width * height * pixelStride, 0);
        WritableRaster raster = Raster.createInterleavedRaster(db, width, height, width * pixelStride, pixelStride, bandOffsets, null);
        ComponentColorModel cm = new ComponentColorModel(colorspace, bits, false, false, 0, db.getDataType());
        return new BufferedImage(cm, raster, false, null);
    }

    private static BufferedImage processRawRGBImage(byte[] arr, int width, int height) {
        int[] bandOffsets = new int[]{0, 1, 2};
        int[] bits = new int[]{8, 8, 8};
        return IppRaster.createImage(arr, ColorSpace.getInstance(1000), width, height, 3, bandOffsets, bits);
    }

    private static BufferedImage processRawBWImage(byte[] arr, int width, int height) {
        int[] bandOffsets = new int[]{0};
        int[] bits = new int[]{8};
        return IppRaster.createImage(arr, ColorSpace.getInstance(1003), width, height, 1, bandOffsets, bits);
    }

    private static BufferedImage createSolidRGBImage(byte[] arr, int width, int height) {
        int dim = width * height * 3;
        byte valueA = arr[0];
        byte valueB = arr[1];
        byte valueC = arr[2];
        byte[] raster = new byte[dim];
        int cnt = 0;
        while (cnt < dim) {
            raster[cnt++] = valueA;
            raster[cnt++] = valueB;
            raster[cnt++] = valueC;
        }
        return IppRaster.processRawRGBImage(raster, width, height);
    }

    private static BufferedImage createSolidBWImage(byte[] arr, int width, int height) {
        int dim = width * height;
        byte value = arr[0];
        byte[] raster = new byte[dim];
        int cnt = 0;
        while (cnt < dim) {
            raster[cnt++] = value;
        }
        return IppRaster.processRawBWImage(raster, width, height);
    }

    private static BufferedImage processJpegImage(byte[] arr) throws IOException {
        ByteArrayInputStream inputStream = new ByteArrayInputStream(arr);
        return ImageIO.read(inputStream);
    }
}