private BufferedImage CreateCompatibleDestImage(BufferedImage src, ColorModel destCM, ColorSpace destCS)
        {
            BufferedImage image;

            if (destCM == null)
            {
                ColorModel srcCM    = src.ColorModel;
                int        nbands   = destCS.NumComponents;
                bool       hasAlpha = srcCM.HasAlpha();
                if (hasAlpha)
                {
                    nbands += 1;
                }
                int[] nbits = new int[nbands];
                for (int i = 0; i < nbands; i++)
                {
                    nbits[i] = 8;
                }
                destCM = new ComponentColorModel(destCS, nbits, hasAlpha, srcCM.AlphaPremultiplied, srcCM.Transparency, DataBuffer.TYPE_BYTE);
            }
            int w = src.Width;
            int h = src.Height;

            image = new BufferedImage(destCM, destCM.CreateCompatibleWritableRaster(w, h), destCM.AlphaPremultiplied, null);
            return(image);
        }
Exemple #2
0
        /// <summary>
        /// Creates a zeroed destination image with the correct size and number of
        /// bands.  If destCM is <code>null</code>, an appropriate
        /// <code>ColorModel</code> will be used. </summary>
        /// <param name="src">       Source image for the filter operation. </param>
        /// <param name="destCM">    the destination's <code>ColorModel</code>, which
        ///                  can be <code>null</code>. </param>
        /// <returns> a filtered destination <code>BufferedImage</code>. </returns>
        public virtual BufferedImage CreateCompatibleDestImage(BufferedImage src, ColorModel destCM)
        {
            BufferedImage image;
            int           w            = src.Width;
            int           h            = src.Height;
            int           transferType = DataBuffer.TYPE_BYTE;

            if (destCM == null)
            {
                ColorModel cm     = src.ColorModel;
                Raster     raster = src.Raster;
                if (cm is ComponentColorModel)
                {
                    DataBuffer db       = raster.DataBuffer;
                    bool       hasAlpha = cm.HasAlpha();
                    bool       isPre    = cm.AlphaPremultiplied;
                    int        trans    = cm.Transparency;
                    int[]      nbits    = null;
                    if (Ltable is ByteLookupTable)
                    {
                        if (db.DataType == db.TYPE_USHORT)
                        {
                            // Dst raster should be of type byte
                            if (hasAlpha)
                            {
                                nbits = new int[2];
                                if (trans == cm.BITMASK)
                                {
                                    nbits[1] = 1;
                                }
                                else
                                {
                                    nbits[1] = 8;
                                }
                            }
                            else
                            {
                                nbits = new int[1];
                            }
                            nbits[0] = 8;
                        }
                        // For byte, no need to change the cm
                    }
                    else if (Ltable is ShortLookupTable)
                    {
                        transferType = DataBuffer.TYPE_USHORT;
                        if (db.DataType == db.TYPE_BYTE)
                        {
                            if (hasAlpha)
                            {
                                nbits = new int[2];
                                if (trans == cm.BITMASK)
                                {
                                    nbits[1] = 1;
                                }
                                else
                                {
                                    nbits[1] = 16;
                                }
                            }
                            else
                            {
                                nbits = new int[1];
                            }
                            nbits[0] = 16;
                        }
                    }
                    if (nbits != null)
                    {
                        cm = new ComponentColorModel(cm.ColorSpace, nbits, hasAlpha, isPre, trans, transferType);
                    }
                }
                image = new BufferedImage(cm, cm.CreateCompatibleWritableRaster(w, h), cm.AlphaPremultiplied, null);
            }
            else
            {
                image = new BufferedImage(destCM, destCM.CreateCompatibleWritableRaster(w, h), destCM.AlphaPremultiplied, null);
            }

            return(image);
        }
