示例#1
0
        private BufferedImage NonICCBIFilter(BufferedImage src, ColorSpace srcColorSpace, BufferedImage dst, ColorSpace dstColorSpace)
        {
            int            w        = src.Width;
            int            h        = src.Height;
            ICC_ColorSpace ciespace = (ICC_ColorSpace)ColorSpace.GetInstance(ColorSpace.CS_CIEXYZ);

            if (dst == null)
            {
                dst           = CreateCompatibleDestImage(src, null);
                dstColorSpace = dst.ColorModel.ColorSpace;
            }
            else
            {
                if ((h != dst.Height) || (w != dst.Width))
                {
                    throw new IllegalArgumentException("Width or height of BufferedImages do not match");
                }
            }
            Raster         srcRas       = src.Raster;
            WritableRaster dstRas       = dst.Raster;
            ColorModel     srcCM        = src.ColorModel;
            ColorModel     dstCM        = dst.ColorModel;
            int            srcNumComp   = srcCM.NumColorComponents;
            int            dstNumComp   = dstCM.NumColorComponents;
            bool           dstHasAlpha  = dstCM.HasAlpha();
            bool           needSrcAlpha = srcCM.HasAlpha() && dstHasAlpha;

            ColorSpace[] list;
            if ((CSList == null) && (ProfileList.Length != 0))
            {
                /* possible non-ICC src, some profiles, possible non-ICC dst */
                bool        nonICCSrc, nonICCDst;
                ICC_Profile srcProfile, dstProfile;
                if (!(srcColorSpace is ICC_ColorSpace))
                {
                    nonICCSrc  = true;
                    srcProfile = ciespace.Profile;
                }
                else
                {
                    nonICCSrc  = false;
                    srcProfile = ((ICC_ColorSpace)srcColorSpace).Profile;
                }
                if (!(dstColorSpace is ICC_ColorSpace))
                {
                    nonICCDst  = true;
                    dstProfile = ciespace.Profile;
                }
                else
                {
                    nonICCDst  = false;
                    dstProfile = ((ICC_ColorSpace)dstColorSpace).Profile;
                }
                /* make a new transform if needed */
                if ((ThisTransform == null) || (ThisSrcProfile != srcProfile) || (ThisDestProfile != dstProfile))
                {
                    UpdateBITransform(srcProfile, dstProfile);
                }
                // process per scanline
                float      maxNum = 65535.0f;            // use 16-bit precision in CMM
                ColorSpace cs;
                int        iccSrcNumComp;
                if (nonICCSrc)
                {
                    cs            = ciespace;
                    iccSrcNumComp = 3;
                }
                else
                {
                    cs            = srcColorSpace;
                    iccSrcNumComp = srcNumComp;
                }
                float[] srcMinVal        = new float[iccSrcNumComp];
                float[] srcInvDiffMinMax = new float[iccSrcNumComp];
                for (int i = 0; i < srcNumComp; i++)
                {
                    srcMinVal[i]        = cs.GetMinValue(i);
                    srcInvDiffMinMax[i] = maxNum / (cs.GetMaxValue(i) - srcMinVal[i]);
                }
                int iccDstNumComp;
                if (nonICCDst)
                {
                    cs            = ciespace;
                    iccDstNumComp = 3;
                }
                else
                {
                    cs            = dstColorSpace;
                    iccDstNumComp = dstNumComp;
                }
                float[] dstMinVal     = new float[iccDstNumComp];
                float[] dstDiffMinMax = new float[iccDstNumComp];
                for (int i = 0; i < dstNumComp; i++)
                {
                    dstMinVal[i]     = cs.GetMinValue(i);
                    dstDiffMinMax[i] = (cs.GetMaxValue(i) - dstMinVal[i]) / maxNum;
                }
                float[] dstColor;
                if (dstHasAlpha)
                {
                    int size = ((dstNumComp + 1) > 3) ? (dstNumComp + 1) : 3;
                    dstColor = new float[size];
                }
                else
                {
                    int size = (dstNumComp > 3) ? dstNumComp : 3;
                    dstColor = new float[size];
                }
                short[] srcLine = new short[w * iccSrcNumComp];
                short[] dstLine = new short[w * iccDstNumComp];
                Object  pixel;
                float[] color;
                float[] alpha = null;
                if (needSrcAlpha)
                {
                    alpha = new float[w];
                }
                int idx;
                // process each scanline
                for (int y = 0; y < h; y++)
                {
                    // convert src scanline
                    pixel = null;
                    color = null;
                    idx   = 0;
                    for (int x = 0; x < w; x++)
                    {
                        pixel = srcRas.GetDataElements(x, y, pixel);
                        color = srcCM.GetNormalizedComponents(pixel, color, 0);
                        if (needSrcAlpha)
                        {
                            alpha[x] = color[srcNumComp];
                        }
                        if (nonICCSrc)
                        {
                            color = srcColorSpace.ToCIEXYZ(color);
                        }
                        for (int i = 0; i < iccSrcNumComp; i++)
                        {
                            srcLine[idx++] = (short)((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] + 0.5f);
                        }
                    }
                    // color convert srcLine to dstLine
                    ThisTransform.colorConvert(srcLine, dstLine);
                    // convert dst scanline
                    pixel = null;
                    idx   = 0;
                    for (int x = 0; x < w; x++)
                    {
                        for (int i = 0; i < iccDstNumComp; i++)
                        {
                            dstColor[i] = ((float)(dstLine[idx++] & 0xffff)) * dstDiffMinMax[i] + dstMinVal[i];
                        }
                        if (nonICCDst)
                        {
                            color = srcColorSpace.FromCIEXYZ(dstColor);
                            for (int i = 0; i < dstNumComp; i++)
                            {
                                dstColor[i] = color[i];
                            }
                        }
                        if (needSrcAlpha)
                        {
                            dstColor[dstNumComp] = alpha[x];
                        }
                        else if (dstHasAlpha)
                        {
                            dstColor[dstNumComp] = 1.0f;
                        }
                        pixel = dstCM.GetDataElements(dstColor, 0, pixel);
                        dstRas.SetDataElements(x, y, pixel);
                    }
                }
            }
            else
            {
                /* possible non-ICC src, possible CSList, possible non-ICC dst */
                // process per pixel
                int numCS;
                if (CSList == null)
                {
                    numCS = 0;
                }
                else
                {
                    numCS = CSList.Length;
                }
                float[] dstColor;
                if (dstHasAlpha)
                {
                    dstColor = new float[dstNumComp + 1];
                }
                else
                {
                    dstColor = new float[dstNumComp];
                }
                Object  spixel = null;
                Object  dpixel = null;
                float[] color  = null;
                float[] tmpColor;
                // process each pixel
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        spixel   = srcRas.GetDataElements(x, y, spixel);
                        color    = srcCM.GetNormalizedComponents(spixel, color, 0);
                        tmpColor = srcColorSpace.ToCIEXYZ(color);
                        for (int i = 0; i < numCS; i++)
                        {
                            tmpColor = CSList[i].FromCIEXYZ(tmpColor);
                            tmpColor = CSList[i].ToCIEXYZ(tmpColor);
                        }
                        tmpColor = dstColorSpace.FromCIEXYZ(tmpColor);
                        for (int i = 0; i < dstNumComp; i++)
                        {
                            dstColor[i] = tmpColor[i];
                        }
                        if (needSrcAlpha)
                        {
                            dstColor[dstNumComp] = color[srcNumComp];
                        }
                        else if (dstHasAlpha)
                        {
                            dstColor[dstNumComp] = 1.0f;
                        }
                        dpixel = dstCM.GetDataElements(dstColor, 0, dpixel);
                        dstRas.SetDataElements(x, y, dpixel);
                    }
                }
            }

            return(dst);
        }