Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. parsing bitmap files (2)

parsing bitmap files (2)

Scheduled Pinned Locked Moved C / C++ / MFC
questiongraphicsjson
10 Posts 3 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Calin Negru
    wrote on last edited by
    #1

    I think I almost got it right. I have a question about the two file reads

    if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
    != sizeof( BITMAPFILEHEADER ) ||

    		// Is the type 'MB'?
    		BFH.bfType != 'MB' ||
    
    		// Did we read in the remaining data?
    		cf.Read( pDib, dwDibSize ) != dwDibSize )
    

    first it will read the first 14 bytes which is the header and store it in BFH, at the second read it will read a chunk of data but from the looks of it that chunk will include the (first) header again along with whatever else is included

    L L C 3 Replies Last reply
    0
    • C Calin Negru

      I think I almost got it right. I have a question about the two file reads

      if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
      != sizeof( BITMAPFILEHEADER ) ||

      		// Is the type 'MB'?
      		BFH.bfType != 'MB' ||
      
      		// Did we read in the remaining data?
      		cf.Read( pDib, dwDibSize ) != dwDibSize )
      

      first it will read the first 14 bytes which is the header and store it in BFH, at the second read it will read a chunk of data but from the looks of it that chunk will include the (first) header again along with whatever else is included

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      No, the second read will start from the byte following the position where the previous read stopped. That is normal file IO operations. It will only re-read the header if you rewind the file after the first operation.

      C 1 Reply Last reply
      0
      • C Calin Negru

        I think I almost got it right. I have a question about the two file reads

        if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
        != sizeof( BITMAPFILEHEADER ) ||

        		// Is the type 'MB'?
        		BFH.bfType != 'MB' ||
        
        		// Did we read in the remaining data?
        		cf.Read( pDib, dwDibSize ) != dwDibSize )
        

        first it will read the first 14 bytes which is the header and store it in BFH, at the second read it will read a chunk of data but from the looks of it that chunk will include the (first) header again along with whatever else is included

        L Offline
        L Offline
        leon de boer
        wrote on last edited by
        #3

        You are confused there are two headers one after another you need to read them both before deciding whether to do step 3 and I have put a few hints what you need to do 1.) Read BITMAPFILEHEADER check for "BM", hold offset to bitmap data 2.) Read BITMAPINFOHEADER calc DWORD line stride width from bitmap width and bitdepth, see if you have a palette if so do step 3 else step 4 3.) Read the index palette if the BMP has one 4.) Jump to file offset from step 1 that is your bitmap data. Now you need to remember each line is DWORD (4 byte aligned) that means if you multiply the bytes per each line pixel * bitmap width it has to equal 4. So lets give you an example if you bitmap is 24Bit so each pixel is 3 bytes. So if your image was one pixel in width the first line is the first 3 bytes then there is a pad of one dummy byte and the second line starts at the 4th byte. So there can be 0 to 3 extra bytes per line because each new line must start on a DWORD boundary. So the amount of data you need to read for a line can be a couple bytes more than the just multiplying the bitmpap width * bytes per pixel. The dummy bytes are usually zero but some smart people worked out long ago if you make all your images odd so you have the extra bytes you can put a hidden watermark, or play spy and put secret messsages in the dummy bytes :-)

        In vino veritas

        1 Reply Last reply
        0
        • C Calin Negru

          I think I almost got it right. I have a question about the two file reads

          if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
          != sizeof( BITMAPFILEHEADER ) ||

          		// Is the type 'MB'?
          		BFH.bfType != 'MB' ||
          
          		// Did we read in the remaining data?
          		cf.Read( pDib, dwDibSize ) != dwDibSize )
          

          first it will read the first 14 bytes which is the header and store it in BFH, at the second read it will read a chunk of data but from the looks of it that chunk will include the (first) header again along with whatever else is included

          C Offline
          C Offline
          Calin Negru
          wrote on last edited by
          #4

          Richard I have it working. Now on to saving. phil, leon thanks guys.

          1 Reply Last reply
          0
          • L Lost User

            No, the second read will start from the byte following the position where the previous read stopped. That is normal file IO operations. It will only re-read the header if you rewind the file after the first operation.

            C Offline
            C Offline
            Calin Negru
            wrote on last edited by
            #5

            This is my write attempt.

            BITMAPFILEHEADER BFH;
            BITMAPINFOHEADER BIH;
            RGBQUAD Palette;
            RGBQUAD * Pixels = new RGBQUAD[10];

            cf.Read( &BFH, sizeof( BITMAPFILEHEADER ));
            cf.Read( &BIH, sizeof( BITMAPINFOHEADER ));
            
            for(int i =0; i<10; i++)
            {
            	cf.Read(&Pixels\[i\],sizeof(RGBQUAD));
            
            }
            
            StringCchPrintfA(message,1024,"b0 is %d", Pixels\[0\].rgbBlue);
            MessageBox(NULL, message, "Textures.exe", MB\_OK);
            StringCchPrintfA(message,1024,"g0 is %d", Pixels\[0\].rgbGreen);
            MessageBox(NULL, message, "Textures.exe", MB\_OK);
            StringCchPrintfA(message,1024,"r0 is %d", Pixels\[0\].rgbRed);
            MessageBox(NULL, message, "Textures.exe", MB\_OK);
            
            StringCchPrintfA(message,1024,"r1 is %d", Pixels\[1\].rgbRed);
            MessageBox(NULL, message, "Textures.exe", MB\_OK);
            StringCchPrintfA(message,1024,"g1 is %d", Pixels\[1\].rgbGreen);
            MessageBox(NULL, message, "Textures.exe", MB\_OK);
            StringCchPrintfA(message,1024,"b1 is %d", Pixels\[1\].rgbBlue);
            MessageBox(NULL, message, "Textures.exe", MB\_OK);
            
            
            CFile fileWrite;
            
            Pixels\[0\].rgbBlue = 100;
            Pixels\[0\].rgbGreen = 100;
            Pixels\[0\].rgbRed = 50;
            // Attempt to create the file.
            if( !fileWrite.Open( pszFilename,
            	CFile::modeCreate | CFile::modeWrite ) )
            	return( FALSE );
            
            fileWrite.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
            fileWrite.Write( &BIH, sizeof( BITMAPINFOHEADER ) );
            for(int i =0;i<10; i++)
            {
            	fileWrite.Write( &Pixels\[i\], sizeof( RGBQUAD ) );
            }
            

            when I start my program again I expect the values of the first pixel to be updated but they aren`t

            L 2 Replies Last reply
            0
            • C Calin Negru

              This is my write attempt.

              BITMAPFILEHEADER BFH;
              BITMAPINFOHEADER BIH;
              RGBQUAD Palette;
              RGBQUAD * Pixels = new RGBQUAD[10];

              cf.Read( &BFH, sizeof( BITMAPFILEHEADER ));
              cf.Read( &BIH, sizeof( BITMAPINFOHEADER ));
              
              for(int i =0; i<10; i++)
              {
              	cf.Read(&Pixels\[i\],sizeof(RGBQUAD));
              
              }
              
              StringCchPrintfA(message,1024,"b0 is %d", Pixels\[0\].rgbBlue);
              MessageBox(NULL, message, "Textures.exe", MB\_OK);
              StringCchPrintfA(message,1024,"g0 is %d", Pixels\[0\].rgbGreen);
              MessageBox(NULL, message, "Textures.exe", MB\_OK);
              StringCchPrintfA(message,1024,"r0 is %d", Pixels\[0\].rgbRed);
              MessageBox(NULL, message, "Textures.exe", MB\_OK);
              
              StringCchPrintfA(message,1024,"r1 is %d", Pixels\[1\].rgbRed);
              MessageBox(NULL, message, "Textures.exe", MB\_OK);
              StringCchPrintfA(message,1024,"g1 is %d", Pixels\[1\].rgbGreen);
              MessageBox(NULL, message, "Textures.exe", MB\_OK);
              StringCchPrintfA(message,1024,"b1 is %d", Pixels\[1\].rgbBlue);
              MessageBox(NULL, message, "Textures.exe", MB\_OK);
              
              
              CFile fileWrite;
              
              Pixels\[0\].rgbBlue = 100;
              Pixels\[0\].rgbGreen = 100;
              Pixels\[0\].rgbRed = 50;
              // Attempt to create the file.
              if( !fileWrite.Open( pszFilename,
              	CFile::modeCreate | CFile::modeWrite ) )
              	return( FALSE );
              
              fileWrite.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
              fileWrite.Write( &BIH, sizeof( BITMAPINFOHEADER ) );
              for(int i =0;i<10; i++)
              {
              	fileWrite.Write( &Pixels\[i\], sizeof( RGBQUAD ) );
              }
              

              when I start my program again I expect the values of the first pixel to be updated but they aren`t

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              The code looks valid enough, are you sure the file is getting created correctly?

              C 1 Reply Last reply
              0
              • L Lost User

                The code looks valid enough, are you sure the file is getting created correctly?

                C Offline
                C Offline
                Calin Negru
                wrote on last edited by
                #7

                you`re right, if I try to create the file under a new name it works.

                1 Reply Last reply
                0
                • C Calin Negru

                  This is my write attempt.

                  BITMAPFILEHEADER BFH;
                  BITMAPINFOHEADER BIH;
                  RGBQUAD Palette;
                  RGBQUAD * Pixels = new RGBQUAD[10];

                  cf.Read( &BFH, sizeof( BITMAPFILEHEADER ));
                  cf.Read( &BIH, sizeof( BITMAPINFOHEADER ));
                  
                  for(int i =0; i<10; i++)
                  {
                  	cf.Read(&Pixels\[i\],sizeof(RGBQUAD));
                  
                  }
                  
                  StringCchPrintfA(message,1024,"b0 is %d", Pixels\[0\].rgbBlue);
                  MessageBox(NULL, message, "Textures.exe", MB\_OK);
                  StringCchPrintfA(message,1024,"g0 is %d", Pixels\[0\].rgbGreen);
                  MessageBox(NULL, message, "Textures.exe", MB\_OK);
                  StringCchPrintfA(message,1024,"r0 is %d", Pixels\[0\].rgbRed);
                  MessageBox(NULL, message, "Textures.exe", MB\_OK);
                  
                  StringCchPrintfA(message,1024,"r1 is %d", Pixels\[1\].rgbRed);
                  MessageBox(NULL, message, "Textures.exe", MB\_OK);
                  StringCchPrintfA(message,1024,"g1 is %d", Pixels\[1\].rgbGreen);
                  MessageBox(NULL, message, "Textures.exe", MB\_OK);
                  StringCchPrintfA(message,1024,"b1 is %d", Pixels\[1\].rgbBlue);
                  MessageBox(NULL, message, "Textures.exe", MB\_OK);
                  
                  
                  CFile fileWrite;
                  
                  Pixels\[0\].rgbBlue = 100;
                  Pixels\[0\].rgbGreen = 100;
                  Pixels\[0\].rgbRed = 50;
                  // Attempt to create the file.
                  if( !fileWrite.Open( pszFilename,
                  	CFile::modeCreate | CFile::modeWrite ) )
                  	return( FALSE );
                  
                  fileWrite.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
                  fileWrite.Write( &BIH, sizeof( BITMAPINFOHEADER ) );
                  for(int i =0;i<10; i++)
                  {
                  	fileWrite.Write( &Pixels\[i\], sizeof( RGBQUAD ) );
                  }
                  

                  when I start my program again I expect the values of the first pixel to be updated but they aren`t

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  I have just tried a similar exercise and the changes are correctly made to the output file.

                  C 1 Reply Last reply
                  0
                  • L Lost User

                    I have just tried a similar exercise and the changes are correctly made to the output file.

                    C Offline
                    C Offline
                    Calin Negru
                    wrote on last edited by
                    #9

                    I will run into other C related issues, you`re not getting rid of me.

                    L 1 Reply Last reply
                    0
                    • C Calin Negru

                      I will run into other C related issues, you`re not getting rid of me.

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #10

                      Don't worry, I have the freedom to ignore any messages that don't interest me.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups