2

I can get smiley.bmp and large.bmp to scale properly, but not small.bmp, where the former is 3x3 and the latter two are larger (exactly how much larger I don't know) -- so I assume my program only works on bitmaps larger than 3x3, and check50 tests with 1x1 and 2x2 images.

The four lines below are the ones I believe are causing trouble. I don't know why nor how the o loop works (if I remove it the program will forcefully scale vertically by a factor of two, but fine horizontally), k represents one pixel, and m duplicates the current pixel. Furthermore, there is must be a better way to do this than using three nested for loops?

for (int o = 0; o < n-1; o++) {
    for (int k = 0; k < bi.biWidth; k++) {
        for (int m = 0; m < n; m++) {
            fwrite((scanline+k), sizeof(RGBTRIPLE), 1, outptr);
        }
    }
}
// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{

    // iterate over pixels in scanline
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;

        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

        // Append triple to scanline
        scanline[j] = triple;

        // write RGB triple to outfile n times
        for (int k = 0; k < n; k++) {
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);

        }
    }

    // Write scanline to outfile n times, as well as duplicate pixels n times
    for (int o = 0; o < n-1; o++) {
        for (int k = 0; k < bi.biWidth; k++) {
            for (int m = 0; m < n; m++) {
                fwrite((scanline+k), sizeof(RGBTRIPLE), 1, outptr);
            }
        }
    }

    // skip over padding in the infile, if any
    fseek(inptr, padding, SEEK_CUR);

    // then add it back to the outfile (to demonstrate how)
    for (int k = 0; k < padding; k++)
    {
        fputc(0x00, outptr);
    }
}

2 Answers 2

2

Your mistake is that you don't add the needed padding for each line that you write to the output file. Inside your outer for loop (the one with the o), right after the ending of the second for loop (the one with the k which writes the whole scanline) you should add the padding. Instead you only do so after the last line of the bunch. You also use the same number of bytes for the in_padding and the out_padding, when they are not the same.

input

###p
###p
###p

So while you should do that (for a 3x3 image enlarged by a factor of 2):

expected output

######pp
######pp
######pp
######pp
######pp
######pp

you do that:

actual output

######
######p
######
######p
######
######p
#: pixel
p: padding

As an improvement, I would suggest you don't write the first line concurrently with reading the scanline. It's better to separate the logic pieces of your code. For example read in one place, and write in another.

As for the 3 nested for loops, I'm afraid you can't escape them. As an improvement if you want, you could create an array to hold the output scanline that is to be written, and write all the pixels at once.

1

I've noticed a minor issue with your code. When you declare the new size of the new image, you do this:

binew.biSizeImage = (binew.biWidth * sizeof(RGBTRIPLE)) * abs(binew.biHeight);

But here, you have forgotten to add the new padding to the width of the image, so if an image requires padding then it will not scale properly by default as there is insufficient space allocated. So you should add the new padding in the brackets before multiplying by the new height.

Hope it helps.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .