0

So I'm trying to figure out what goes wrong in my code and can't seem to find the problem. When I try to resize an image it just copies the first skanlines and the rest of the picture is black. I hope any of you guys figures out what is going on and gives me a tip so I can solve the problem.

The code:

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

#include "bmp.h"

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

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

    //assure n is positive and over 100
    if(n < 1 || n > 100)
    {
        printf("n must be a positive integer over 100");
        return 6;
    }

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

    //store the width and height values of the infile
    int infile_width = bi.biWidth;
    int infile_height = bi.biHeight;

    //change and store the width and height values of the outfile
    bi.biWidth = bi.biWidth * n;
    bi.biHeight = bi.biHeight * n;

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

    // change BITMAPFILEHEADER and BITMAPINFOHEADER values for the outfile
    bi.biSizeImage = bi.biHeight * (bi.biWidth + outfile_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);

    // iterate over infile's scanlines
    for (int i = 0, f = abs(infile_height); i < f; i++)
    {
        for(int o = 0; o < n; o++)
        {
            fseek(inptr, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + i * (infile_width * sizeof(RGBTRIPLE) + infile_padding), SEEK_SET);
            {
                // iterate over pixels in scanline
                for (int j = 0, m = infile_width; j < m; j++)
                {
                    // temporary storage
                    RGBTRIPLE triple;

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

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

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

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

    // close outfile
    fclose(outptr);

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

There's more than one problem here, but for now you should think how resizing works in a 2D image.

4
  • We are multiplying every pixel by n and every scanline by n so I guess I missed one for loop, but it still doesn't work. I editted the code and also made some other changes on the fseek function but its still not right. Check the corrections if you have the time. – Petar Petrov Aug 27 '16 at 14:41
  • I guess the problem is with my padding now because when I try to resize large.bmp it's working fine bout not with small.bmp. Large.bmp doesn't need padding while small.bmp needs one so the problem must be there somewhere. – Petar Petrov Aug 27 '16 at 14:48
  • I figured it out, just removed the padding that the copy.c file had. I just had to put the outfile's padding. – Petar Petrov Aug 27 '16 at 15:08
  • Congratulations! :) – thomas Aug 27 '16 at 15:37

You must log in to answer this question.

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