FluxJpeg.Core.Decoder.JpegComponent.writeBlockScaled C# (CSharp) Method

writeBlockScaled() private method

private writeBlockScaled ( byte raster, byte blockdata, int compIndex, int x, int y, BlockUpsamplingMode mode ) : void
raster byte
blockdata byte
compIndex int
x int
y int
mode BlockUpsamplingMode
return void
        private void writeBlockScaled(byte[][,] raster, byte[,] blockdata, int compIndex, int x, int y, BlockUpsamplingMode mode)
        {
            int w = raster[0].GetLength(0),
                h = raster[0].GetLength(1);

            int factorUpVertical = factorUpV,
                factorUpHorizontal = factorUpH;

            int oldV = blockdata.GetLength(0),
                oldH = blockdata.GetLength(1),
                newV = oldV * factorUpVertical,
                newH = oldH * factorUpHorizontal;

            byte[,] comp = raster[compIndex];

            // Blocks may spill over the frame so we bound by the frame size
            int yMax = newV; if ((y + yMax) > h) yMax = h - y;
            int xMax = newH; if ((x + xMax) > w) xMax = w - x;

            switch (mode)
            {
                case BlockUpsamplingMode.BoxFilter:

                    #region Upsampling by repeating values

                    // Special case 1: No scale-up
                    if (factorUpVertical == 1 && factorUpHorizontal == 1)
                    {
                        for (int u = 0; u < xMax; u++)
                            for (int v = 0; v < yMax; v++)
                                comp[u + x, y + v] = blockdata[v, u];
                    }
                    // Special case 2: Perform scale-up 4 pixels at a time
                    else if (factorUpHorizontal == 2 && 
                             factorUpVertical == 2 && 
                             xMax == newH && yMax == newV)
                    {
                        for (int src_u = 0; src_u < oldH; src_u++)
                        {
                            int bx = src_u * 2 + x;

                            for ( int src_v = 0; src_v < oldV; src_v++)
                            {
                                byte val = blockdata[src_v, src_u];
                                int by = src_v * 2 + y;

                                comp[bx, by] = val;
                                comp[bx, by + 1] = val;
                                comp[bx + 1, by] = val;
                                comp[bx + 1, by + 1] = val;
                            }
                        }
                    }
                    else
                    {
                        /* Perform scaling (Box filter) */
                        for (int u = 0; u < xMax; u++)
                        {
                            int src_u = u / factorUpHorizontal;
                            for (int v = 0; v < yMax; v++)
                            {
                                int src_v = v / factorUpVertical;
                                comp[u + x, y + v] = blockdata[src_v, src_u];
                            }
                        }
                    }


                    #endregion
                    break;

                // JRP 4/7/08 -- This mode is disabled temporarily as it needs to be fixed after
                //               recent performance tweaks.
                //               It can produce slightly better (less blocky) decodings.

                //case BlockUpsamplingMode.Interpolate:
                //    #region Upsampling by interpolation
                //    for (int u = 0; u < newH; u++)
                //    {
                //        for (int v = 0; v < newV; v++)
                //        {
                //            int val = 0;
                //            for (int x = 0; x < factorUpHorizontal; x++)
                //            {
                //                int src_u = (u + x) / factorUpHorizontal;
                //                if (src_u >= oldH) src_u = oldH - 1;
                //                for (int y = 0; y < factorUpVertical; y++)
                //                {
                //                    int src_v = (v + y) / factorUpVertical;
                //                    if (src_v >= oldV) src_v = oldV - 1;
                //                    val += src[src_v, src_u];
                //                }
                //            }
                //            dest[v, u] = (byte)(val / (factorUpHorizontal * factorUpVertical));
                //        }
                //    }
                //    #endregion
                //    break;

                default:
                    throw new ArgumentException("Upsampling mode not supported.");
            }

        }