Click here to Skip to main content
15,919,132 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am supposed to resize a bmp by the integer n ( betw 1 and 100).
I currently don't have any compilation errors or memory leaks.
The output would be wrong.

I would get blank bmp images (that are resized, though).
I also get:

~/workspace/pset4/bmp/ $ ./resize 3 small.bmp large.bmp
*** Error in `./resize': double free or corruption (top): 0x000000000125c250 ***
Aborted



Thanks a lot,c

What I have tried:

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

         
         if ( ( n < 0 ) || ( n > 100 ) )
         {
           
            printf(" n must be a positive floating integer from 0.0 up till 100.0\n");
            return 1;
          
         }
         
    }

    // remember filenames
    char* infile = argv[2];
    char* outfile = argv[3];
    
     
    // open input file 
    FILE* input = fopen(infile, "r");
    
    if (input == NULL)
    {
        printf("Could not open %s.\n", infile);
        return 2;
    }

    // open output file
    FILE* output = fopen(outfile, "w");
    
    if (output == NULL)
    {
        fclose(input);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 3;
    }
    
     
     
    // read infile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, input);
 
     // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi;
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, input);

    // 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(output);
        fclose(input);
        fprintf(stderr, "Unsupported file format.\n");
        return 4;
    }
    
    int originalwidth = bi.biWidth;
    int originalheight = bi.biHeight;
    int originalpadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
 
    bi.biWidth = bi.biWidth * n;
    bi.biHeight = bi.biHeight * n;
       
    int newpadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
     bi.biSizeImage = bi.biHeight * ( 3 * bi.biWidth + newpadding );
    bf.bfSize = bf.bfOffBits + bi.biSizeImage;    

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

    // write outfile's BITMAPINFOHEADER
    fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, output);
 
    // iterate over infile's scanlines
    for (int i = 0; i < abs(originalheight); i++)
    {
        int numberoflines = 0;
        // iterate over pixels in scanline
        for (int j = 0; j < abs(originalwidth); j++)
        {
             // temporary storage
            RGBTRIPLE triple;

            // read RGB triple from infile
            fread(&triple, sizeof(RGBTRIPLE), 1, input);
            
             
            // write RGB triple to outfile n times for horizontal resize
            for (int a = 0; a < n; a++)
            {
                
                fwrite(&triple, sizeof(RGBTRIPLE), 1, output);
                fclose(output);
                
                
                //temporary = malloc(sizeof(RGBTRIPLE));
                //temporary = fopen("tempmem.txt", "w");
                //fwrite(&triple, sizeof(RGBTRIPLE), 1, temporary);
                
            }
            
            //for (int b = 0; b < n-1; b++)
            //{
                //fwrite(temporary, sizeof(RGBTRIPLE),1, output);
            //}
                
        }

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

        // then add it back (to demonstrate how)
        for (int k = 0; k < newpadding; k++)
        {
            fputc(0x00, output);
        }
        
        if ( numberoflines < n - 1)
        {
            fseek( input, -1 * ( 3 * originalwidth + originalpadding ), SEEK_CUR);
        }
        
        numberoflines++;

    }

    // close infile
    
    //fclose( temporary);
    fclose(input);
   
    // close outfile
    fclose(output);

    // that's all folks
    return 0;
}
Posted
Updated 2-Jan-17 21:09pm
v2

1 solution

I assume that you are using Windows. Then the files should be opened in binary mode to disable newline translation:
FILE* input = fopen(infile, "rb");
FILE* output = fopen(outfile, "wb");


Here you should use the padding of the input:
// skip over padding, if any
// Your code:
//fseek( input, newpadding, SEEK_CUR);
// Should be:
fseek( input, originalpadding, SEEK_CUR);


But the most important error resulting in the error message is here:
// write RGB triple to outfile n times for horizontal resize
for (int a = 0; a < n; a++)
{
    fwrite(&triple, sizeof(RGBTRIPLE), 1, output);
    fclose(output);
}
You are closing the output file!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900