An algorithm I use for scaling bitmaps to any arbitrary factor goes like
1) Create a blank destination bitmap of size (source_width * scale_factor,
source_height * scale_factor).
2) Loop through every pixel in the destination image.
3) Calculate where that pixel would be in the source image (dest_x /
scale_factor, dest_y / scale_factor) using floating-point math.
4) The result will be a fractional coordinate somewhere between for source
pixels, like this:
(it may, by chance, land right on a source pixel, but the math will still
come out OK)
5) Perform a linear interpolation of pixels A & B and C & D horizontally,
AB = x_delta * (B - A) + A
CD = x_delta * (D - C) + C
(x_delta is the fractional portion of the source X value: source_x -
6) Perform a linear interpolation of AB & CD vertically, like this:
result = y_delta * (CD - AB) + AB
7) The resulting pixel value is assigned to the destination image.
This algorithm provides for a high-quality scaled version of the original
image. It is easy to implement scale-to-gray with this algorithm also.