Listing 3: The Expand function
void LP::Expand (unsigned level)
{
if (level >= _levels || level + 1 >= _levels)
throw "Level is out of range";
unsigned char *src = _r_images[level + 1];
unsigned char *dest = _l_images[level];
unsigned width = _width >> level;
unsigned height = _height >> level;
for (int y = 0; y < (int) (height - 3); y += 2)
{
for (int x = 0; x < (int) (width - 3); x += 2)
{
// Expand argument is the top left corner
// of the sample block
Expand3x3 (src[((y / 2) * (width / 2)) + x / 2],
&dest[y * width + x], width);
}
}
// Fix the edges
// If the width is a multiple of two, then the reduced
// image has a column on the right that was not expanded.
if (!(width & 1))
{
for (int y = 0; y < (int) (height - 3); y += 2)
{
Expand2x3 (src[((y/2) * (width/2)) + (width - 2) / 2],
&dest[y * width + (width - 2)], width);
}
}
// If the height is a multiple of two, then the reduced
// image has a row on the bottom that was not expanded.
if (!(height & 1))
{
for (int x = 0; x < (int) (width - 3); x += 2)
{
Expand3x2 (src[(((height - 2)/2) * (width/2)) + x/2],
&dest[(height - 2) * width + x], width);
}
}
// If both the width and height are multiples of two, then
// the bottom right corner was never expanded.
if (!(width & 1) && !(height & 1))
{
Expand2x2 (src[(((height-2)/2) * (width/2)) + (width-2)/2],
&dest[(height-2) * width + (width-2)], width);
}
// When expanding, the outer edges need a little more
// fixing because they have not been interpolated enough.
// The top row only got interpolated with half the number
// of pixels needed.
for (int x = 0; x < (int) (width); x++)
dest[x] *= 2;
// Same with the left column. The top left corner only got 1/4
// the number of pixels it needed, but we're multiplying it
// by 2 twice, so it's OK.
for (y = 0; y < (int) (height); y++)
dest[y * width] *= 2;
// If the width is an odd number, the number of pixels needed
// to interpolate the right column is 1/2. If it's an even
// number, then it's OK.
if (width & 1)
for (int y = 1; y <= (int) (height); y++)
dest[y * width - 1] *= 2;
// If the height is an odd number, then the bottom row needs
// twice as many pixels to interpolate correctly.
if (height & 1)
for (int x = 0; x < (int) (width); x++)
dest[(height - 1) * width + x] *= 2;
// Notice that the NE, SE, and SW corners are OK -- they
// were multiplied by 2 or 4 automatically when the sides
// were being fixed.
}
//End of File