1

I've been stuck on this problem for over a week now, and even after reading answers to a few similar questions, I'm not getting where I'm going wrong :(

Watching the walkthrough, I wasn't quite sure if I understood how to resize vertically, so I thought I'd try out the rest and resize horizontally first, and then try to wrap my head around how the vertical part works. But even as my code for horizontal resizing (right now) makes perfect sense to me, it's doing something strange altogether. It does reproduce the same image when n = 1, but for all other values, it prints random colours, and even though I did nothing about the vertical resizing yet, the output is resized vertically as well.

Here's the relevant part of my code:

// determine infile's padding
    int in_pad = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // determine outfile's padding
    int out_pad = (4 - (n * bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // update outfile's header info
    bi.biWidth *= n;
    bi.biHeight *= n;
    bi.biSizeImage = bi.biSizeImage * (n^2) + out_pad;
    bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    // write outfile's BITMAPFILEHEADER
    fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);

    // write outfile's BITMAPINFOHEADER
    fwrite(&bi, sizeof(BITMAPINFOHEADER), 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);

            // write horizontally resized RGB triple
            for (int k = 0; k < n; k++)
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
        }

        // write outfile's padding
        for (int k = 0; k < out_pad; k++)
            fputc(0x00, outptr);

        // skip over infile's padding, if any
        fseek(inptr, in_pad, SEEK_CUR);
    }

(The parts before and after this are almost the same as in copy.c)

I also tried to make sense of what's going on in my code by comparing the header info of my file with the staff's solution, but it resulted in this, which I'm unable to comprehend (so I need a little help here too). By the way, this is what my outfile [try.bmp] looks like when n = 2, and this is what it looks like when n = 4.

I guess I'm stuck because there are some concepts that I'm trying to use without properly understanding them, but the problem is that I don't know what those concepts are.
Anyway, any help is deeply appreciated!

1 Answer 1

1

The calculation of the headings is clearly incorrect, as shown in its image, one of the difficulties of this set is that it needs extensive documentation and a deep understanding of how a BMP works. That is why we should look for information about the structure of a Windows BMP, especially the following two structures: BITMAPFILEHEADER and BITMAPINFOHEADER. These structures have a series of elements, called members or headers, that determine a set of bits to be considered as a BMP file. The most important for this set of problems are what the documentation considers "mandatory." For example, some important headings are biSize, biWidth, biHeight etc.

Some of these headers must be recalculated to obtain a new resized BMP, the output BMP. These calculations are made based on the values of the input BMP, multiplied by the scale factor. Padding must also be calculated. But be careful, we need to keep the values of the input BMP, so it is necessary to define new variables. For example, the statement:

bi.biWidth *= n;
bi.biHeight *= n;

It is not correct, these statements make the height and width values of the input BMP disappear. To conserve these values we will use new variables of the structure type:

LONG oldbiWidth = bi.biWidth;
....
bi.biWidth = oldbiWidth * n;

The width and height values of the input BMP will be used to iterate over each BMP line in the for loops, which will resize horizontally and vertically:

    // iterate over infile's scanlines   
    for (int i = 0, biHeight = abs(oldbiHeight); i < biHeight; i++)

.......

        // iterate over pixels in scanline
           for (int j = 0; j < oldbiWidth; j++)
......

Another incorrect header is bi.biSizeImage, operator ^, it is a bit-level operator, I don't think you're going to get a correct value. Make sure you understand what biSizeImage is, its calculation is a function of the height, width and padding of the output BMP. When you have the correct value of bi.biSizeImage, you should get the correct value from bf.bfSize. The big problem is related to padding and the use of the fseek () function, but I think it is a matter of a new question. Let's solve the issue of headings, and look forward.

3
  • I understand that you probably aren't a native English speaker (just for the record, neither am I), but I'm having trouble understanding what you're trying to say. I could make out 2 problems that you pointed out- not storing the old height and width values, and incorrect header calculations- and have fixed those, but I'm not sure I'm getting the rest of my mistakes. Could you please rephrase the rest of your answer? Thanks anyway! Commented Jul 31, 2019 at 15:26
  • I have to apologize for my English, although I study English for many years it is very difficult to express myself in this language, I have to apologize for my awkwardness
    – MARS
    Commented Aug 2, 2019 at 12:27
  • Hey, don't worry too much about your English; it's not that incomprehensible after all! Even after years of practice, sometimes it just happens that we just can't express ourselves as well as we intend to...Anyway, I get what you're saying now, so thanks a lot and here's your upvote! Commented Aug 3, 2019 at 13:28

You must log in to answer this question.

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