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.");
}
}