Пример #1
0
        public void Scale(Rectangle provided_input, PixelMap sourceMap, Rectangle targetRect, PixelMap output)
        {
            // Compute rectangles
            Rectangle required_red = new Rectangle();
            Rectangle sourceRect   = CreateRectangles(targetRect, required_red);

            // Parameter validation
            if (
                (provided_input.Width != sourceMap.ImageWidth) ||
                (provided_input.Height != sourceMap.ImageHeight))
            {
                throw new Exception("invalid rectangle");
            }

            if (
                (provided_input.XMin > sourceRect.XMin) ||
                (provided_input.YMin > sourceRect.YMin) ||
                (provided_input.XMax < sourceRect.XMax) ||
                (provided_input.YMax < sourceRect.YMax))
            {
                throw new Exception("invalid rectangle");
            }

            // Adjust output pixmap
            if (
                (targetRect.Width != (int)output.ImageWidth) ||
                (targetRect.Height != (int)output.ImageHeight))
            {
                output.Init(
                    targetRect.Height,
                    targetRect.Width,
                    null);
            }

            // Prepare temp stuff
            int bufw = required_red.Width;

            Pixel[] lbuffer = new Pixel[bufw + 2];

            for (int i = 0; i < lbuffer.Length;)
            {
                lbuffer[i++] = new Pixel();
            }

            try
            {
                if ((xshift > 0) || (yshift > 0))
                {
                    p1 = new PixelMap().Init(1, bufw, null);
                    p2 = new PixelMap().Init(2, bufw, null);
                    l1 = l2 = -1;
                }

                // Loop on output lines
                for (int y = targetRect.YMin; y < targetRect.YMax; y++)
                {
                    // Perform vertical interpolation
                    {
                        int            fy  = vcoord[y];
                        int            fy1 = fy >> FRACBITS;
                        int            fy2 = fy1 + 1;
                        PixelReference upper;
                        PixelReference lower;

                        // Obtain upper and lower line in reduced image
                        if ((xshift > 0) || (yshift > 0))
                        {
                            lower = GetLine(fy1, required_red, provided_input, sourceMap);
                            upper = GetLine(fy2, required_red, provided_input, sourceMap);
                        }
                        else
                        {
                            int dx = required_red.XMin - provided_input.XMin;

                            if (required_red.YMin > fy1)
                            {
                                fy1 = required_red.YMin;
                            }

                            if (required_red.YMax <= fy2)
                            {
                                fy2 = required_red.YMax - 1;
                            }

                            lower =
                                sourceMap.CreateGPixelReference(fy1 - provided_input.YMin, dx);
                            upper =
                                sourceMap.CreateGPixelReference(fy2 - provided_input.YMin, dx);
                        }

                        // Compute line
                        int     idest  = 1;
                        short[] deltas = interp[fy & FRACMASK];

                        for (
                            int edest = idest + bufw;
                            idest < edest;
                            upper.IncOffset(), lower.IncOffset())
                        {
                            Pixel dest    = lbuffer[idest++];
                            int   lower_r = lower.Red;
                            int   delta_r = deltas[(256 + upper.Red) - lower_r];
                            int   lower_g = lower.Green;
                            int   delta_g = deltas[(256 + upper.Green) - lower_g];
                            int   lower_b = lower.Blue;
                            int   delta_b = deltas[(256 + upper.Blue) - lower_b];
                            dest.SetBGR(lower_b + delta_b, lower_g + delta_g, lower_r + delta_r);
                        }
                    }

                    // Perform horizontal interpolation
                    {
                        // Prepare for side effects
                        lbuffer[0] = lbuffer[1];

                        // lbuffer[bufw] = lbuffer[bufw];
                        int            line = 1 - required_red.XMin;
                        PixelReference dest =
                            output.CreateGPixelReference(y - targetRect.YMin, 0);

                        // Loop horizontally
                        for (int x = targetRect.XMin; x < targetRect.XMax; x++)
                        {
                            int     n       = hcoord[x];
                            int     lower   = line + (n >> FRACBITS);
                            Pixel   lower0  = lbuffer[lower];
                            Pixel   lower1  = lbuffer[lower + 1];
                            short[] deltas  = interp[n & FRACMASK];
                            int     lower_r = lower0.Red;
                            int     delta_r = deltas[(256 + lower1.Red) - lower_r];
                            int     lower_g = lower0.Green;
                            int     delta_g = deltas[(256 + lower1.Green) - lower_g];
                            int     lower_b = lower0.Blue;
                            int     delta_b = deltas[(256 + lower1.Blue) - lower_b];
                            dest.SetBGR(lower_b + delta_b, lower_g + delta_g, lower_r + delta_r);
                            dest.IncOffset();
                        }
                    }
                }
            }
            finally
            {
                p1 = null;
                p2 = null;
            }
        }
Пример #2
0
        public void Scale(Rectangle srcRect, IPixelMap srcMap, Rectangle targetRect, IPixelMap targetMap)
        {
            // Parameter validation
            if ((srcRect.Width != srcMap.Width) || (srcRect.Height != srcMap.Height))
            {
                throw new DjvuArgumentException("Invalid rectangle", nameof(srcRect));
            }

            // Compute rectangles
            Rectangle required_red = new Rectangle();
            Rectangle sourceRect   = CreateRectangles(targetRect, required_red);

            if ((srcRect.XMin > sourceRect.XMin) || (srcRect.YMin > sourceRect.YMin) ||
                (srcRect.XMax < sourceRect.XMax) || (srcRect.YMax < sourceRect.YMax))
            {
                throw new DjvuArgumentException("Invalid rectangle", nameof(srcRect));
            }

            // Adjust output pixmap
            if ((targetRect.Width != (int)targetMap.Width) || (targetRect.Height != (int)targetMap.Height))
            {
                targetMap.Init(targetRect.Height, targetRect.Width, null);
            }

            // Prepare temp stuff
            int bufw = required_red.Width;

            Pixel[] lbuffer = new Pixel[bufw + 2];

            try
            {
                if ((_XShift > 0) || (_YShift > 0))
                {
                    _PixelMap1 = new PixelMap().Init(1, bufw, null);
                    _PixelMap2 = new PixelMap().Init(2, bufw, null);
                    _L1        = _L2 = -1;
                }

                IPixelReference upper = srcMap.CreateGPixelReference(0, 0);
                IPixelReference lower = srcMap.CreateGPixelReference(0, 0);
                IPixelReference dest  = targetMap.CreateGPixelReference(0, 0);

                // Loop on output lines
                for (int y = targetRect.YMin; y < targetRect.YMax; y++)
                {
                    // Perform vertical interpolation
                    {
                        int fy  = _VCoord[y];
                        int fy1 = fy >> FRACBITS;
                        int fy2 = fy1 + 1;

                        // Obtain upper and lower line in reduced image
                        if ((_XShift > 0) || (_YShift > 0))
                        {
                            lower = GetLine(fy1, required_red, srcRect, srcMap);
                            upper = GetLine(fy2, required_red, srcRect, srcMap);
                        }
                        else
                        {
                            int dx = required_red.XMin - srcRect.XMin;

                            if (required_red.YMin > fy1)
                            {
                                fy1 = required_red.YMin;
                            }

                            if (required_red.YMax <= fy2)
                            {
                                fy2 = required_red.YMax - 1;
                            }

                            lower.SetOffset(fy1 - srcRect.YMin, dx);
                            // srcMap.CreateGPixelReference(fy1 - srcRect.YMin, dx);
                            upper.SetOffset(fy2 - srcRect.YMin, dx);
                            // srcMap.CreateGPixelReference(fy2 - srcRect.YMin, dx);
                        }

                        // Compute line
                        int     idest  = 1;
                        short[] deltas = interp[fy & FRACMASK];

                        unsafe
                        {
                            for (int edest = idest + bufw; idest < edest; upper.IncOffset(), lower.IncOffset())
                            {
                                Pixel destPix = lbuffer[idest++];

                                int    color    = 0;
                                sbyte *colorPtr = (sbyte *)&color;
                                // Skip alpha and set pointer to Blue
                                colorPtr++;
                                *colorPtr  = lower.Blue;
                                *colorPtr += (sbyte)deltas[(256 + upper.Blue) - *colorPtr];

                                // Set pointer to Green
                                colorPtr++;
                                *colorPtr  = lower.Green;
                                *colorPtr += (sbyte)deltas[(256 + upper.Green) - *colorPtr];

                                // Set pointer to Red
                                colorPtr++;
                                *colorPtr  = lower.Red;
                                *colorPtr += (sbyte)deltas[(256 + upper.Red) - *colorPtr];

                                //Pixel d = (Pixel) lower.ToPixel();
                                //destPix.SetBGR(d);
                                destPix.SetBGR(*colorPtr);
                            }
                        }
                    }

                    // Perform horizontal interpolation
                    {
                        // Prepare for side effects
                        lbuffer[0] = lbuffer[1];

                        // lbuffer[bufw] = lbuffer[bufw];
                        int line = 1 - required_red.XMin;
                        dest.SetOffset(y - targetRect.YMin, 0);
                        //= targetMap.CreateGPixelReference(y - targetRect.YMin, 0);

                        // Loop horizontally
                        unsafe
                        {
                            for (int x = targetRect.XMin; x < targetRect.XMax; x++)
                            {
                                int     n      = _HCoord[x];
                                int     lowerl = line + (n >> FRACBITS);
                                Pixel   lower0 = lbuffer[lowerl];
                                Pixel   lower1 = lbuffer[lowerl + 1];
                                short[] deltas = interp[n & FRACMASK];

                                int    color    = 0;
                                sbyte *colorPtr = (sbyte *)&color;
                                // Skip alpha and set pointer to Blue
                                colorPtr++;
                                *colorPtr  = lower0.Blue;
                                *colorPtr += (sbyte)deltas[(256 + lower1.Blue) - *colorPtr];

                                // Set pointer to Green
                                colorPtr++;
                                *colorPtr  = lower0.Green;
                                *colorPtr += (sbyte)deltas[(256 + lower1.Green) - *colorPtr];

                                // Set pointer to Red
                                colorPtr++;
                                *colorPtr  = lower0.Red;
                                *colorPtr += (sbyte)deltas[(256 + lower1.Red) - *colorPtr];

                                dest.SetBGR(*colorPtr);
                                dest.IncOffset();
                            }
                        }
                    }
                }
            }
            finally
            {
                _PixelMap1 = null;
                _PixelMap2 = null;
            }
        }