Listing 1: The Reduce function

void LP::Reduce (unsigned level)
{
    // Reduce an image using a three by three block

    if (level >= _levels || level + 1 >= _levels)
        throw "Level is out of range";

    unsigned char *src = _r_images[level];
    unsigned char *dest = _r_images[level + 1];
    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)
        {
            // Reduce argument is the top left corner
            // of the sample block

            unsigned char r = Reduce3x3 (&src[y * width + x], width);

            dest[((y / 2) * (width / 2)) + x / 2] = r;
        }
    }

    // Fix the edges

    // If the width is a multiple of two, then the reduced 
    // image has a missing column on the right hand side.

    if (!(width & 1))
    {
        for (int y = 0; y < (int) (height - 3); y += 2)
        {
            unsigned char r =
                Reduce2x3 (&src[y * width + width - 2], width);

            dest[((y / 2) * (width / 2)) + (width - 2) / 2] = r;
        }
    }

    // If the height is a multiple of two, then the reduced 
    // image has a missing row on the bottom.

    if (!(height & 1))
    {
        for (int x = 0; x < (int) (width - 3); x += 2)
        {
            unsigned char r =
                Reduce3x2 (&src[(height - 2) * width + x], width);
            dest[(((height - 2) / 2) * (width / 2)) + x / 2] = r;
        }
    }

    // If both the width and height are multiples of two, then
    // we missed the bottom right corner.

    if (!(width & 1) && !(height & 1))
    {
        unsigned char r =
            Reduce2x2 (&src[(height - 2) * width + (width - 2)],
                       width);

        dest[(((height-2)/2) * (width / 2)) + (width - 2) / 2] = r;
    }
}
//End of File