/*
 * SDK Pullenti Unitext, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software. 
 * This class is generated using the converter Unisharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

package com.pullenti.unitext.internal.pdf;

public class PdfImage extends PdfRect implements IPdfDictionaryWrapper {

    public PdfImage(PdfDictionary xobj, boolean smask, RgbColor fillcol, boolean nocontent) throws Exception, java.io.IOException {
        super();
        setDic(xobj);
        xobj.obj = this;
        PdfObject wi = xobj.getObject("Width", false);
        if (wi != null) 
            imageWidth = (int)wi.getDouble();
        PdfObject hi = xobj.getObject("Height", false);
        if (hi != null) 
            imageHeight = (int)hi.getDouble();
        if (nocontent) 
            return;
        PdfName sub = (PdfName)com.pullenti.unisharp.Utils.cast(xobj.getObject("Filter", false), PdfName.class);
        byte[] data = xobj.getData();
        if (sub == null) {
            PdfArray aaa = (PdfArray)com.pullenti.unisharp.Utils.cast(xobj.getObject("Filter", false), PdfArray.class);
            if (aaa != null && aaa.getItemsCount() == 1) 
                sub = (PdfName)com.pullenti.unisharp.Utils.cast(aaa.getItem(0, false), PdfName.class);
            else if ((aaa != null && aaa.getItemsCount() == 2 && (aaa.getItem(0, false) instanceof PdfName)) && com.pullenti.unisharp.Utils.stringsEq(((PdfName)com.pullenti.unisharp.Utils.cast(aaa.getItem(0, false), PdfName.class)).name, "FlateDecode")) {
                data = xobj.extractData();
                sub = (PdfName)com.pullenti.unisharp.Utils.cast(aaa.getItem(1, false), PdfName.class);
            }
        }
        if (sub != null && com.pullenti.unisharp.Utils.stringsEq(sub.name, "DCTDecode")) {
            content = data;
            return;
        }
        if (sub != null && com.pullenti.unisharp.Utils.stringsEq(sub.name, "JPXDecode")) {
            content = data;
            return;
        }
        PdfImage mask = null;
        PdfArray matte = null;
        PdfDictionary mdic = getDic().getDictionary("SMask", null);
        if (mdic != null && matte == null) {
            PdfImage mmm = new PdfImage(mdic, true, null, false);
            if (mmm.imageHeight == imageHeight && mmm.imageWidth == imageWidth) {
                mask = mmm;
                matte = (PdfArray)com.pullenti.unisharp.Utils.cast(mdic.getObject("Matte", false), PdfArray.class);
            }
        }
        if (sub != null && com.pullenti.unisharp.Utils.stringsEq(sub.name, "CCITTFaxDecode")) {
            PdfDictionary parms = xobj.getDictionary("DecodeParms", null);
            if (parms != null) {
                int k = parms.getIntItem("K");
                int _width = parms.getIntItem("Columns");
                if (_width < 10) 
                    _width = xobj.getIntItem("Width");
                int _height = parms.getIntItem("Rows");
                if (_height < 10) 
                    _height = xobj.getIntItem("Height");
                boolean invert = false;
                String str = parms.getStringItem("BlackIs1");
                if (str == null) 
                    str = xobj.getStringItem("ImageMask");
                if (str != null) {
                    if (com.pullenti.unisharp.Utils.stringsEq(str, "true")) 
                        invert = true;
                }
                if (_width > 0 && _height > 0) {
                    try (com.pullenti.unisharp.MemoryStream mem = new com.pullenti.unisharp.MemoryStream()) {
                        com.pullenti.unitext.internal.misc.TiffHelper.Tiff tif = new com.pullenti.unitext.internal.misc.TiffHelper.Tiff(null);
                        tif.writeTiff(mem, _width, _height, (k < 0 ? com.pullenti.unitext.internal.misc.TiffHelper.CCITT_Types.G4 : (k == 0 ? com.pullenti.unitext.internal.misc.TiffHelper.CCITT_Types.G3_2D : com.pullenti.unitext.internal.misc.TiffHelper.CCITT_Types.G3_1D)), 300.0F, 300.0F, invert, data);
                        content = mem.toByteArray();
                    }
                }
            }
            return;
        }
        if (((sub == null || ((com.pullenti.unisharp.Utils.stringsEq(sub.name, "FlateDecode") || com.pullenti.unisharp.Utils.stringsEq(sub.name, "LZWDecode"))))) && imageWidth > 0 && imageHeight > 0) {
            data = xobj.extractData();
            PdfObject bpi = xobj.getObject("BitsPerComponent", false);
            PdfDictionary dparms = xobj.getDictionary("DecodeParms", null);
            int predict = 0;
            if (dparms != null) {
                PdfIntValue pred = (PdfIntValue)com.pullenti.unisharp.Utils.cast(dparms.getObject("Predictor", false), PdfIntValue.class);
                if (pred != null && pred.val > 1) {
                    predict = pred.val;
                    if (predict >= 10 && (predict < 15)) {
                    }
                }
            }
            PdfObject colorsp = xobj.getObject("ColorSpace", false);
            byte[] colorMap = null;
            if (bpi != null && ((bpi.getDouble() == 8 || bpi.getDouble() == 4 || bpi.getDouble() == 1)) && colorsp != null) {
                String colorTyp = null;
                int bpiVal = (int)bpi.getDouble();
                boolean isIccBased = false;
                if (colorsp instanceof PdfName) 
                    colorTyp = ((PdfName)com.pullenti.unisharp.Utils.cast(colorsp, PdfName.class)).name;
                else if (colorsp instanceof PdfArray) {
                    PdfArray arr = (PdfArray)com.pullenti.unisharp.Utils.cast(colorsp, PdfArray.class);
                    PdfName it0 = (PdfName)com.pullenti.unisharp.Utils.cast(arr.getItem(0, false), PdfName.class);
                    if (it0 != null && com.pullenti.unisharp.Utils.stringsEq(it0.name, "ICCBased")) 
                        isIccBased = true;
                    if (it0 != null && com.pullenti.unisharp.Utils.stringsEq(it0.name, "Indexed")) {
                        PdfStringValue sss = (PdfStringValue)com.pullenti.unisharp.Utils.cast(arr.getItem(3, false), PdfStringValue.class);
                        if (sss != null) 
                            colorMap = sss.val;
                        else {
                            PdfDictionary ddd = (PdfDictionary)com.pullenti.unisharp.Utils.cast(arr.getItem(3, false), PdfDictionary.class);
                            if (ddd != null) 
                                colorMap = ddd.extractData();
                        }
                    }
                    PdfDictionary dii = (PdfDictionary)com.pullenti.unisharp.Utils.cast(arr.getItem(3, false), PdfDictionary.class);
                    if (dii == null && arr.getItemsCount() == 2) {
                        dii = (PdfDictionary)com.pullenti.unisharp.Utils.cast(arr.getItem(1, false), PdfDictionary.class);
                        PdfDictionary ddd = (PdfDictionary)com.pullenti.unisharp.Utils.cast(arr.getItem(1, false), PdfDictionary.class);
                        if (ddd != null && (ddd.getObject("Alternate", false) instanceof PdfName)) 
                            colorTyp = ((PdfName)com.pullenti.unisharp.Utils.cast(ddd.getObject("Alternate", false), PdfName.class)).name;
                    }
                    if (arr.getItemsCount() > 2 && (arr.getItem(1, false) instanceof PdfArray)) {
                        arr = (PdfArray)com.pullenti.unisharp.Utils.cast(arr.getItem(1, false), PdfArray.class);
                        if (arr.getItemsCount() == 2) {
                            PdfDictionary ddd = (PdfDictionary)com.pullenti.unisharp.Utils.cast(arr.getItem(1, false), PdfDictionary.class);
                            if (ddd != null && (ddd.getObject("Alternate", false) instanceof PdfName)) 
                                colorTyp = ((PdfName)com.pullenti.unisharp.Utils.cast(ddd.getObject("Alternate", false), PdfName.class)).name;
                        }
                    }
                    else if (arr.getItemsCount() == 4 && (arr.getItem(1, false) instanceof PdfName)) 
                        colorTyp = ((PdfName)com.pullenti.unisharp.Utils.cast(arr.getItem(1, false), PdfName.class)).name;
                }
                if (com.pullenti.unisharp.Utils.stringsEq(colorTyp, "DeviceRGB") || com.pullenti.unisharp.Utils.stringsEq(colorTyp, "DeviceGray") || com.pullenti.unisharp.Utils.stringsEq(colorTyp, "DeviceCMYK")) {
                    if (data != null) {
                        int rowWidth = data.length / imageHeight;
                        int mmm = data.length % imageHeight;
                        int nn = rowWidth / imageWidth;
                        if (mmm != 0) {
                        }
                        if (nn == 0 && (bpiVal < 8)) 
                            nn = 1;
                        boolean isGray = com.pullenti.unisharp.Utils.stringsEq(colorTyp, "DeviceGray");
                        boolean isCmyk = com.pullenti.unisharp.Utils.stringsEq(colorTyp, "DeviceCMYK");
                        if ((nn == 3 || ((nn == 4 && isCmyk)) || ((isCmyk && colorMap != null))) || bpiVal == 4 || (((nn == 1 && ((colorMap != null || com.pullenti.unisharp.Utils.stringsEq(colorTyp, "DeviceGray")))) || ((bpiVal == 1 && colorMap != null))))) {
                            if (com.pullenti.unisharp.Utils.stringsEq(colorTyp, "DeviceGray")) {
                            }
                            if (com.pullenti.unisharp.Utils.stringsEq(colorTyp, "DeviceRGB") && colorMap != null && ((colorMap.length % 3)) == 0) {
                            }
                            if (isCmyk && colorMap != null) {
                                byte[] rgb = new byte[((colorMap.length / 4)) * 3];
                                int j = 0;
                                for (int i = 0; (i + 3) < colorMap.length; i += 4) {
                                    rgb[j] = _corrCMYK(colorMap[i], colorMap[i + 3]);
                                    rgb[j + 1] = _corrCMYK(colorMap[i + 1], colorMap[i + 3]);
                                    rgb[j + 2] = _corrCMYK(colorMap[i + 2], colorMap[i + 3]);
                                    j += 3;
                                }
                                colorMap = rgb;
                            }
                            com.pullenti.unitext.internal.misc.PngWrapper img = new com.pullenti.unitext.internal.misc.PngWrapper(imageWidth, imageHeight, isGray, colorMap, smask);
                            for (int row = 0; row < imageHeight; row++) {
                                int pp = row * rowWidth;
                                if (img != null) 
                                    img.beginRow();
                                if (bpiVal == 1) {
                                    for (int ii = 0; ii < rowWidth; ii++) {
                                        if ((pp + ii) >= data.length) 
                                            break;
                                        byte b = data[pp + ii];
                                        for (int jj = 7; jj >= 0; jj--) {
                                            if (img != null) 
                                                img.addPixelIndex((byte)(((((Byte.toUnsignedInt(b)) >>> jj)) & 1)));
                                        }
                                    }
                                }
                                else 
                                    for (int w = 0; w < imageWidth; w++) {
                                        if (nn == 3) {
                                            if ((pp + 2) >= data.length) 
                                                break;
                                            byte r = data[pp + 0];
                                            byte g = data[pp + 1];
                                            byte b = data[pp + 2];
                                            if (mask != null && mask.m_Smask != null) {
                                                byte alpha = mask.m_Smask.getPixelGray(w, row);
                                                fillcol = null;
                                                PdfObject m0 = null;
                                                PdfObject m1 = null;
                                                PdfObject m2 = null;
                                                if (matte != null && matte.getItemsCount() == 3) {
                                                    m0 = matte.getItem(0, false);
                                                    m1 = matte.getItem(1, false);
                                                    m2 = matte.getItem(2, false);
                                                }
                                                r = _corrSMask(r, alpha, m0, (fillcol == null ? (byte)0 : fillcol.R));
                                                g = _corrSMask(g, alpha, m1, (fillcol == null ? (byte)0 : fillcol.G));
                                                b = _corrSMask(b, alpha, m2, (fillcol == null ? (byte)0 : fillcol.B));
                                                if ((alpha == ((byte)0) && r == ((byte)0) && g == ((byte)0)) && b == ((byte)0)) 
                                                    r = (g = (b = (byte)0xFF));
                                            }
                                            img.addPixelRgb(r, g, b);
                                            pp += 3;
                                        }
                                        else if (nn == 4) {
                                            if ((pp + 3) >= data.length) 
                                                break;
                                            byte r = _corrCMYK(data[pp], data[pp + 3]);
                                            byte g = _corrCMYK(data[pp + 1], data[pp + 3]);
                                            byte b = _corrCMYK(data[pp + 2], data[pp + 3]);
                                            img.addPixelRgb(b, r, g);
                                            pp += 4;
                                        }
                                        else if (com.pullenti.unisharp.Utils.stringsEq(colorTyp, "DeviceGray") && colorMap == null) {
                                            if (pp < data.length) {
                                                byte bb = data[pp];
                                                img.addPixelGray(bb);
                                                pp += 1;
                                            }
                                        }
                                        else if (pp < data.length) {
                                            int b1 = Byte.toUnsignedInt(data[pp]);
                                            if (bpiVal == 4) {
                                                if (colorMap != null) {
                                                    img.addPixelIndex((byte)((((b1 >> 4)) & 0xF)));
                                                    img.addPixelIndex((byte)((b1 & 0xF)));
                                                    pp++;
                                                }
                                                else if ((pp + 2) < data.length) {
                                                    int b2 = Byte.toUnsignedInt(data[pp + 1]);
                                                    int b3 = Byte.toUnsignedInt(data[pp + 2]);
                                                    img.addPixelRgb((byte)b3, (byte)b1, (byte)b2);
                                                    img.addPixelRgb((byte)b3, (byte)b1, (byte)b2);
                                                    pp += 3;
                                                }
                                            }
                                            else {
                                                img.addPixelIndex((byte)b1);
                                                pp += 1;
                                            }
                                        }
                                    }
                                img.endRow();
                            }
                            if (smask) 
                                m_Smask = img;
                            else {
                                img.commit();
                                content = img.getBytes();
                            }
                            return;
                        }
                    }
                }
            }
        }
    }

    public com.pullenti.unitext.internal.misc.PngWrapper m_Smask;

    private PdfDictionary _dic;

    @Override
    public PdfDictionary getDic() {
        return _dic;
    }

    public PdfDictionary setDic(PdfDictionary value) {
        _dic = value;
        return _dic;
    }


    private static byte _corrCMYK(byte b1, byte b2) {
        int i = Byte.toUnsignedInt(b1);
        i += (Byte.toUnsignedInt(b2));
        if (i >= 256) 
            i = 256;
        return (byte)((256 - i));
    }

    private static byte _corrSMask(byte c, byte a, PdfObject mat, byte def) {
        int m = 0;
        if (mat instanceof PdfIntValue) 
            m = ((PdfIntValue)com.pullenti.unisharp.Utils.cast(mat, PdfIntValue.class)).val * 256;
        else if (mat instanceof PdfRealValue) 
            m = (int)((((PdfRealValue)com.pullenti.unisharp.Utils.cast(mat, PdfRealValue.class)).getDouble() * (256.0)));
        if (m == 0) 
            m = Byte.toUnsignedInt(def);
        int res = (Byte.toUnsignedInt(c)) - m;
        res *= (Byte.toUnsignedInt(a));
        res /= 256;
        res += m;
        byte cres = (byte)((res & 0xFF));
        return cres;
    }

    public byte[] content;

    public int imageWidth;

    public int imageHeight;

    @Override
    public String toString() {
        return (super.toString() + ": Image " + (content == null ? "?" : ((Integer)content.length).toString()) + " bytes");
    }

    public static void setNewImageContent(PdfDictionary __dic, int _width, int _height, byte[] data) throws java.io.IOException {
        PdfName filt = (PdfName)com.pullenti.unisharp.Utils.cast(__dic.getObject("Filter", false), PdfName.class);
        if (filt != null) 
            filt.name = "DCTDecode";
        else 
            __dic.addObject("Filter", PdfName._new229("DCTDecode"));
        __dic.setData(data);
        PdfIntValue wi = (PdfIntValue)com.pullenti.unisharp.Utils.cast(__dic.getObject("Width", false), PdfIntValue.class);
        if (wi != null) 
            wi.val = _width;
        else 
            __dic.addObject("Width", PdfIntValue._new230(_width));
        PdfIntValue hi = (PdfIntValue)com.pullenti.unisharp.Utils.cast(__dic.getObject("Height", false), PdfIntValue.class);
        if (hi != null) 
            hi.val = _height;
        else 
            __dic.addObject("Height", PdfIntValue._new230(_height));
        __dic.addObject("SMask", null);
        PdfObject col = __dic.getObject("ColorSpace", false);
        if (col != null && (col instanceof PdfName)) 
            ((PdfName)com.pullenti.unisharp.Utils.cast(col, PdfName.class)).name = "DeviceRGB";
        else 
            __dic.addObject("ColorSpace", PdfName._new229("DeviceRGB"));
    }
    public PdfImage() {
        super();
    }
}
