0

I can't figure out how to fix the colors of large.bmp when I run it. It resizes correctly but the pixels are all messed up and don't look like the original. Someone help me? Please and thank you!

// Copies a BMP file

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

#include "bmp.h"

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

    // remember filenames
    int n = atoi(argv[1]);
    char *infile = argv[2];
    char *outfile = argv[3];

    // If user inputs n not as 0-100
    if (n < 0 || n > 100)
    {
        fprintf(stderr, "Use 0-100 for n\n");
        return 2;
    }

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

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

    // 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;
      }

     int oldpadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // Storage
    BITMAPFILEHEADER old_bf;
    BITMAPINFOHEADER old_bi;

    // Stores original width and height
    old_bi.biWidth = bi.biWidth;
    old_bi.biHeight = bi.biHeight;

    // Updates height and width
    bi.biWidth *= n;
    bi.biHeight *= n;

    int newpadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // Updates biSizeImage with updated sizes and newpadding
    bi.biSize = ((sizeof(RGBTRIPLE) * bi.biWidth) + newpadding) * 
    abs(bi.biHeight);

    // Updates bfSize with updated sizes and newpadding
    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(old_bi.biHeight); i < biHeight; i++)
    {
        // Loop to recopy each line (resize vertically)
        for (int j = 0; j < n - 1; j++)
        {
            // iterate over pixels in scanline
            for (int k = 0; k < old_bi.biWidth; k++)
            {
                // temporary storage
                RGBTRIPLE triple;

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

                // To copy pixels horizontally
                for (int l = 0; l < n; l++)
                {
                    // write RGB triple to outfile
                    fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
                }

                // Go back to the beginning of the line to copy again
                fseek(inptr, (old_bi.biWidth * sizeof(RGBTRIPLE)) * -1, 
                SEEK_CUR);
            }

            // Add newpadding, if any
            for (int m = 0; m < newpadding; m++)
            {
                fputc(0x00, outptr);
            }
        }

        // Iterate over pixels in scanline one more time
        for (int k = 0; k < old_bi.biWidth; k++)
        {
            // Temporary storage
            RGBTRIPLE triple;

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

            // To copy pixels horizontally
            for (int l = 0; l < n; l++)
            {
                // Write RGB triple to outfile
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }

        }

        // Add newpadding, if any
        for (int m = 0; m < newpadding; m++)
        {
            fputc(0x00, outptr);
        }

        // Skip over old padding
        fseek(inptr, oldpadding, SEEK_CUR);
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

1 Answer 1

0

Well there are issues with your for loop.

I don't understand why you wrote the code twice instead of making a for look.

Also why did you use n - 1 in this loop?:

// Loop to recopy each line (resize vertically)
    for (int j = 0; j < n - 1; j++)

You will also need to use the fSeek function you do the vertical resizing. To move the pointer the the beginning of the line and then to the back.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

You must log in to answer this question.

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