Example #1
0
        /// <summary>
        /// Transforms the source <CODE>Raster</CODE> and stores the results in
        /// the destination <CODE>Raster</CODE>.  This operation performs the
        /// transform band by band.
        /// <para>
        /// If the destination <CODE>Raster</CODE> is null, a new
        /// <CODE>Raster</CODE> is created.
        /// An <CODE>IllegalArgumentException</CODE> may be thrown if the source is
        /// the same as the destination or if the number of bands in
        /// the source is not equal to the number of bands in the
        /// destination.
        /// </para>
        /// <para>
        /// The coordinates of the rectangle returned by
        /// <code>getBounds2D(Raster)</code>
        /// are not necessarily the same as the coordinates of the
        /// <code>WritableRaster</code> returned by this method.  If the
        /// upper-left corner coordinates of rectangle are negative then
        /// this part of the rectangle is not drawn.  If the coordinates
        /// of the rectangle are positive then the filtered image is drawn at
        /// that position in the destination <code>Raster</code>.
        /// </para>
        /// <para>
        /// </para>
        /// </summary>
        /// <param name="src"> The <CODE>Raster</CODE> to transform. </param>
        /// <param name="dst"> The <CODE>Raster</CODE> in which to store the results of the
        /// transformation.
        /// </param>
        /// <returns> The transformed <CODE>Raster</CODE>.
        /// </returns>
        /// <exception cref="ImagingOpException"> if the raster cannot be transformed
        ///         because of a data-processing error that might be
        ///         caused by an invalid image format, tile format, or
        ///         image-processing operation, or any other unsupported
        ///         operation. </exception>
        public WritableRaster Filter(Raster src, WritableRaster dst)
        {
            if (src == null)
            {
                throw new NullPointerException("src image is null");
            }
            if (dst == null)
            {
                dst = CreateCompatibleDestRaster(src);
            }
            if (src == dst)
            {
                throw new IllegalArgumentException("src image cannot be the " + "same as the dst image");
            }
            if (src.NumBands != dst.NumBands)
            {
                throw new IllegalArgumentException("Number of src bands (" + src.NumBands + ") does not match number of " + " dst bands (" + dst.NumBands + ")");
            }

            if (ImagingLib.filter(this, src, dst) == null)
            {
                throw new ImagingOpException("Unable to transform src image");
            }
            return(dst);
        }
