0
\$\begingroup\$
class Surface 
{
protected:
    Surface();
    virtual ~Surface();

    class IMAGE // create a discreet type to be used to instantiate queue template
    {
    public:
        // single bitmap image width and height
        unsigned short width, height;
        unsigned int size;      // single bitmap image size
        DWORD* buffer;          // buffer to hold a width X height _size_ image
…

class Bitmap : protected Surface
{
public:
    class BMP_32
    {
    public:
        BMPHeader       HeaderSection;
        BMPInfo         InfoSection;
        BMPColorTable       ColorTableSection;

…

void Bitmap::BMP_32::Read(Bitmap::BMP_32& a_bmp32, IMAGE& an_image, SURFACE& a_surface, const char* file_name)
{
…
fread(&a_bmp32.HeaderSection.FileType, sizeof(a_bmp32.HeaderSection.FileType), 1, fp);
…
fread(&a_bmp32.InfoSection.HeaderSize, sizeof(a_bmp32.InfoSection.HeaderSize), 1, fp);
…
fread(&a_bmp32.ColorTableSection.RedIntensity, sizeof(a_bmp32.ColorTableSection.RedIntensity), 1, fp);
…

an_image.buffer = new DWORD[IMAGEBUFFERSIZE];

…
// The following three examples render the same output visually:

// DWORD dwords_read = fread(an_image.buffer, sizeof(DWORD), an_image.size, fp);  // dwords_read = 2,073,600

DWORD dwords_read = fread(an_image.buffer, (SCREEN_WIDTH * SCREEN_HEIGHT), 4, fp);   // dwords_read = 4
// DWORD dwords_read = fread(an_image.buffer, ((SCREEN_WIDTH * SCREEN_HEIGHT) * 2), 2, fp);  // dwords_read = 2

Background Detail: I am building up a class framework to read in 32BPP BMP files, that I am creating on a backsurface, which I then bltfast to the frontsurface and flip to GDI. The 32BPP background BMP that I am reading in is 8294400 in size, but the most I am able to read using “fread()” is 2073600, which is exactly 25% of the original artwork. I am using Visual Studio 2019 Community Edition and fread(&MyBuffer, arg2, arg3, stream) extensively. My application is an MFC application.

I have a need to read in the entire BMP Pixel Data Section into memory, because I am saving this into a queue Abstract Data type. Once I have the BMP in memory the I/O is done to disk and I just make calls to update the backsurface, bltfast and flip to update my scene. I am creating a class library for the BMP code.

Question: Is fread() hitting an upperbound on size limit? If so can someone suggest how I might be able to overcome this problem. If so I am hoping to make a minor substitution for this fread() API call for another C++ call. I cannot do anything too fancy with multiple buffers or doing a lot of I/O, as I have tried that approach already without success.

\$\endgroup\$
  • \$\begingroup\$ What is the value of an_image.size and IMAGEBUFFERSIZE? \$\endgroup\$ – Fuzzy Logic May 30 '20 at 7:45
  • \$\begingroup\$ // some useful constants #define SCREEN_WIDTH 1920 #define SCREEN_HEIGHT 1080 #define BPP 32 // Bits Per Pixel #define IMAGEBUFFERSIZE ( SCREEN_WIDTH * SCREEN_HEIGHT ) * BPP // holds max IMAGE size; an_image.size == 8294400 // size of the raw pixel data from this specific 32 BPP BMP // here is how I obtained it -- fread(&a_bmp32.InfoSection.ImageSize, sizeof(a_bmp32.InfoSection.ImageSize), 1, fp); an_image.size = a_bmp32.InfoSection.ImageSize; I have set the value of IMAGEBUFFERSIZE much higher than I believe it needs to be Thanks for taking a peek \$\endgroup\$ – DHarding May 30 '20 at 8:31
0
\$\begingroup\$

I found the following to work well. from working code that I wrote some time back, which I now converted to utilize 32BPP BMP files and x64.

For the 32BPP header file I used the following link:
https://solarianprogrammer.com/2018/11/19/cpp-reading-writing-bmp-images/

In case your wondering I am using DirectX 7.0

class Bitmap
{
public:

    class BMP32
    {
    public:

        BMPHeader       HeaderSection;
        BMPInfo         InfoSection;
        BMPColorTable   ColorTableSection;
        BYTE* buffer;           // buffer to hold a BMP raw pixel data


        BMP32() {
            memset(&HeaderSection, 0, sizeof(HeaderSection));
            memset(&InfoSection, 0, sizeof(InfoSection));
            memset(&ColorTableSection, 0, sizeof(ColorTableSection));
            buffer = NULL;
        }

        virtual ~BMP32() { if (buffer != NULL && InfoSection.ImageSize != 0) delete buffer; }
        void Read(BMP32& a_bmp32, const char* file_name); // read that will read 32BPP
    };
...

class Surface...

class IMAGE     // create a discreet type to be used to instantiate a queue of surfaces
    {
    public:
        int width, height;      // single bitmap image width and height
        unsigned int size;      // single bitmap image size
        DWORD* buffer;          // buffer to hold a width X height _size_ image
        IMAGE() { buffer = NULL; width = 0; height = 0; size = 0; }
        virtual ~IMAGE() { if (buffer != NULL && size != 0) delete buffer; }    // don't leak memory!
    };

...

void ReadGFX(const char* file_name, PALETTEENTRY scene_palette[MAX_COLORS_PALETTE]); // read in all 32 bit bmp images from the gfx (aka the sprite library) file name passed to this method
    

// What we want to do here is to read a file containing one or more
// bmp files. each bmp read will be written into a ddraw surface.
// The bmp file consists of a header ( width  height and size ) and data ( size bytes )
void Sprite::ReadGFX(const char* file_name, PALETTEENTRY scene_palette[MAX_COLORS_PALETTE])
{

    TRACE("Sprite::ReadGFX invoked. GFX name is : %s\n", file_name );

    
    FILE* fp;                           // file pointer to opened file_name
    if ( ( fp = fopen(file_name,"rb") ) != NULL )
    {
    
        short image_count = 0, i = 0;               // number of sprite images contained in file_name
        int w = 0, h = 0;
        unsigned int size = 0;
        DWORD buffer_size = 0;

        fread(&image_count, sizeof(image_count), 1, fp);    // get number of bmp files to read
        

        for ( i = 1; i <= image_count; i++ )
        {
            IMAGE an_image;     // create enough local storage to read in one image
            SURFACE a_surface;

        w = fread(&an_image.width,  sizeof(an_image.width), 1, fp);         // bmp width
        h = fread(&an_image.height, sizeof(an_image.height), 1, fp);        // bmp height
        size =  fread(&an_image.size,   sizeof(an_image.size), 1, fp);      // bmp size

        TRACE("Sprite::Read an_image.width = %d, an_image.height = %d, an_image.size = %d\n", w, h, size);
            an_image.buffer = new DWORD[an_image.size]; // create enough storage to hold bmp data
            buffer_size = fread(an_image.buffer, sizeof(BYTE), an_image.size, fp);  // read the raw pixel data from the bmp here 
            try
            {
                Create(an_image.width, an_image.height, a_surface); // create ddraw surface
                Write(an_image, a_surface, Scene::scene_palette);               // copy image into surface
                surface_queue.Enqueue(a_surface);   // save data structure by queueing record object
                TRACE("Width = %i, Height = %i, Size = %i, Buffer Size = %u\n", w, h, size, buffer_size);
            }
            catch (int exception)
            {
                TRACE("%Xh exception caught by Sprite::ReadGFX\n ", exception);
                if (exception == VIDEO_EXCEPTION)
                {
                    TRACE("VIDEO_EXCEPTION caught by Sprite::ReadGFX, due to Surface::Create failure\n");
                    TRACE("Terminating: throwing SPRITE_EXCEPTION\n");
        
                    // clean up to avoid memory leaks!!
                    if (!surface_queue.IsEmpty())
                    {
                        surface_queue.MakeEmpty();
                    }
                    if (  an_image.buffer != NULL && an_image.size != 0   )
                    {
                        delete an_image.buffer;
                        an_image.buffer = 0;
                        an_image.buffer = NULL;
                    }
                    fclose(fp); // close the input file
                    throw (SPRITE_EXCEPTION); // terminate the program
                }
            }
        }
        fclose(fp);
    }
    else
    {
        TRACE ("Sprite::ReadGFX %s not found\n", file_name);
        char message[60];
        strcpy ( message, "Graphics file not found: ");
        strcat ( message, file_name);
        strcat ( message, "\nApplication will now terminate.");
        FatalMessageBox( message );
        throw (SPRITE_EXCEPTION);
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.