0

I am having some trouble with the resize assignment. I've written the following code, when I execute it the output file does show increased size, however the colors are completely scattered (also non-green colors appear). Does anyone know what I did wrong? I am finding this subject extremely difficult to understand. So please correct me if my code shows misunderstandings of the theory. Thanks!

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

#include "bmp.h"

int main(int argc, char *argv[])
{
    // ensure proper usage
    int n = atoi(argv[1]);
    if (argc != 4 || n > 100 || n < 0)
    {
        fprintf(stderr, "Usage: ./copy infile outfile\n");
        return 1;
    }

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

    // open input file 
    FILE *inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "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;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

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

    // 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;
    }
    bi.biWidth *= n;
    int new_padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    bi.biHeight = abs(bi.biHeight) * n;
    bi.biSizeImage = abs(bi.biHeight) * (bi.biWidth * sizeof(RGBTRIPLE) + new_padding);
    bf.bfSize = bi.biSizeImage + 54;

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

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

    // determine padding for scanlines
    int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
        for (int t = 0; t < n; t++)
        {
            // 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);
                for (int q = 0; q < n; q++)
                {    
                    // write RGB triple to outfile
                    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 < padding; k++)
        {
            fputc(0x00, outptr);
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

1 Answer 1

1

Please access argv[1] only after you have verified that argc>1, otherwise atoi dereferences arbitrary value, and you might get random segfaults if calling the programme without arguments.

How do padding and newpadding differ? In your code, both are calculated based on the resized image's width.

You don't want to change the bi.biHeight's sign, so no abs in that assignment. Otherwise, you'd flip your image upside down, as that's the meaning of sign in BMP's image height.

You might want to store the input file's width and height, and use those on the first and third of the four nested for loops.

You store one pixel at a time, so you'll need to read any single line n times, meaning you'll need some fseek resetting input file's pointer to the beginning of the line. Also make sure you're skipping/writing the correct padding (those might differ for the two files), and ensure each output line has output padding written to the file.

3
  • Great help, thank you! Feb 9, 2017 at 17:41
  • So I changed all the things you said and I think the program (pastebin.com/R6XWLSwr) is really close to working. However the output file it generates shows a somewhat distorted form of small.bmp. I checked my code in general and my for loops in particular to find a shifted range. But it seems there isn't any. Do you know what's wrong? Feb 9, 2017 at 18:49
  • Looks like in the second fseek, your +padding is outside the parentheses, so your step back is too short by twice the padding.
    – Blauelf
    Feb 10, 2017 at 6:09

You must log in to answer this question.

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