Example #2
0
        /// <summary>
        /// Rescales the pixel data in the source Raster.
        /// If the destination Raster is null, a new Raster will be created.
        /// The source and destination must have the same number of bands.
        /// Otherwise, an IllegalArgumentException is thrown.
        /// Note that the number of scaling factors/offsets in this object must
        /// meet the restrictions stated in the class comments above.
        /// Otherwise, an IllegalArgumentException is thrown. </summary>
        /// <param name="src"> the <code>Raster</code> to be filtered </param>
        /// <param name="dst"> the destination for the filtering operation
        ///            or <code>null</code> </param>
        /// <returns> the filtered <code>WritableRaster</code>. </returns>
        /// <exception cref="IllegalArgumentException"> if <code>src</code> and
        ///         <code>dst</code> do not have the same number of bands,
        ///         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 WritableRaster Filter(Raster src, WritableRaster dst)
        {
            int numBands = src.NumBands;
            int width    = src.Width;
            int height   = src.Height;

            int[] srcPix = null;
            int   step   = 0;
            int   tidx   = 0;

            // Create a new destination Raster, if needed
            if (dst == null)
            {
                dst = CreateCompatibleDestRaster(src);
            }
            else if (height != dst.Height || width != dst.Width)
            {
                throw new IllegalArgumentException("Width or height of Rasters do not " + "match");
            }
            else if (numBands != dst.NumBands)
            {
                // Make sure that the number of bands are equal
                throw new IllegalArgumentException("Number of bands in src " + numBands + " does not equal number of bands in dest " + dst.NumBands);
            }
            // Make sure that the arrays match
            // Make sure that the low/high/constant arrays match
            if (Length != 1 && Length != src.NumBands)
            {
                throw new IllegalArgumentException("Number of scaling constants " + "does not equal the number of" + " of bands in the src raster");
            }


            //
            // Try for a native raster rescale first
            //
            if (ImagingLib.filter(this, src, dst) != null)
            {
                return(dst);
            }

            //
            // Native raster rescale failed.
            // Try to see if a lookup operation can be used
            //
            if (CanUseLookup(src, dst))
            {
                int srcNgray = (1 << SrcNbits);
                int dstNgray = (1 << DstNbits);

                if (dstNgray == 256)
                {
                    ByteLookupTable lut = CreateByteLut(ScaleFactors, Offsets, numBands, srcNgray);
                    LookupOp        op  = new LookupOp(lut, Hints);
                    op.Filter(src, dst);
                }
                else
                {
                    ShortLookupTable lut = CreateShortLut(ScaleFactors, Offsets, numBands, srcNgray);
                    LookupOp         op  = new LookupOp(lut, Hints);
                    op.Filter(src, dst);
                }
            }
            else
            {
                //
                // Fall back to the slow code
                //
                if (Length > 1)
                {
                    step = 1;
                }

                int sminX = src.MinX;
                int sY    = src.MinY;
                int dminX = dst.MinX;
                int dY    = dst.MinY;
                int sX;
                int dX;

                //
                //  Determine bits per band to determine maxval for clamps.
                //  The min is assumed to be zero.
                //  REMIND: This must change if we ever support signed data types.
                //
                int         nbits;
                int[]       dstMax  = new int[numBands];
                int[]       dstMask = new int[numBands];
                SampleModel dstSM   = dst.SampleModel;
                for (int z = 0; z < numBands; z++)
                {
                    nbits      = dstSM.GetSampleSize(z);
                    dstMax[z]  = (1 << nbits) - 1;
                    dstMask[z] = ~(dstMax[z]);
                }

                int val;
                for (int y = 0; y < height; y++, sY++, dY++)
                {
                    dX = dminX;
                    sX = sminX;
                    for (int x = 0; x < width; x++, sX++, dX++)
                    {
                        // Get data for all bands at this x,y position
                        srcPix = src.GetPixel(sX, sY, srcPix);
                        tidx   = 0;
                        for (int z = 0; z < numBands; z++, tidx += step)
                        {
                            val = (int)(srcPix[z] * ScaleFactors[tidx] + Offsets[tidx]);
                            // Clamp
                            if ((val & dstMask[z]) != 0)
                            {
                                if (val < 0)
                                {
                                    val = 0;
                                }
                                else
                                {
                                    val = dstMax[z];
                                }
                            }
                            srcPix[z] = val;
                        }

                        // Put it back for all bands
                        dst.SetPixel(dX, dY, srcPix);
                    }
                }
            }
            return(dst);
        }
