Help with a program to resize an image

This is a discussion on Help with a program to resize an image within the C Programming forums, part of the General Programming Boards category; Hi everyone, I am working on a HOMEWORK assignment to resize an image... As this is something that I will ...

  1. #1
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73

    Help with a program to resize an image

    Hi everyone,

    I am working on a HOMEWORK assignment to resize an image... As this is something that I will be graded on, I am NOT asking you do "do it all for me" I am asking for hints and help so that I may continue to learn (and get a good grade at the same time).

    The assignment I am currently working on involves resizing a bmp image by a factor of n. I believe I am close to having a fully working program, The part I am stuck on is writing from an RGB tripple to an array "n times" In my code I have coloured it in red. I know the code that I have there now won't work, but I am not sure what will.

    So my question is: "how do I write the RGB tripple to an array n times"

    Also if you find anything else that is worrisome don't hesitate to tell me!

    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
        char* nchar = argv[1];
        char* infile = argv[2];
        char* outfile = argv[3];
        
        int timeswriten = 0;
        
        //convert nchar to an int
        int n = atoi (nchar);
    
    
    
    
        
        if (n < 1 || n > 100)
        {
        printf("Please try again with a positive number less then 100\n");
        return 1;
        }
    
    
        // 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, bf2;
        fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
    
    
        // read infile's BITMAPINFOHEADER
        BITMAPINFOHEADER bi, bi2;
        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;
        }
        
        
        bi2.biHeight = bi.biHeight *n;
        bi2.biWidth = bi.biWidth *n;
        int padding = (4 -(bi2.biWidth * sizeof(RGBTRIPLE))%4)%4;
        bi2.biSizeImage = (bi2.biWidth * sizeof(RGBTRIPLE) + padding) * abs(bi2.biHeight);
        bf2.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi2.biSizeImage;
    
    
    
    
        // write outfile's BITMAPFILEHEADER and BITMAPINFOHEADER
        fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);
        fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);
    
    
       RGBTRIPLE *buffer = (RGBTRIPLE *)malloc(sizeof(RGBTRIPLE) * bi2.biWidth);
    
    
        // iterate over infile's scanlines
        for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
        {
            // 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);
    
    
                // write RGB tripple to array n times    
                for (int z = 0; z < n; z++) 
                {
                buffer[j]=triple[j];
                }
    
    
              
            }
            
            // write RGB triple to outfile
            fwrite(buffer, 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);
    
    
        // that's all folks
        return 0;
    }

  2. #2
    Registered User
    Join Date
    May 2012
    Posts
    333
    Quote Originally Posted by Dude22 View Post
    Hi everyone,
    Code:
                // write RGB tripple to array n times    
                for (int z = 0; z < n; z++) 
                {
                buffer[j]=triple[j];
                }
    C doesn't allow ypu to assign a structure to another with the = operator.

    either use memcy(&buffer[i], &buffer[i], sizeof(RGBTRIPLE) (horribly inefficient of this case), or assign each member individually.
    You also need to add z to the i and j indices, or, probably easier, increment i and j on each pass.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    http://www.malcolmmclean.site11.com/www

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,820
    > C doesn't allow ypu to assign a structure to another with the = operator.
    Yes, it does (though not as written).

    Apart from abandoning a perfectly good thread, you need something like
    Code:
                for (int z = 0; z < n; z++) 
                {
                    buffer[k++]=triple;
                }
    This generates your n copies of the pixel in the horizontal direction.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  4. #4
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73

    Smile Close, but not quite

    Ok, I have made the recommended changes and the program now compiles and runs with no problems!!! Only the images that it outputs wont open due to "BMP image has bogus header data"

    I am not sure what might be causing this, I have looked over the part of the program where I generate the new header file and nothing jumps out at me a being "wrong". Below is my code, if you could take a look, and give me your opinion on what might be wrong that would be great!

    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
        char* nchar = argv[1];
        char* infile = argv[2];
        char* outfile = argv[3];
        
        //int timeswriten = 0;
        
        //convert nchar to an int
        int n = atoi (nchar);
    
    
    
    
        
        if (n < 1 || n > 100)
        {
        printf("Please try again with a positive number less then 100\n");
        return 1;
        }
    
    
        // 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, bf2;
        fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
    
    
        // read infile's BITMAPINFOHEADER
        BITMAPINFOHEADER bi, bi2;
        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;
        }
        
        
        bi2.biHeight = bi.biHeight *n;
        bi2.biWidth = bi.biWidth *n;
        int padding = (4 -(bi2.biWidth * sizeof(RGBTRIPLE))%4)%4;
        bi2.biSizeImage = (bi2.biWidth * sizeof(RGBTRIPLE) + padding) * abs(bi2.biHeight);
        bf2.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi2.biSizeImage;
    
    
    
    
        // write outfile's BITMAPFILEHEADER and BITMAPINFOHEADER
        fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);
        fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);
    
    
       RGBTRIPLE *buffer = (RGBTRIPLE *)malloc(sizeof(RGBTRIPLE) * bi2.biWidth);
    
    
        // iterate over infile's scanlines
        for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
        {
            // 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);
    
    
                // write RGB tripple to array n times    
                for (int z = 0; z < n; z++) 
                {
                buffer[j++]=triple;
                }
    
    
              
            }
            
            // write RGB triple to outfile
            fwrite(buffer, 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);
    
    
        // that's all folks
        return 0;
    }

    NOTE TO salem: I have not abandoned the other forum, but I have not received any responses recently, so I decided to try posting my questions here as-well.

  5. #5
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,832
    I don't see you defining all of the bi2 fields. For example: bf.bfType, bf.bfOffBits, bi.biSize, bi.biBitCount, bi.biCompression. There may be more.
    Why don't you try to generate an output images that's the SAME as the input image before doing anything fancier. I mean that’s just basic programming in building blocks and verifying logic.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,820
    > buffer[j++]=triple;
    Read my post again - did I use j ?

    > fwrite(buffer, sizeof(RGBTRIPLE), 1, outptr);
    How long will the buffer be, when you've written each pixel n times?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  7. #7
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    Quote Originally Posted by Salem View Post
    > buffer[j++]=triple;
    Read my post again - did I use j ?
    I didn't use k because it us used later in the program, will using j, or any unused name for the int cause any problems???

    > fwrite(buffer, sizeof(RGBTRIPLE), 1, outptr);
    How long will the buffer be, when you've written each pixel n times?
    Sorry, I don't quite understand what you are getting at...

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,820
    > I didn't use k because it us used later in the program, will using j, or any unused name for the int cause any problems???
    Do you know what all your indices are for?

    Does this make any more sense to you?
    Code:
        for (int row = 0, biHeight = abs(bi.biHeight); row < biHeight; row++)
        {
            // iterate over pixels in scanline
            for (int col = 0; col < bi.biWidth; col++)
            {
                // temporary storage
                RGBTRIPLE triple;
     
     
                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
     
     
                // write RGB tripple to array n times   
                for (int dupe = 0; dupe < n; dupe++)
                {
                buffer[numCopiedPixels++]=triple;
                }
    > Sorry, I don't quite understand what you are getting at...
    In other words, which did you allocate sizeof(RGBTRIPLE) * bi2.biWidth bytes of memory if you're not outputting sizeof(RGBTRIPLE) * bi2.biWidth bytes of memory.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  9. #9
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    Quote Originally Posted by Salem View Post
    > I didn't use k because it us used later in the program, will using j, or any unused name for the int cause any problems???
    Do you know what all your indices are for?

    Does this make any more sense to you?
    Code:
        for (int row = 0, biHeight = abs(bi.biHeight); row < biHeight; row++)
        {
            // iterate over pixels in scanline
            for (int col = 0; col < bi.biWidth; col++)
            {
                // temporary storage
                RGBTRIPLE triple;
     
     
                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
     
     
                // write RGB tripple to array n times   
                for (int dupe = 0; dupe < n; dupe++)
                {
                buffer[numCopiedPixels++]=triple;
                }
    Oh, that makes sense, I have now changed it to something I think should work.

    Sorry, I don't quite understand what you are getting at...
    In other words, which did you allocate sizeof(RGBTRIPLE) * bi2.biWidth bytes of memory if you're not outputting sizeof(RGBTRIPLE) * bi2.biWidth bytes of memory.
    Sorry, I actually still don't get what you are saying, are you pointing out a problem... or asking a question???

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,820
    > Sorry, I actually still don't get what you are saying, are you pointing out a problem... or asking a question???
    Both, actually

    There is a logical inconsistency between
    - the amount of space you allocate
    - the amount of space you write pixels to
    - the amount of space you write to the file

    I've pointed out that the inconsistency exists.

    You look at it, and figure out how to fix it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  11. #11
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    Quote Originally Posted by Salem View Post
    > Sorry, I actually still don't get what you are saying, are you pointing out a problem... or asking a question???
    Both, actually

    There is a logical inconsistency between
    - the amount of space you allocate
    - the amount of space you write pixels to
    - the amount of space you write to the file

    I've pointed out that the inconsistency exists.

    You look at it, and figure out how to fix it.
    Ok, I spent a lot of time going through the program, and have got it a LOT closer to working. It is now at the point where it outputs an image without saying bogus header file.

    It also, is a lot closer to outputting the image properly (although I don't think the width is correct). If you could take a look at my program now, and again, point me in the right direction, that would be great!!!

    Code:
    /****************************************************************************
     * resize.c
     *
     * Computer Science 50
     * Problem Set 4
     *
     * Resizes a BMP piece by piece, just because.
     ***************************************************************************/
           
    #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
        char* nchar = argv[1];
        char* infile = argv[2];
        char* outfile = argv[3];
        
        int timeswriten = 0;
        
        //convert nchar to an int
        int n = atoi (nchar);
    
    
    
    
        
        if (n < 1 || n > 100)
        {
        printf("Please try again with a positive number less then 100\n");
        return 1;
        }
    
    
        // 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;
        }
        
        //save original image headder
        int oldheight = bi.biHeight;
        int oldwidth = bi.biWidth;
        int oldpadding = (4-(oldwidth*sizeof(RGBTRIPLE)) % 4) % 4;
        
        
        bi.biHeight = oldheight *n;
        bi.biWidth = oldwidth *n;
        int padding = (4 -(bi.biWidth * sizeof(RGBTRIPLE))%4)%4;
        bi.biSizeImage = (bi.biWidth * sizeof(RGBTRIPLE) + padding) * abs(bi.biHeight);
        bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi.biSizeImage;
    
    
    
    
        // write outfile's BITMAPFILEHEADER and BITMAPINFOHEADER
        fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
        fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
    
    
        RGBTRIPLE *buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth);
    
    
        // iterate over infile's scanlines
        for (int i = 0; i < abs(oldheight); i++)
        {
            int element = 0;
    
    
            // iterate over pixels in scanline
            for (int j = 0; j < oldwidth; j++)
            {
                // temporary storage
                RGBTRIPLE triple;
    
    
                // read RGB triple from infile and store in buffer
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
    
    
                //iterate over each pixel factor times
                for (int k = 0; k < n; k++)
                {
                    buffer[timeswriten] = triple;
                    element++;
                }
            }
    
    
            // skip over any input padding
            fseek(inptr, oldpadding, SEEK_CUR);
    
    
    
    
            // print each row from buffer factor times
            for (int r = 0; r < n; r++)
            {
                // write RGB triple to outfile
                fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
    
    
                // write padding to outfile
                for (int p = 0; p < padding; p++)
                fputc(0x00, outptr);
    
    
            }
        }
    
    
        // close infile
        fclose(inptr);
    
    
        // close outfile
        fclose(outptr);
    
    
        // that's all folks
        return 0;
    }

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,820
    > buffer[timeswriten] = triple;
    > element++;
    OK, look at my example again, and work out why I only use one variable to keep track of the number of pixels written to the destination buffer.

    > // write RGB triple to outfile
    > fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
    The old width, or the new width?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  13. #13
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    Quote Originally Posted by Salem View Post
    > buffer[timeswriten] = triple;
    > element++;
    OK, look at my example again, and work out why I only use one variable to keep track of the number of pixels written to the destination buffer.
    Oh.... I did that wrong. Ok, I think I have finally fixed that part.


    > // write RGB triple to outfile
    > fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
    The old width, or the new width?
    I am not quite sure what you mean, as far as I know I should be using the new width, which I do.



    After making the change I compiled and ran the program with the test image i have been using all along, which is a very small image. It almost worked, when I viewed it with xxd this is what I saw when I tried to resize the image by 1 (hence not re-sizing it at all):

    ORIGINAL IMAGE:

    0000036: 00ff00 00ff00 00ff00 000000 00ff00 ffffff 00ff00 000000 ........................
    000004e: 00ff00 00ff00 00ff00 000000 ............


    NEW IMAGE:

    0000036: 00ff00 00ff00 00ff00 000000 00ff00 00ff00 00ff00 000000 ........................
    000004e: 00ff00 00ff00 00ff00 000000 ............


    There is a problem, however, when I either try to re-size an image by a factor greater then 1 or, when I try to re-size a larger image. I get a segmentation fault! I have put my code below, If you could take another look at it and let me know what you think that would be great! I have tried to identify the problem using GDB, but so far I have had no success.


    Code:
    /****************************************************************************
     * resize.c
     *
     * Computer Science 50
     * Problem Set 4
     *
     * Resizes a BMP piece by piece, just because.
     ***************************************************************************/
           
    #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
        char* nchar = argv[1];
        char* infile = argv[2];
        char* outfile = argv[3];
        
        int timeswriten = 0;
        
        //convert nchar to an int
        int n = atoi (nchar);
    
    
    
    
        
        if (n < 1 || n > 100)
        {
        printf("Please try again with a positive number less then 100\n");
        return 1;
        }
    
    
        // 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;
        }
        
        //save original image headder
        int oldheight = bi.biHeight;
        int oldwidth = bi.biWidth;
        int oldpadding = (4-(oldwidth*sizeof(RGBTRIPLE)) % 4) % 4;
        
        
        bi.biHeight = oldheight *n;
        bi.biWidth = oldwidth *n;
        int padding = (4 -(bi.biWidth * sizeof(RGBTRIPLE))%4)%4;
        bi.biSizeImage = (bi.biWidth * sizeof(RGBTRIPLE) + padding) * abs(bi.biHeight);
        bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi.biSizeImage;
    
    
    
    
        // write outfile's BITMAPFILEHEADER and BITMAPINFOHEADER
        fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
        fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
    
    
        RGBTRIPLE *buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth);
    
    
        // iterate over infile's scanlines
        for (int i = 0; i < abs(oldheight); i++)
        {
    
    
            // iterate over pixels in scanline
            for (int j = 0; j < oldwidth; j++)
            {
                // temporary storage
                RGBTRIPLE triple;
    
    
                // read RGB triple from infile and store in buffer
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
    
    
                //iterate over each pixel factor times
                for (int k = 0; k < n; k++)
                {
                    buffer[timeswriten++] = triple;
                }
            }
    
    
            // skip over any input padding
            fseek(inptr, oldpadding, SEEK_CUR);
    
    
    
    
            // print each row from buffer factor times
            for (int r = 0; r < n; r++)
            {
                // write RGB triple to outfile
                fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
    
    
                // write padding to outfile
                for (int p = 0; p < padding; p++)
                fputc(0x00, outptr);
    
    
            }
        }
    
    
        // close infile
        fclose(inptr);
    
    
        // close outfile
        fclose(outptr);
    
    
        // that's all folks
        return 0;
    }

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,820
    > buffer[timeswriten++] = triple;
    When do you think would be a good time to reset timeswriten back to zero?

    Or put another way, when are you going to start using a debugger instead of just posting the code and saying "this segfaults".
    Code:
    Compile with debug
    gcc -g prog.c
    
    Load program into the debugger
    gdb ./a.out
    
    Run program with test params
    run 3 in.bmp out.bmp
    
    It segfaults!
    When it segfaults, it points you at a line of code.

    My guess is that it will be the line where you write buffer.

    Further, if you then do
    print timeswriten
    you will see it is a large value, perhaps very large, but certainly larger than the scaled width of the bitmap.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  15. #15
    Noobin to the max
    Join Date
    Mar 2013
    Posts
    73
    Quote Originally Posted by Salem View Post
    > buffer[timeswriten++] = triple;
    When do you think would be a good time to reset timeswriten back to zero?

    Or put another way, when are you going to start using a debugger instead of just posting the code and saying "this segfaults".
    Code:
    Compile with debug
    gcc -g prog.c
    
    Load program into the debugger
    gdb ./a.out
    
    Run program with test params
    run 3 in.bmp out.bmp
    
    It segfaults!
    When it segfaults, it points you at a line of code.

    My guess is that it will be the line where you write buffer.

    Further, if you then do
    print timeswriten
    you will see it is a large value, perhaps very large, but certainly larger than the scaled width of the bitmap.
    Oh.... Ok, I have now reset times written back to 0 after the for loop that it is contained in. That seems to fix the seg fault, as I can now run it with any image with any factor (at-least any image and factor I have tried so far). The output is still not correct however, here is the xxd out put for an image with a re-size factor of 3:

    Original image:

    0000036: 00ff00 00ff00 00ff00 000000 00ff00 ffffff 00ff00 000000 ........................
    000004e: 00ff00 00ff00 00ff00 000000 ............

    New image:

    0000036: 00ff00 00ff00 00ff00 000000 000000 000000 000000 000000 ........................
    000004e: 000000 0000ff 0000ff 0000ff 000000 000000 000000 000000 ........................
    0000066: 000000 000000 000000 ff0000 ff0000 ff0000 000000 000000 ........................
    000007e: 000000 000000 000000 000000 00ff00 00ff00 00ff00 000000 ........................
    0000096: 000000 000000 000000 000000 000000 0000ff 0000ff 0000ff ........................
    00000ae: 000000 000000 000000 000000 000000 000000 000000 ff0000 ........................
    00000c6: ff0000 ff0000 000000 000000 000000 000000 000000 000000 ........................
    00000de: 00ff00 00ff00 00ff00 000000 000000 000000 000000 000000 ........................
    00000f6: 000000 0000ff 0000ff 0000ff 000000 000000 000000 000000 ........................
    000010e: 000000 000000 000000 ff0000 ff0000 ff0000 000000 000000 ........................
    0000126: 000000 000000 000000 000000 ............


    It looks to me as if the padding is messed up, and I also don't think this width is working correctly.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. resize image
    By lamko in forum C Programming
    Replies: 22
    Last Post: 09-01-2011, 10:59 AM
  2. C program for text to image
    By karthiks551985 in forum C Programming
    Replies: 7
    Last Post: 10-10-2008, 10:36 AM
  3. png Image Resize
    By bhupesh.kec in forum C Programming
    Replies: 3
    Last Post: 12-06-2007, 07:52 AM
  4. Resize Image File???
    By stickman in forum C++ Programming
    Replies: 4
    Last Post: 09-19-2004, 12:46 PM
  5. how ot add an image in a c program
    By nisharoopa in forum C Programming
    Replies: 3
    Last Post: 07-13-2002, 03:06 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21