Exemple #3
0
        /// <summary>
        /// Performs a lookup operation on a <code>BufferedImage</code>.
        /// If the color model in the source image is not the same as that
        /// in the destination image, the pixels will be converted
        /// in the destination.  If the destination image is <code>null</code>,
        /// a <code>BufferedImage</code> will be created with an appropriate
        /// <code>ColorModel</code>.  An <code>IllegalArgumentException</code>
        /// might be thrown if the number of arrays in the
        /// <code>LookupTable</code> does not meet the restrictions
        /// stated in the class comment above, or if the source image
        /// has an <code>IndexColorModel</code>. </summary>
        /// <param name="src"> the <code>BufferedImage</code> to be filtered </param>
        /// <param name="dst"> the <code>BufferedImage</code> in which to
        ///            store the results of the filter operation </param>
        /// <returns> the filtered <code>BufferedImage</code>. </returns>
        /// <exception cref="IllegalArgumentException"> if the number of arrays in the
        ///         <code>LookupTable</code> does not meet the restrictions
        ///         described in the class comments, or if the source image
        ///         has an <code>IndexColorModel</code>. </exception>
        public BufferedImage Filter(BufferedImage src, BufferedImage dst)
        {
            ColorModel srcCM    = src.ColorModel;
            int        numBands = srcCM.NumColorComponents;
            ColorModel dstCM;

            if (srcCM is IndexColorModel)
            {
                throw new IllegalArgumentException("LookupOp cannot be " + "performed on an indexed image");
            }
            int numComponents = Ltable.NumComponents;

            if (numComponents != 1 && numComponents != srcCM.NumComponents && numComponents != srcCM.NumColorComponents)
            {
                throw new IllegalArgumentException("Number of arrays in the " + " lookup table (" + numComponents + " is not compatible with the " + " src image: " + src);
            }


            bool needToConvert = false;

            int width  = src.Width;
            int height = src.Height;

            if (dst == null)
            {
                dst   = CreateCompatibleDestImage(src, null);
                dstCM = srcCM;
            }
            else
            {
                if (width != dst.Width)
                {
                    throw new IllegalArgumentException("Src width (" + width + ") not equal to dst width (" + dst.Width + ")");
                }
                if (height != dst.Height)
                {
                    throw new IllegalArgumentException("Src height (" + height + ") not equal to dst height (" + dst.Height + ")");
                }

                dstCM = dst.ColorModel;
                if (srcCM.ColorSpace.Type != dstCM.ColorSpace.Type)
                {
                    needToConvert = true;
                    dst           = CreateCompatibleDestImage(src, null);
                }
            }

            BufferedImage origDst = dst;

            if (ImagingLib.filter(this, src, dst) == null)
            {
                // Do it the slow way
                WritableRaster srcRaster = src.Raster;
                WritableRaster dstRaster = dst.Raster;

                if (srcCM.HasAlpha())
                {
                    if (numBands - 1 == numComponents || numComponents == 1)
                    {
                        int   minx  = srcRaster.MinX;
                        int   miny  = srcRaster.MinY;
                        int[] bands = new int[numBands - 1];
                        for (int i = 0; i < numBands - 1; i++)
                        {
                            bands[i] = i;
                        }
                        srcRaster = srcRaster.CreateWritableChild(minx, miny, srcRaster.Width, srcRaster.Height, minx, miny, bands);
                    }
                }
                if (dstCM.HasAlpha())
                {
                    int dstNumBands = dstRaster.NumBands;
                    if (dstNumBands - 1 == numComponents || numComponents == 1)
                    {
                        int   minx  = dstRaster.MinX;
                        int   miny  = dstRaster.MinY;
                        int[] bands = new int[numBands - 1];
                        for (int i = 0; i < numBands - 1; i++)
                        {
                            bands[i] = i;
                        }
                        dstRaster = dstRaster.CreateWritableChild(minx, miny, dstRaster.Width, dstRaster.Height, minx, miny, bands);
                    }
                }

                Filter(srcRaster, dstRaster);
            }

            if (needToConvert)
            {
                // ColorModels are not the same
                ColorConvertOp ccop = new ColorConvertOp(Hints);
                ccop.Filter(dst, origDst);
            }

            return(origDst);
        }
        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);
        }
Exemple #5
0
        /// <summary>
        /// Rescales the source BufferedImage.
        /// If the color model in the source image is not the same as that
        /// in the destination image, the pixels will be converted
        /// in the destination.  If the destination image is null,
        /// a BufferedImage will be created with the source ColorModel.
        /// An IllegalArgumentException may be thrown if the number of
        /// scaling factors/offsets in this object does not meet the
        /// restrictions stated in the class comments above, or if the
        /// source image has an IndexColorModel. </summary>
        /// <param name="src"> the <code>BufferedImage</code> to be filtered </param>
        /// <param name="dst"> the destination for the filtering operation
        ///            or <code>null</code> </param>
        /// <returns> the filtered <code>BufferedImage</code>. </returns>
        /// <exception cref="IllegalArgumentException"> if the <code>ColorModel</code>
        ///         of <code>src</code> is an <code>IndexColorModel</code>,
        ///         or if the number of scaling factors and offsets in this
        ///         <code>RescaleOp</code> do not meet the requirements
        ///         stated in the class comments. </exception>
        public BufferedImage Filter(BufferedImage src, BufferedImage dst)
        {
            ColorModel srcCM = src.ColorModel;
            ColorModel dstCM;
            int        numBands = srcCM.NumColorComponents;


            if (srcCM is IndexColorModel)
            {
                throw new IllegalArgumentException("Rescaling cannot be " + "performed on an indexed image");
            }
            if (Length != 1 && Length != numBands && Length != srcCM.NumComponents)
            {
                throw new IllegalArgumentException("Number of scaling constants " + "does not equal the number of" + " of color or color/alpha " + " components");
            }

            bool needToConvert = false;

            // Include alpha
            if (Length > numBands && srcCM.HasAlpha())
            {
                Length = numBands + 1;
            }

            int width  = src.Width;
            int height = src.Height;

            if (dst == null)
            {
                dst   = CreateCompatibleDestImage(src, null);
                dstCM = srcCM;
            }
            else
            {
                if (width != dst.Width)
                {
                    throw new IllegalArgumentException("Src width (" + width + ") not equal to dst width (" + dst.Width + ")");
                }
                if (height != dst.Height)
                {
                    throw new IllegalArgumentException("Src height (" + height + ") not equal to dst height (" + dst.Height + ")");
                }

                dstCM = dst.ColorModel;
                if (srcCM.ColorSpace.Type != dstCM.ColorSpace.Type)
                {
                    needToConvert = true;
                    dst           = CreateCompatibleDestImage(src, null);
                }
            }

            BufferedImage origDst = dst;

            //
            // Try to use a native BI rescale operation first
            //
            if (ImagingLib.filter(this, src, dst) == null)
            {
                //
                // Native BI rescale failed - convert to rasters
                //
                WritableRaster srcRaster = src.Raster;
                WritableRaster dstRaster = dst.Raster;

                if (srcCM.HasAlpha())
                {
                    if (numBands - 1 == Length || Length == 1)
                    {
                        int   minx  = srcRaster.MinX;
                        int   miny  = srcRaster.MinY;
                        int[] bands = new int[numBands - 1];
                        for (int i = 0; i < numBands - 1; i++)
                        {
                            bands[i] = i;
                        }
                        srcRaster = srcRaster.CreateWritableChild(minx, miny, srcRaster.Width, srcRaster.Height, minx, miny, bands);
                    }
                }
                if (dstCM.HasAlpha())
                {
                    int dstNumBands = dstRaster.NumBands;
                    if (dstNumBands - 1 == Length || Length == 1)
                    {
                        int   minx  = dstRaster.MinX;
                        int   miny  = dstRaster.MinY;
                        int[] bands = new int[numBands - 1];
                        for (int i = 0; i < numBands - 1; i++)
                        {
                            bands[i] = i;
                        }
                        dstRaster = dstRaster.CreateWritableChild(minx, miny, dstRaster.Width, dstRaster.Height, minx, miny, bands);
                    }
                }

                //
                // Call the raster filter method
                //
                Filter(srcRaster, dstRaster);
            }

            if (needToConvert)
            {
                // ColorModels are not the same
                ColorConvertOp ccop = new ColorConvertOp(Hints);
                ccop.Filter(dst, origDst);
            }

            return(origDst);
        }