Example #3
0
        /// <summary>
        /// Transforms the source <CODE>BufferedImage</CODE> and stores the results
        /// in the destination <CODE>BufferedImage</CODE>.
        /// If the color models for the two images do not match, a color
        /// conversion into the destination color model is performed.
        /// If the destination image is null,
        /// a <CODE>BufferedImage</CODE> is created with the source
        /// <CODE>ColorModel</CODE>.
        /// <para>
        /// The coordinates of the rectangle returned by
        /// <code>getBounds2D(BufferedImage)</code>
        /// are not necessarily the same as the coordinates of the
        /// <code>BufferedImage</code> returned by this method.  If the
        /// upper-left corner coordinates of the rectangle are
        /// negative then this part of the rectangle is not drawn.  If the
        /// upper-left corner coordinates of the  rectangle are positive
        /// then the filtered image is drawn at that position in the
        /// destination <code>BufferedImage</code>.
        /// </para>
        /// <para>
        /// An <CODE>IllegalArgumentException</CODE> is thrown if the source is
        /// the same as the destination.
        ///
        /// </para>
        /// </summary>
        /// <param name="src"> The <CODE>BufferedImage</CODE> to transform. </param>
        /// <param name="dst"> The <CODE>BufferedImage</CODE> in which to store the results
        /// of the transformation.
        /// </param>
        /// <returns> The filtered <CODE>BufferedImage</CODE>. </returns>
        /// <exception cref="IllegalArgumentException"> if <code>src</code> and
        ///         <code>dst</code> are the same </exception>
        /// <exception cref="ImagingOpException"> if the image cannot be transformed
        ///         because of a data-processing error that might be
        ///         caused by an invalid image format, tile format, or
        ///         image-processing operation, or any other unsupported
        ///         operation. </exception>
        public BufferedImage Filter(BufferedImage src, BufferedImage dst)
        {
            if (src == null)
            {
                throw new NullPointerException("src image is null");
            }
            if (src == dst)
            {
                throw new IllegalArgumentException("src image cannot be the " + "same as the dst image");
            }

            bool          needToConvert = false;
            ColorModel    srcCM         = src.ColorModel;
            ColorModel    dstCM;
            BufferedImage origDst = dst;

            if (dst == null)
            {
                dst     = CreateCompatibleDestImage(src, null);
                dstCM   = srcCM;
                origDst = dst;
            }
            else
            {
                dstCM = dst.ColorModel;
                if (srcCM.ColorSpace.Type != dstCM.ColorSpace.Type)
                {
                    int  type      = Xform.Type;
                    bool needTrans = ((type & (Xform.TYPE_MASK_ROTATION | Xform.TYPE_GENERAL_TRANSFORM)) != 0);
                    if (!needTrans && type != Xform.TYPE_TRANSLATION && type != Xform.TYPE_IDENTITY)
                    {
                        double[] mtx = new double[4];
                        Xform.GetMatrix(mtx);
                        // Check out the matrix.  A non-integral scale will force ARGB
                        // since the edge conditions can't be guaranteed.
                        needTrans = (mtx[0] != (int)mtx[0] || mtx[3] != (int)mtx[3]);
                    }

                    if (needTrans && srcCM.Transparency == java.awt.Transparency_Fields.OPAQUE)
                    {
                        // Need to convert first
                        ColorConvertOp ccop   = new ColorConvertOp(Hints);
                        BufferedImage  tmpSrc = null;
                        int            sw     = src.Width;
                        int            sh     = src.Height;
                        if (dstCM.Transparency == java.awt.Transparency_Fields.OPAQUE)
                        {
                            tmpSrc = new BufferedImage(sw, sh, BufferedImage.TYPE_INT_ARGB);
                        }
                        else
                        {
                            WritableRaster r = dstCM.CreateCompatibleWritableRaster(sw, sh);
                            tmpSrc = new BufferedImage(dstCM, r, dstCM.AlphaPremultiplied, null);
                        }
                        src = ccop.Filter(src, tmpSrc);
                    }
                    else
                    {
                        needToConvert = true;
                        dst           = CreateCompatibleDestImage(src, null);
                    }
                }
            }

            if (InterpolationType_Renamed != TYPE_NEAREST_NEIGHBOR && dst.ColorModel is IndexColorModel)
            {
                dst = new BufferedImage(dst.Width, dst.Height, BufferedImage.TYPE_INT_ARGB);
            }
            if (ImagingLib.filter(this, src, dst) == null)
            {
                throw new ImagingOpException("Unable to transform src image");
            }

            if (needToConvert)
            {
                ColorConvertOp ccop = new ColorConvertOp(Hints);
                ccop.Filter(dst, origDst);
            }
            else if (origDst != dst)
            {
                java.awt.Graphics2D g = origDst.CreateGraphics();
                try
                {
                    g.Composite = AlphaComposite.Src;
                    g.DrawImage(dst, 0, 0, null);
                }
                finally
                {
                    g.Dispose();
                }
            }

            return(origDst);
        }
Example #4
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);
        }