0

I've tried to do this by going back to the beginning of each scanline n times. I'm fairly sure that my problem lies in where I've tried to reposition to the beginning of the scanline, but I've changed that around to many different values and can't seem to get it right.

#include <stdio.h>
#include <stdlib.h>

#include "bmp.h"

int main(int argc, char* argv[])
{
    // ensure proper usage
    if (argc != 4)
    {
        printf("Usage: ./resize n infile outfile\n");
        return 1;
    }

    // remember filenames
    char* infile = argv[2];
    char* outfile = argv[3];

    // remember size
    int n = atoi(argv[1]);

    //ensure size is inbetween 1 and 100
    if (n < 1 || n > 100)
    {
        printf("please enter a n between 1 and 100\n");
        return 5;
    }

    // open input file 
    FILE* inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        printf("Could not open %s.\n", infile);
        return 2;
    }

    // open output file
    FILE* outptr = fopen(outfile, "w");
    if (outptr == NULL)
    {
        fclose(inptr);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 3;
    }

    // read infile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf, bf_new;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
    bf_new = bf;

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi, bi_new;
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
    bi_new = bi;

    // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
    if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
        bi.biBitCount != 24 || bi.biCompression != 0)
    {
        fclose(outptr);
        fclose(inptr);
        fprintf(stderr, "Unsupported file format.\n");
        return 4;
    }

    // determine new dimensions
    bi_new.biHeight = bi.biHeight * n;
    bi_new.biWidth = bi.biWidth * n;

    // calculate padding
    int new_padding = (4 - (bi_new.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // calculate further dimensions
    bi_new.biSizeImage = abs(bi_new.biHeight) * (bi_new.biWidth * sizeof(RGBTRIPLE) + new_padding);
    bf_new.bfSize = bi_new.biSizeImage + 54;

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

    // write outfile's BITMAPINFOHEADER
    fwrite(&bi_new, sizeof(BITMAPINFOHEADER), 1, outptr);

    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
        // iterate over scanline n times
        for (int y = 0; y < n; y++)
        {
            // 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 RGB triple to outfile n times
                for (int x = 0; x < n; x++)
                    fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }

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

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

            // return to beginning of scanline
            fseek(inptr, -(bi.biWidth + padding), SEEK_CUR);
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}
1

Your you are very close to the solution. The most serious problem of this program is the padding:

fseek(inptr, -(bi.biWidth + padding), SEEK_CUR);

your value is not correct, but nearly. note that biWidth is the width in pixels, which is made each three bytes (if I remember correctly) in an uncompressed bmp.

for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)

in each iteration loop for, you must place the cursor in the right position again using fseek, it is the same value as before but positive

2
  • So if i understand correctly, to go back by the correct number of bytes I need to multiply the biWidth by 3?
    – roncook
    Sep 19 '16 at 12:29
  • In fact, you should multiply by 3 bi.biWidth and padding
    – MARS
    Sep 19 '16 at 18:48

You must log in to answer this question.

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