Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    15
    Rep Power
    0

    Need help resizing a bitmap file


    Hello all!

    I am having a very hard trying to figure out how to resize a bitmap file. I feel like I'm very close(as I'm getting some output). However, my output file outputs a black color. When I performed xxd on my output file, I actually noticed that the colors are being written to the file. Just for some reason I'm not seeing it. Here is the code I currently have:

    FILE* inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
    printf("Could not open %s.\n", infile);
    return 4;
    }

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

    // read infile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi;
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

    Oldwidth=bi.biWidth;
    OldHeight=bi.biHeight;
    oldSizeImage=bi.biSizeImage;

    bi.biWidth=bi.biWidth*factor;

    bi.biHeight=bi.biHeight*factor;

    oldpadding= (4-(Oldwidth*sizeof(RGBTRIPLE)) % 4) % 4;
    bi.biSizeImage=bi.biWidth*(abs(bi.biHeight))*(sizeof(RGBTRIPLE));

    // 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;
    }
    RGBTRIPLE *buffer=NULL;
    buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth);

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

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

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


    // 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
    fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

    //iterate over each pixel factor times

    for (int k = 0; k <factor; k++)
    {
    buffer[k]=triple;


    }
    // write RGB triple to outfile
    // fwrite(&triple, sizeof(RGBTRIPLE), bi.biWidth, outptr);

    }
    // skip over padding, if any
    fseek(inptr,54 + (Oldwidth*sizeof(RGBTRIPLE)*i), SEEK_SET);


    for (int r = 0; r < factor; r++)
    {

    fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
    }
    // write padding to outfile

    for (int p = 0; p < padding; p++)
    fputc(0x00, outptr);


    }

    Any help or suggestions would greatly be appreciated. thanks.
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    First, use [code][/code] tags when posting code.

    Like so
    Code:
    #include <stdio.h>
    
    int main()
    {
      FILE *inptr = fopen(infile, "r");
      if (inptr == NULL) {
        printf("Could not open %s.\n", infile);
        return 4;
      }
    
      // open output file
      FILE *outptr = fopen(outfile, "w");
      if (outptr == NULL) {
        fclose(inptr);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 5;
      }
    
      // read infile's BITMAPFILEHEADER
      BITMAPFILEHEADER bf;
      fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
    
      // read infile's BITMAPINFOHEADER
      BITMAPINFOHEADER bi;
      fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
    
      Oldwidth = bi.biWidth;
      OldHeight = bi.biHeight;
      oldSizeImage = bi.biSizeImage;
    
      bi.biWidth = bi.biWidth * factor;
    
      bi.biHeight = bi.biHeight * factor;
    
      oldpadding = (4 - (Oldwidth * sizeof(RGBTRIPLE)) % 4) % 4;
      bi.biSizeImage = bi.biWidth * (abs(bi.biHeight)) * (sizeof(RGBTRIPLE));
    
      // 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;
      }
      RGBTRIPLE *buffer = NULL;
      buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth);
    
      // write outfile's BITMAPFILEHEADER
      fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
    
      // write outfile's BITMAPINFOHEADER
      fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
    
      // determine padding for scanlines
      int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    
      // 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
          fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
    
          //iterate over each pixel factor times
          for (int k = 0; k < factor; k++) {
            buffer[k] = triple;
          }
    // write RGB triple to outfile
    // fwrite(&triple, sizeof(RGBTRIPLE), bi.biWidth, outptr);
        }
        // skip over padding, if any
        fseek(inptr, 54 + (Oldwidth * sizeof(RGBTRIPLE) * i), SEEK_SET);
    
        for (int r = 0; r < factor; r++) {
          fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
        }
        // write padding to outfile
        for (int p = 0; p < padding; p++)
          fputc(0x00, outptr);
      }
      return 0;
    }
    Second - what tests have you done?
    The obvious case with factor=1 should just make a copy of the file - does it?

    What test bmp files do you have?
    3x3 4x4 and 5x5 should allow you to test the most interesting aspects of padding, and be small enough that you can single-step the code without having to wait for ages for each row to complete (for example). They're also small enough to visually check in a hex editor.

    Your padding calculations seem overly complicated.

    The fseek to skip the padding might be better as
    fseek(inptr,oldPadding,SEEK_CUR);

    On windows, you need to open the files in "rb" and "wb" modes.
    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
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    15
    Rep Power
    0
    Originally Posted by salem
    First, use [code][/code] tags when posting code.

    Like so
    Code:
    #include <stdio.h>
    
    int main()
    {
      FILE *inptr = fopen(infile, "r");
      if (inptr == NULL) {
        printf("Could not open %s.\n", infile);
        return 4;
      }
    
      // open output file
      FILE *outptr = fopen(outfile, "w");
      if (outptr == NULL) {
        fclose(inptr);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 5;
      }
    
      // read infile's BITMAPFILEHEADER
      BITMAPFILEHEADER bf;
      fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
    
      // read infile's BITMAPINFOHEADER
      BITMAPINFOHEADER bi;
      fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
    
      Oldwidth = bi.biWidth;
      OldHeight = bi.biHeight;
      oldSizeImage = bi.biSizeImage;
    
      bi.biWidth = bi.biWidth * factor;
    
      bi.biHeight = bi.biHeight * factor;
    
      oldpadding = (4 - (Oldwidth * sizeof(RGBTRIPLE)) % 4) % 4;
      bi.biSizeImage = bi.biWidth * (abs(bi.biHeight)) * (sizeof(RGBTRIPLE));
    
      // 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;
      }
      RGBTRIPLE *buffer = NULL;
      buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth);
    
      // write outfile's BITMAPFILEHEADER
      fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
    
      // write outfile's BITMAPINFOHEADER
      fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
    
      // determine padding for scanlines
      int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    
      // 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
          fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
    
          //iterate over each pixel factor times
          for (int k = 0; k < factor; k++) {
            buffer[k] = triple;
          }
    // write RGB triple to outfile
    // fwrite(&triple, sizeof(RGBTRIPLE), bi.biWidth, outptr);
        }
        // skip over padding, if any
        fseek(inptr, 54 + (Oldwidth * sizeof(RGBTRIPLE) * i), SEEK_SET);
    
        for (int r = 0; r < factor; r++) {
          fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
        }
        // write padding to outfile
        for (int p = 0; p < padding; p++)
          fputc(0x00, outptr);
      }
      return 0;
    }
    Second - what tests have you done?
    The obvious case with factor=1 should just make a copy of the file - does it?

    What test bmp files do you have?
    3x3 4x4 and 5x5 should allow you to test the most interesting aspects of padding, and be small enough that you can single-step the code without having to wait for ages for each row to complete (for example). They're also small enough to visually check in a hex editor.

    Your padding calculations seem overly complicated.

    The fseek to skip the padding might be better as
    fseek(inptr,oldPadding,SEEK_CUR);

    On windows, you need to open the files in "rb" and "wb" modes.


    Thanks Salem for getting back to me. I appreciate it. I have not done a hex dump to see the output of my code(I'll be sure to do that tonight).
    I agree about my padding lol.What happpened, I started to question the padding I initially had. The padding that you output(fseek(inptr,oldPadding,SEEK_CUR) is the padding I initially had. I do have two test files, and there is an enlargement going on. But do you know or have some sort of an idea on what would be causing the black output to display on my output file?
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    But do you know or have some sort of an idea on what would be causing the black output to display on my output file
    First of all, you didn't post your complete code. So, I have to ask if you have byte aligned the BitmapFileHeader structure. Failing to byte align the structure would throw off everything in your file by two bytes causing inaccurate reads and writes.

    Secondly, I don't see where you are adding your "factor" to the biWidth and biHeight variable fields of your output BitmapInfoHeader structure.

    Finally, I don't see where you calculate the value for the bfSize for your output BitmapInfoHeader.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    15
    Rep Power
    0
    Originally Posted by BobS0327
    First of all, you didn't post your complete code. So, I have to ask if you have byte aligned the BitmapFileHeader structure. Failing to byte align the structure would throw off everything in your file by two bytes causing inaccurate reads and writes.

    Secondly, I don't see where you are adding your "factor" to the biWidth and biHeight variable fields of your output BitmapInfoHeader structure.

    Finally, I don't see where you calculate the value for the bfSize for your output BitmapInfoHeader.
    Code:
        // ensure proper usage
        if (argc != 4)
        {
            printf("Usage: resize n infile outfile\n");
            return 1;
        }
    
        // remember filenames
        char* number=argv[1];
        char* infile = argv[2];
        char* outfile = argv[3];
        
       
        factor=atoi(number); 
        
        
    /*    if (!isdigit(factor))*/
    /*        {*/
    /*            printf("Resize factor must be an integer\n");*/
    /*            return 2;*/
    /*     }*/
    
       
       
        
    if (factor>100)
    {
    
    
    
     printf("Please enter in a number greater than 0 and less than or equal to 100 ");
     printf(" \n");
     printf("%d",factor);
            return 3;
          
    }
        // open input file 
        FILE* inptr = fopen(infile, "r");
        if (inptr == NULL)
        {
            printf("Could not open %s.\n", infile);
            return 4;
        }
    
        // open output file
        FILE* outptr = fopen(outfile, "w");
        if (outptr == NULL)
        {
            fclose(inptr);
            fprintf(stderr, "Could not create %s.\n", outfile);
            return 5;
        }
    
        // read infile's BITMAPFILEHEADER
        BITMAPFILEHEADER bf;
        fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
    
        // read infile's BITMAPINFOHEADER
        BITMAPINFOHEADER bi;
        fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
    
         Oldwidth=bi.biWidth;
         OldHeight=bi.biHeight;
         oldSizeImage=bi.biSizeImage; 
    
         bi.biWidth=bi.biWidth*factor;
        
         bi.biHeight=bi.biHeight*factor;
                     
         oldpadding= (4-(Oldwidth*sizeof(RGBTRIPLE)) % 4) % 4; 
         bi.biSizeImage=bi.biWidth*(abs(bi.biHeight))*(sizeof(RGBTRIPLE));
     
         
         
         
         
        // 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;
        }
           RGBTRIPLE *buffer=NULL;
          buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth); 
        
    
         
         
        // write outfile's BITMAPFILEHEADER
        fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
    
        // write outfile's BITMAPINFOHEADER
        fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
    
        // determine padding for scanlines
        int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
       
       
        // 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++)
            {
              int k=0;
                // temporary storage
                RGBTRIPLE triple;
    
                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
              
                 //iterate over each pixel factor times  
              
              //   for (int k = 0; k <factor; k++) 
              //  { 
                    buffer[k]= triple;
                   // temp= (BYTE)temp2; 
                 
              //  } 
               // write RGB triple to outfile 
              // fwrite(&triple, sizeof(RGBTRIPLE), bi.biWidth, outptr); 
              fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr); 
                
             } 
              // skip over padding, if any
              // fseek(inptr, 54 + (Oldwidth*sizeof(RGBTRIPLE)*i), SEEK_SET); 
                  fseek(inptr, padding, SEEK_CUR);
               
    /*           for (int r = 0; r < factor; r++) */
    /*           { */
    /*            */
    /*           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);


    here it is bob!
  10. #6
  11. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    That's not complete code.

    Where is main() ?
    Where is the definition of your structs BITMAPFILEHEADER, BITMAPINFOHEADER and RGBTRIPLE. Are you assuming we're all visual studio users with access to windows.h?

    Complete code is where we can do copy/paste into a source file, and compile it with ANY ANSI/ISO compatible compiler. Otherwise, you're just cutting down on the number of people who can help you (who have your compiler), and can be bothered to patch up your code to make it compile.
    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
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    Well, the submitted code isn't compilable and it still doesn't indicate how you're implementing the various required bitmap structures. For example, in the Windows environment, you could use the windows.h header file in order to use the BitmapInfoHeader structure etc.

    But from a Microsoft compiler perspective, you would byte align the BITMAPFILEHEADER structure as follows:

    Code:
    #pragma pack(push)
    #pragma pack(1)
    
    typedef struct 
    { 
    	WORD   bfType; 
    	DWORD  bfSize; 
    	WORD   bfReserved1; 
    	WORD   bfReserved2; 
    	DWORD  bfOffBits; 
    }BITMAPFILEHEADER; 
    
    #pragma pack(pop)
    If you use the sizeof macro to return the total size of this structure as it appears above, it would return 14 bytes which is the required structure size in the bitmap file format. If you did NOT use the MS pragma commands as indicated above, sizeof would return 16 bytes as the total size of the structure which will cause your read and writes on the BMP file format to be inaccurate. In other words, the structure is being padded which is what you do NOT want.

    If you want to continue working on this assignment, you must post compilable code for us to review. This compilable code will consist of the following three structures:

    BITMAPINFOHEADER
    RGBTRIPLE
    BITMAPFILEHEADER (the structure above)

    As a starting point, I would suggest that you clone a BITMAPFILEHEADER struct from your input BMP and then modify it to be used in writing the output BMP file.

    One such modification would be as follows:

    Code:
    output.biWidth = bi.biWidth * factor;
    output.biHeight = bi.biHeight * factor;
    Last edited by BobS0327; January 28th, 2013 at 11:36 PM.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    15
    Rep Power
    0
    Originally Posted by salem
    That's not complete code.

    Where is main() ?
    Where is the definition of your structs BITMAPFILEHEADER, BITMAPINFOHEADER and RGBTRIPLE. Are you assuming we're all visual studio users with access to windows.h?

    Complete code is where we can do copy/paste into a source file, and compile it with ANY ANSI/ISO compatible compiler. Otherwise, you're just cutting down on the number of people who can help you (who have your compiler), and can be bothered to patch up your code to make it compile.
    sorry man! LOL....not trying to be a butt at all...
    Code:
           
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include "bmp.h"
    
    int main(int argc, char* argv[])
    {
    int factor=0;
    int Oldwidth=0;
    int OldHeight=0;
    int oldpadding=0;
    int oldSizeImage =0;
    
    
    
    
    
    
    
        // ensure proper usage
        if (argc != 4)
        {
            printf("Usage: resize n infile outfile\n");
            return 1;
        }
    
        // remember filenames
        char* number=argv[1];
        char* infile = argv[2];
        char* outfile = argv[3];
        
       
        factor=atoi(number); 
        
        
    /*    if (!isdigit(factor))*/
    /*        {*/
    /*            printf("Resize factor must be an integer\n");*/
    /*            return 2;*/
    /*     }*/
    
       
       
        
    if (factor>100)
    {
    
    
    
     printf("Please enter in a number greater than 0 and less than or equal to 100 ");
     printf(" \n");
     printf("%d",factor);
            return 3;
          
    }
        // open input file 
        FILE* inptr = fopen(infile, "r");
        if (inptr == NULL)
        {
            printf("Could not open %s.\n", infile);
            return 4;
        }
    
        // open output file
        FILE* outptr = fopen(outfile, "w");
        if (outptr == NULL)
        {
            fclose(inptr);
            fprintf(stderr, "Could not create %s.\n", outfile);
            return 5;
        }
    
        // read infile's BITMAPFILEHEADER
        BITMAPFILEHEADER bf;
        fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
    
        // read infile's BITMAPINFOHEADER
        BITMAPINFOHEADER bi;
        fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
    
         Oldwidth=bi.biWidth;
         OldHeight=bi.biHeight;
         oldSizeImage=bi.biSizeImage; 
    
         bi.biWidth=bi.biWidth*factor;
        
         bi.biHeight=bi.biHeight*factor;
                     
         oldpadding= (4-(Oldwidth*sizeof(RGBTRIPLE)) % 4) % 4; 
         bi.biSizeImage=bi.biWidth*(abs(bi.biHeight))*(sizeof(RGBTRIPLE));
     
         
         
         
         
        // 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;
        }
           RGBTRIPLE *buffer=NULL;
           buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth); 
        
    
         
         
        // write outfile's BITMAPFILEHEADER
        fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
    
        // write outfile's BITMAPINFOHEADER
        fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
    
        // determine padding for scanlines
       int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
       
       
        // iterate over infile's scanlines
        for (int i = 0, BHeight=abs(OldHeight);i<BHeight; i++)
        {
             
            // iterate over pixels in scanline
            for (int j = 0; j < Oldwidth; j++)
            {
            
                // temporary storage
                RGBTRIPLE triple;
    
                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
              
                 //iterate over each pixel factor times  
              
                for (int k = 0; k <factor; k++) 
               { 
                  buffer[k]= triple;
                  
                 
               } 
               // write RGB triple to outfile 
              // fwrite(&triple, sizeof(RGBTRIPLE), bi.biWidth, outptr); 
              fwrite(buffer, sizeof(RGBTRIPLE),1, outptr); 
                
             } 
              // skip over padding, if any
               fseek(inptr, 54 + (Oldwidth*sizeof(RGBTRIPLE)*i), SEEK_SET); 
               
               
                // write padding to outfile 
                
                for (int p = 0; p <padding; p++) 
                fputc(0x00, outptr); 
              
      
            }   
           
    
       // close infile
        fclose(inptr);
    
        // close outfile
        fclose(outptr);
    
     return 0;
    Code:
    #include <stdint.h>
    
    /**
     * Common Data Types 
     *
     * The data types in this section are essentially aliases for C/C++ 
     * primitive data types.
     *
     * Adapted from http://msdn.microsoft.com/en-us/library/cc230309(PROT.10).aspx.
     * See http://en.wikipedia.org/wiki/Stdint.h for more on stdint.h.
     */
    typedef uint8_t  BYTE;
    typedef uint32_t DWORD;
    typedef int32_t  LONG;
    typedef uint16_t WORD;
    
    /**
     * BITMAPFILEHEADER
     *
     * The BITMAPFILEHEADER structure contains information about the type, size,
     * and layout of a file that contains a DIB [device-independent bitmap].
     *
     * Adapted from http://msdn.microsoft.com/en-us/library/dd183374(VS.85).aspx.
     */
    typedef struct 
    { 
        WORD   bfType; 
        DWORD  bfSize; 
        WORD   bfReserved1; 
        WORD   bfReserved2; 
        DWORD  bfOffBits; 
    } __attribute__((__packed__)) 
    BITMAPFILEHEADER; 
    
    /**
     * BITMAPINFOHEADER
     *
     * The BITMAPINFOHEADER structure contains information about the 
     * dimensions and color format of a DIB [device-independent bitmap].
     *
     * Adapted from http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx.
     */
    typedef struct
    {
        DWORD  biSize; 
        LONG   biWidth; 
        LONG   biHeight; 
        WORD   biPlanes; 
        WORD   biBitCount; 
        DWORD  biCompression; 
        DWORD  biSizeImage; 
        LONG   biXPelsPerMeter; 
        LONG   biYPelsPerMeter; 
        DWORD  biClrUsed; 
        DWORD  biClrImportant; 
    } __attribute__((__packed__))
    BITMAPINFOHEADER; 
    
    /**
     * RGBTRIPLE
     *
     * This structure describes a color consisting of relative intensities of
     * red, green, and blue.
     *
     * Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx.
     */
    typedef struct
    {
        BYTE  rgbtBlue;
        BYTE  rgbtGreen;
        BYTE  rgbtRed;
    } __attribute__((__packed__))
    RGBTRIPLE;
    Sorry again.
  16. #9
  17. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    Code:
    $ ./a.out 2 foo5x5-24.bmp bar.bmp
    $ odx foo5x5-24.bmp 
    000000 42 4d 86 00 00 00 00 00 00 00 36 00 00 00 28 00  >BM........6...(.<
    000010 00 00 05 00 00 00 05 00 00 00 01 00 18 00 00 00  >................<
    000020 00 00 50 00 00 00 13 0b 00 00 13 0b 00 00 00 00  >..P.............<
    000030 00 00 00 00 00 00 33 33 33 36 36 36 39 39 39 3c  >......333666999<<
    000040 3c 3c 3f 3f 3f 00 63 63 63 66 66 66 69 69 69 6c  ><<???.cccfffiiil<
    000050 6c 6c 6f 6f 6f 00 93 93 93 96 96 96 99 99 99 9c  >llooo...........<
    000060 9c 9c 9f 9f 9f 00 c3 c3 c3 c6 c6 c6 c9 c9 c9 cc  >................<
    000070 cc cc cf cf cf 00 f3 f3 f3 f6 f6 f6 f9 f9 f9 fc  >................<
    000080 fc fc ff ff ff 00                                >......<
    000086
    $ odx bar.bmp 
    000000 42 4d 86 00 00 00 00 00 00 00 36 00 00 00 28 00  >BM........6...(.<
    000010 00 00 0a 00 00 00 0a 00 00 00 01 00 18 00 00 00  >................<
    000020 00 00 2c 01 00 00 13 0b 00 00 13 0b 00 00 00 00  >..,.............<
    000030 00 00 00 00 00 00 33 33 33 36 36 36 39 39 39 3c  >......333666999<<
    000040 3c 3c 3f 3f 3f 00 00 33 33 33 36 36 36 39 39 39  ><<???..333666999<
    000050 3c 3c 3c 3f 3f 3f 00 00 00 63 63 63 66 66 66 69  ><<<???...cccfffi<
    000060 69 69 6c 6c 6c 6f 6f 00 00 6f 00 93 93 93 96 96  >iillloo..o......<
    000070 96 99 99 99 9c 9c 9c 9f 00 00 9f 9f 00 c3 c3 c3  >................<
    000080 c6 c6 c6 c9 c9 c9 cc cc cc 00 00                 >...........<
    00008b
    The only thing you managed to do was insert an extra padding byte at the end of each row. But at least 2 bytes of padding is correct for an image which should be 10x10 when complete.

    > buffer[k]= triple;
    You need to append pixels to the buffer, not overwrite the ones you stored.

    > fwrite(buffer, sizeof(RGBTRIPLE),1, outptr);
    You need to write the whole buffer, not just one pixel.
    You also need to do this 'factor' times.
    Don't forget the padding at the end of each row.

    My test bitmap is attached.
    Attached Images
    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
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    15
    Rep Power
    0
    Originally Posted by salem
    Code:
    $ ./a.out 2 foo5x5-24.bmp bar.bmp
    $ odx foo5x5-24.bmp 
    000000 42 4d 86 00 00 00 00 00 00 00 36 00 00 00 28 00  >BM........6...(.<
    000010 00 00 05 00 00 00 05 00 00 00 01 00 18 00 00 00  >................<
    000020 00 00 50 00 00 00 13 0b 00 00 13 0b 00 00 00 00  >..P.............<
    000030 00 00 00 00 00 00 33 33 33 36 36 36 39 39 39 3c  >......333666999<<
    000040 3c 3c 3f 3f 3f 00 63 63 63 66 66 66 69 69 69 6c  ><<???.cccfffiiil<
    000050 6c 6c 6f 6f 6f 00 93 93 93 96 96 96 99 99 99 9c  >llooo...........<
    000060 9c 9c 9f 9f 9f 00 c3 c3 c3 c6 c6 c6 c9 c9 c9 cc  >................<
    000070 cc cc cf cf cf 00 f3 f3 f3 f6 f6 f6 f9 f9 f9 fc  >................<
    000080 fc fc ff ff ff 00                                >......<
    000086
    $ odx bar.bmp 
    000000 42 4d 86 00 00 00 00 00 00 00 36 00 00 00 28 00  >BM........6...(.<
    000010 00 00 0a 00 00 00 0a 00 00 00 01 00 18 00 00 00  >................<
    000020 00 00 2c 01 00 00 13 0b 00 00 13 0b 00 00 00 00  >..,.............<
    000030 00 00 00 00 00 00 33 33 33 36 36 36 39 39 39 3c  >......333666999<<
    000040 3c 3c 3f 3f 3f 00 00 33 33 33 36 36 36 39 39 39  ><<???..333666999<
    000050 3c 3c 3c 3f 3f 3f 00 00 00 63 63 63 66 66 66 69  ><<<???...cccfffi<
    000060 69 69 6c 6c 6c 6f 6f 00 00 6f 00 93 93 93 96 96  >iillloo..o......<
    000070 96 99 99 99 9c 9c 9c 9f 00 00 9f 9f 00 c3 c3 c3  >................<
    000080 c6 c6 c6 c9 c9 c9 cc cc cc 00 00                 >...........<
    00008b
    The only thing you managed to do was insert an extra padding byte at the end of each row. But at least 2 bytes of padding is correct for an image which should be 10x10 when complete.

    > buffer[k]= triple;
    You need to append pixels to the buffer, not overwrite the ones you stored.

    > fwrite(buffer, sizeof(RGBTRIPLE),1, outptr);
    You need to write the whole buffer, not just one pixel.
    You also need to do this 'factor' times.
    Don't forget the padding at the end of each row.

    My test bitmap is attached.



    How would I append the pixels to the buffer?
    buffer+=Triple;?
  20. #11
  21. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    > How would I append the pixels to the buffer?
    Here's a side exercise for you - write your own strcat() function.
    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
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    15
    Rep Power
    0
    Originally Posted by salem
    > How would I append the pixels to the buffer?
    Here's a side exercise for you - write your own strcat() function.

    That makes sense...its a string, not a integer or number. Ok, thank you! Sorry about earlier man. Wasnt trying to be a butt. This was, afteral, my first time posting to this forum.
  24. #13
  25. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    Originally Posted by saldar05
    That makes sense...its a string, not a integer or number.
    Not really,

    It's about the concept.
    The way that you would write
    strcat(char *dest, const char *src);
    is in some way similar to what you would write for
    rgbtriplecat( RGBTRIPLE *dest, const RGBTRIPLE *src );

    If you also maintain a count of the number added, this becomes rather trivial.
    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
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    15
    Rep Power
    0
    Originally Posted by salem
    Not really,

    It's about the concept.
    The way that you would write
    strcat(char *dest, const char *src);
    is in some way similar to what you would write for
    rgbtriplecat( RGBTRIPLE *dest, const RGBTRIPLE *src );

    If you also maintain a count of the number added, this becomes rather trivial.
    Ok, but for sure, in your humble opinion, strcat is the way to go to append the pixels to the buffer? And by overwriting them, you are essentially saying that when the the for loop within the width for loop exits, the for loop for width starts to rewrite what has already been written, correct?
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    187
    Rep Power
    82
    One way to add your image data to your BMP file is to set up several loops. The outer loop would be based on the height of the new image. The inner loop would be based on the width of the new image. This inner loop would read a RGBTRIPLE from the input file and then "factor" it into the buffer. The next loop within the height loop would write out buffer that was previously built a number of times based on the value of "factor". Finally, append padding based on the "new" padding value.

    Your logic would look something lik this pseudo code:

    |-Height loop (based on image height)
    | |- Width loop (based on image width)
    | | Read a RGBTRIPLE from input file
    | |- Loop to "factor" each pixel in buffer
    | Skip over "old" padding in input file using fseek SEEK_CUR
    | Loop to write out buffer to row "factor" of times
    |- Append "new" padding to output file using fputc
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo