Thread: Loading files into memory

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    9

    Loading files into memory

    I stopped coding for about a year and a half ago. So I'm trying to find things to brush up on. At the moment it's file i/o.

    I'm not exactly sure what is wrong with my code, but when I go to check what I loaded into memory by outputting it to the consol, I am getting weird numbers.

    Code:
    #include <fstream>
    
    using namespace std;
    
    class BitmapPic
    {
        private:
                
            //bitmap fileheader(info about file)
            typedef struct Bitmap_FileHeader
            {
                unsigned short bfType;//WORD
                unsigned long bfSize;//DWORD
                unsigned short bfReserved1;
                unsigned short bfReserved2;
                unsigned long bfOffBits;
            };//total:14 bytes
            
            //bitmap infoheader:(info on contents of file)
            typedef struct Bitmap_InfoHeader
            {
                unsigned long biSize;//DWORD
                unsigned long biWidth;
                unsigned long biHeigth;
                unsigned short biPlanes;//WORD
                unsigned short biBitCount;
                unsigned long biCompression;
                unsigned long biSizeImage;
                unsigned long biXPelsPerMeter;
                unsigned long biYPelsPerMeter;
                unsigned long biClrUsed;
                unsigned long biClrImportant;
            };//total: 40 bytes
            
            //structure for containing pixel values.
            typedef struct RGBQuad
            {
                unsigned char rgbBlue;
                unsigned char rgbGreen;
                unsigned char rgbRed;
                unsigned char rgbReserved;
            };
    
        public:
    
            Bitmap_FileHeader bmfh;
            Bitmap_InfoHeader bmih;
            RGBQuad aColors[];
            
            void LBmp(char file[]);
    };
    
    void BitmapPic::LBmp(char file[])
    {
        ifstream infile(file,ios::binary|ios::in);
        infile.read(reinterpret_cast<char*>(&bmfh),sizeof(Bitmap_FileHeader));
        infile.read(reinterpret_cast<char*>(&bmih),sizeof(Bitmap_InfoHeader));
    }
    The only value that seems to come out true is the first one which is always going to be "19778"

    bfSize comes out as 0
    biWidth comes out as 18808832
    biHeigth comes out as 65536 (2^16)

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Easy check: what does your compiler say sizeof(Bitmap_FileHeader) and sizeof(Bitmap_InfoHeader) are? I wouldn't be surprised if the first, at least, is not actually 14.

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    9
    sizeof(bmp.bmfh) = 16
    sizeof(bmp.bmih) = 40

    how can I fix that? I'm pretty sure I am using the right sized data in my structures.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You can either make a function that reads in the appropriate bits of the struct separately, or you can do something compiler-specific to "pack" the structure together so that there's no padding bytes in it.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    Even if "pack" generates a struct of the right size, it still won't fix endian problems.

    Yes it sucks to read the file byte by byte, but it's the only sure way of producing a consistent answer independent of your compiler or platform.
    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.

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Since this is a Windows-specific file format, why not just use the structures defined in the related header files (since they're guaranteed to be aligned properly)?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Holy sweet Jesus, Sebastiani! There is a name from back when I was really active on the forums. I hope the years have been kind to you old friend.

  8. #8
    Registered User
    Join Date
    Sep 2008
    Posts
    9
    it worked, reading it in piece by piece. I wanted to avoid that but meh... actually I did try sizeof(Bitmap_FileHeader) before I just forgot totally about it. I knew it had to do with bytes getting stored in the wrong spot somewhere. For some dumb reason I didn't think "oh my struct is 16bytes and it's only 14bytes"

    Anyways, thanks everyone

    side note: I'm just practice I/O, I'd like to try loading something like JPEG's into memory once I get a bit better. (eventually for texture mapping in OpenGL). I'd rather texture map other files than uncompressed bmp files. I know I could always use an image library like devIL but I'm just weird =P.

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> it worked, reading it in piece by piece. I wanted to avoid that but meh...

    Most compilers accept either of these two conventions:


    Code:
    // borland style?
    #pragma pack( push, sizeof( int ) ) 
    // stuff
    #pragma pack( pop )
     
     
    // gcc style
    class stuff
          __attribute__( ( packed( sizeof( int ) ) ) ) 
    {      };
    At any rate, there are many situations where it is preferable to reading in data "byte by byte".

    @master5001 : Good to see you old chap!
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  10. #10
    Registered User
    Join Date
    Sep 2008
    Posts
    9
    why would they add padding bytes to structs anyways?

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    On some architectures, trying to read unaligned memory can even trigger a hardware exception.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Even on the case of x86 and x86-64, it can cause processor penalties (speed hits!) to read unaligned memory...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Oh, and you typically can't perform atomic operations (test_and_set, compare_and_swap, etc.) on unaligned memory locations.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Another example of instructions that require alignment: SSE. SSE loads (except for special "unaligned load" instructions) must be aligned to 16-byte boundaries.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by CornedBee View Post
    Another example of instructions that require alignment: SSE. SSE loads (except for special "unaligned load" instructions) must be aligned to 16-byte boundaries.
    Yes, very true. And with the above mentioned exception in mind, there is only two options: Make sure the data IS aligned, or read the data into a register using the special "unaligned" instructions (and they ARE slower in most machines, even if the data IS aligned). For such operations, you do not only need alignment to the boundary of the basic data, but a bigger alignment (because the basic data is multiple elements, but the WHOLE block of for example 4 floats need to be 16-byte aligned).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. reading files into memory
    By bobthebullet990 in forum C Programming
    Replies: 3
    Last Post: 11-30-2005, 03:39 PM
  2. CreateProcess and Memory mapped files
    By kevcri in forum C++ Programming
    Replies: 14
    Last Post: 12-10-2003, 03:14 AM
  3. Is it necessary to write a specific memory manager ?
    By Morglum in forum Game Programming
    Replies: 18
    Last Post: 07-01-2002, 01:41 PM
  4. Loading a file into memory ???
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 01-09-2002, 07:35 AM