0

I'm stocked in resize My main problem is when it comes to enlarge a file that has some padding, i cannot enlarge it But when I run my program trying to enlarge a file with no initial padding, it runs correctly, so I think my mistake should be in the fseek's arguments (lines 134 and 139) I've tried to run my program with the sample files and with Smiley.bmp and Large.bmp it runs okay, but i still have trouble with Small.bmp Thanks in advance!

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

#include "bmp.h"

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

    // checks the times of resizing
    int n = atoi(argv[1]);
    if (n <= 0 || n > 100)
    {
        fprintf(stderr, "Ivalid resize value\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;
    }




    // saves the values of the original picture
    int oldpadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int oldwidth = bi.biWidth;
    int oldheight = bi.biHeight;

    // changing values in terms of n
    bi.biWidth = bi.biWidth * n;
    bi.biHeight = bi.biHeight * n;
    int newpadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; //           determine padding for scanlines for the enlarged picture

    bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + newpadding) *         abs(bi.biHeight); // new size of the image
    bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) +     sizeof(BITMAPINFOHEADER); //new size of the file




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

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




    // iterate over "infile's" (ORIGINAL PICTURE) scanlines
    for (int i = 0, biHeight = abs(oldheight); i < biHeight; i++)
    {
        // REPEAT SCANLINES! does it n times for each scanline of the original picture
        for (int j = 0; j < n; j++)
        {

            // EVERY PIXEL! iterate over pixels in  original scanline
            for (int k = 0; k < bi.biWidth/n; k++)
            {

                // temporary storage
                RGBTRIPLE triple;

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

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

                // adds padding to the new file if needed
                if (newpadding > 0)
                {

                    for (int m = 0; m < newpadding; m++)
                    {

                        fputc(0x00, outptr);
                    }
                }
            }


            // returns the cursor to the beginning of the scanline in the ORIGINAL FILE in case it's not the last repetition
            if(j < n-1)
            {
                fseek(inptr, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + ((sizeof(RGBTRIPLE)*oldwidth + oldpadding)*i), SEEK_SET);
            }
        }

        // skip over padding, if any ORIGINAL FILE
        fseek(inptr, oldpadding, SEEK_CUR);
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

1 Answer 1

0

One problem in the k loop: It is adding padding each time it duplicates a triple instead of one time when it is done with the line.
If you 2x small.bmp it will:

read a triple, write two triples, write new padding
read a triple, write two triples, write new padding
read a triple, write two triples, write new padding

Another problem: You need to skip the old padding each time you read a line from input file. That happens here
fseek(inptr, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + ((sizeof(RGBTRIPLE)*oldwidth + oldpadding)*i), SEEK_SET);
for all but the last line. Since fseek(inptr, oldpadding, SEEK_CUR); is outside the j loop, it only executes once for each line in the input file. It has to execute inside the j loop (conditionally of course) to keep the input file pointer aligned.

1
  • Thank you so much! Now it is working fine! Jan 30, 2017 at 23:11

You must log in to answer this question.

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