| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703 |
- /*
- ** Command & Conquer Red Alert(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- //*******************************************************************
- //
- // file.c
- //
- // Source file for Device-Independent Bitmap (DIB) API. Provides
- // the following functions:
- //
- // SaveDIB() - Saves the specified dib in a file
- // LoadDIB() - Loads a DIB from a file
- // DestroyDIB() - Deletes DIB when finished using it
- //
- // Development Team: Mark Bader
- // Patrick Schreiber
- // Garrett McAuliffe
- // Eric Flo
- // Tony Claflin
- //
- // Written by Microsoft Product Support Services, Developer Support.
- // COPYRIGHT:
- //
- // (C) Copyright Microsoft Corp. 1993. All rights reserved.
- //
- // You have a royalty-free right to use, modify, reproduce and
- // distribute the Sample Files (and/or any modified version) in
- // any way you find useful, provided that you agree that
- // Microsoft has no warranty obligations or liability for any
- // Sample Application Files which are modified.
- //
- //*******************************************************************
- #include <windows.h>
- #include <string.h>
- #include <stdio.h>
- #include <math.h>
- #include <io.h>
- #include <direct.h>
- #include <stdlib.h>
- #include "dibutil.h"
- #include "dibapi.h"
- //#include "WolDebug.h"
- /*
- * Dib Header Marker - used in writing DIBs to files
- */
- #define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
- /*********************************************************************
- *
- * Local Function Prototypes
- *
- *********************************************************************/
- HANDLE ReadDIBFile(int);
- BOOL MyRead(int, LPSTR, DWORD);
- BOOL SaveDIBFile(void);
- BOOL WriteDIB(LPSTR, HANDLE);
- DWORD PASCAL MyWrite(int, VOID FAR *, DWORD);
- /*************************************************************************
- *
- * LoadDIB()
- *
- * Loads the specified DIB from a file, allocates memory for it,
- * and reads the disk file into the memory.
- *
- *
- * Parameters:
- *
- * LPSTR lpFileName - specifies the file to load a DIB from
- *
- * Returns: A handle to a DIB, or NULL if unsuccessful.
- *
- * NOTE: The DIB API were not written to handle OS/2 DIBs; This
- * function will reject any file that is not a Windows DIB.
- *
- * History: Date Author Reason
- * 9/15/91 Mark Bader Based on DIBVIEW
- *
- *************************************************************************/
- HDIB FAR LoadDIB(LPSTR lpFileName)
- {
- HDIB hDIB;
- int hFile;
- OFSTRUCT ofs;
- /*
- * Set the cursor to a hourglass, in case the loading operation
- * takes more than a sec, the user will know what's going on.
- */
- SetCursor(LoadCursor(NULL, IDC_WAIT));
- if ((hFile = OpenFile(lpFileName, &ofs, OF_READ)) != -1)
- {
- hDIB = ReadDIBFile(hFile);
- _lclose(hFile);
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- return hDIB;
- }
- else
- {
- // DIBError(ERR_FILENOTFOUND);
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- return NULL;
- }
- }
- /*************************************************************************
- *
- * SaveDIB()
- *
- * Saves the specified DIB into the specified file name on disk. No
- * error checking is done, so if the file already exists, it will be
- * written over.
- *
- * Parameters:
- *
- * HDIB hDib - Handle to the dib to save
- *
- * LPSTR lpFileName - pointer to full pathname to save DIB under
- *
- * Return value: 0 if successful, or one of:
- * ERR_INVALIDHANDLE
- * ERR_OPEN
- * ERR_LOCK
- *
- * History:
- *
- * NOTE: The DIB API were not written to handle OS/2 DIBs, so this
- * function will not save a file if it is not a Windows DIB.
- *
- * History: Date Author Reason
- * 9/15/91 Mark Bader Taken from DIBVIEW (which was taken
- * from SHOWDIB)
- * 1/30/92 Mark Bader Fixed problem of writing too many
- * bytes to the file
- * 6/24/92 Mark Bader Added check for OS/2 DIB
- *
- *************************************************************************/
- WORD FAR SaveDIB(HDIB hDib, LPSTR lpFileName)
- {
- BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
- LPBITMAPINFOHEADER lpBI; // Pointer to DIB info structure
- int fh; // file handle for opened file
- OFSTRUCT of; // OpenFile structure
- DWORD dwDIBSize;
- DWORD dwError; // Error return from MyWrite
- if (!hDib)
- return ERR_INVALIDHANDLE;
- fh = OpenFile(lpFileName, &of, OF_CREATE | OF_READWRITE);
- if (fh == -1)
- return ERR_OPEN;
- /*
- * Get a pointer to the DIB memory, the first of which contains
- * a BITMAPINFO structure
- */
- lpBI = (LPBITMAPINFOHEADER)GlobalLock(hDib);
- if (!lpBI)
- return ERR_LOCK;
- // Check to see if we're dealing with an OS/2 DIB. If so, don't
- // save it because our functions aren't written to deal with these
- // DIBs.
- if (lpBI->biSize != sizeof(BITMAPINFOHEADER))
- {
- GlobalUnlock(hDib);
- return ERR_NOT_DIB;
- }
- /*
- * Fill in the fields of the file header
- */
- /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
- bmfHdr.bfType = DIB_HEADER_MARKER; // "BM"
- // Calculating the size of the DIB is a bit tricky (if we want to
- // do it right). The easiest way to do this is to call GlobalSize()
- // on our global handle, but since the size of our global memory may have
- // been padded a few bytes, we may end up writing out a few too
- // many bytes to the file (which may cause problems with some apps,
- // like HC 3.0).
- //
- // So, instead let's calculate the size manually.
- //
- // To do this, find size of header plus size of color table. Since the
- // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains
- // the size of the structure, let's use this.
- dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI); // Partial Calculation
- // Now calculate the size of the image
- if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4)) {
- // It's an RLE bitmap, we can't calculate size, so trust the
- // biSizeImage field
- dwDIBSize += lpBI->biSizeImage;
- }
- else {
- DWORD dwBmBitsSize; // Size of Bitmap Bits only
- // It's not RLE, so size is Width (DWORD aligned) * Height
- dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;
- dwDIBSize += dwBmBitsSize;
-
- // Now, since we have calculated the correct size, why don't we
- // fill in the biSizeImage field (this will fix any .BMP files which
- // have this field incorrect).
- lpBI->biSizeImage = dwBmBitsSize;
- }
- // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
-
- bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
- bmfHdr.bfReserved1 = 0;
- bmfHdr.bfReserved2 = 0;
- /*
- * Now, calculate the offset the actual bitmap bits will be in
- * the file -- It's the Bitmap file header plus the DIB header,
- * plus the size of the color table.
- */
- bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize +
- PaletteSize((LPSTR)lpBI);
- /* Write the file header */
- _lwrite(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
- /*
- * Write the DIB header and the bits -- use local version of
- * MyWrite, so we can write more than 32767 bytes of data
- */
- dwError = MyWrite(fh, (LPSTR)lpBI, dwDIBSize);
- GlobalUnlock(hDib);
- _lclose(fh);
- if (dwError == 0)
- return ERR_OPEN; // oops, something happened in the write
- else
- return 0; // Success code
- }
- /*************************************************************************
- *
- * DestroyDIB ()
- *
- * Purpose: Frees memory associated with a DIB
- *
- * Returns: Nothing
- *
- * History: Date Author Reason
- * 9/15/91 Mark Bader Created
- *
- *************************************************************************/
- WORD FAR DestroyDIB(HDIB hDib)
- {
- GlobalFree(hDib);
- return 0;
- }
- //************************************************************************
- //
- // Auxiliary Functions which the above procedures use
- //
- //************************************************************************
- /*************************************************************************
- *
- * Function: ReadDIBFile (int)
- *
- * Purpose: Reads in the specified DIB file into a global chunk of
- * memory.
- *
- * Returns: A handle to a dib (hDIB) if successful.
- * NULL if an error occurs.
- *
- * Comments: BITMAPFILEHEADER is stripped off of the DIB. Everything
- * from the end of the BITMAPFILEHEADER structure on is
- * returned in the global memory handle.
- *
- *
- * NOTE: The DIB API were not written to handle OS/2 DIBs, so this
- * function will reject any file that is not a Windows DIB.
- *
- * History: Date Author Reason
- * 9/15/91 Mark Bader Based on DIBVIEW
- * 6/25/92 Mark Bader Added check for OS/2 DIB
- * 7/21/92 Mark Bader Added code to deal with bfOffBits
- * field in BITMAPFILEHEADER
- * 9/11/92 Mark Bader Fixed Realloc Code to free original mem
- *
- *************************************************************************/
- HANDLE ReadDIBFile(int hFile)
- {
- BITMAPFILEHEADER bmfHeader;
- DWORD dwBitsSize;
- UINT nNumColors; // Number of colors in table
- HANDLE hDIB;
- HANDLE hDIBtmp; // Used for GlobalRealloc() //MPB
- LPBITMAPINFOHEADER lpbi;
- DWORD offBits;
- /*
- * get length of DIB in bytes for use when reading
- */
- dwBitsSize = filelength(hFile);
- // Allocate memory for header & color table. We'll enlarge this
- // memory as needed.
- hDIB = GlobalAlloc(GMEM_MOVEABLE,
- (DWORD)(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)));
-
- if (!hDIB) return NULL;
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
- if (!lpbi)
- {
- GlobalFree(hDIB);
- return NULL;
- }
- // read the BITMAPFILEHEADER from our file
- if (sizeof (BITMAPFILEHEADER) != _lread (hFile, (LPSTR)&bmfHeader, sizeof (BITMAPFILEHEADER)))
- goto ErrExit;
- if (bmfHeader.bfType != 0x4d42) /* 'BM' */
- goto ErrExit;
- // read the BITMAPINFOHEADER
- if (sizeof(BITMAPINFOHEADER) != _lread (hFile, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
- goto ErrExit;
- // Check to see that it's a Windows DIB -- an OS/2 DIB would cause
- // strange problems with the rest of the DIB API since the fields
- // in the header are different and the color table entries are
- // smaller.
- //
- // If it's not a Windows DIB (e.g. if biSize is wrong), return NULL.
- if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
- goto ErrExit;
- // Now determine the size of the color table and read it. Since the
- // bitmap bits are offset in the file by bfOffBits, we need to do some
- // special processing here to make sure the bits directly follow
- // the color table (because that's the format we are susposed to pass
- // back)
- nNumColors = (UINT)lpbi->biClrUsed;
- if (!nNumColors)
- {
- // no color table for 24-bit, default size otherwise
- if (lpbi->biBitCount != 24)
- nNumColors = 1 << lpbi->biBitCount; /* standard size table */
- }
- // fill in some default values if they are zero
- if (lpbi->biClrUsed == 0)
- lpbi->biClrUsed = nNumColors;
- if (lpbi->biSizeImage == 0)
- {
- lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3)
- * lpbi->biHeight;
- }
- // get a proper-sized buffer for header, color table and bits
- GlobalUnlock(hDIB);
- hDIBtmp = GlobalReAlloc(hDIB, lpbi->biSize +
- nNumColors * sizeof(RGBQUAD) +
- lpbi->biSizeImage, 0);
- if (!hDIBtmp) // can't resize buffer for loading
- goto ErrExitNoUnlock; //MPB
- else
- hDIB = hDIBtmp;
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
- // read the color table
- _lread (hFile, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
- // offset to the bits from start of DIB header
- offBits = lpbi->biSize + nNumColors * sizeof(RGBQUAD);
- // If the bfOffBits field is non-zero, then the bits might *not* be
- // directly following the color table in the file. Use the value in
- // bfOffBits to seek the bits.
- if (bmfHeader.bfOffBits != 0L)
- _llseek(hFile, bmfHeader.bfOffBits, SEEK_SET);
-
- if (MyRead(hFile, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
- goto OKExit;
- ErrExit:
- GlobalUnlock(hDIB);
- ErrExitNoUnlock:
- GlobalFree(hDIB);
- return NULL;
- OKExit:
- GlobalUnlock(hDIB);
- return hDIB;
- }
- /*************************************************************************
- Function: MyRead (int, LPSTR, DWORD)
- Purpose: Routine to read files greater than 64K in size.
- Returns: TRUE if successful.
- FALSE if an error occurs.
-
- History: Date Author Reason
- 9/15/91 Mark Bader Based on DIBVIEW
-
- *************************************************************************/
- BOOL MyRead(int hFile, LPSTR lpBuffer, DWORD dwSize)
- {
- char huge *lpInBuf = (char huge *)lpBuffer;
- int nBytes;
- /*
- * Read in the data in 32767 byte chunks (or a smaller amount if it's
- * the last chunk of data read)
- */
- while (dwSize)
- {
- nBytes = (int)(dwSize > (DWORD)32767 ? 32767 : LOWORD (dwSize));
- if (_lread(hFile, (LPSTR)lpInBuf, nBytes) != (WORD)nBytes)
- return FALSE;
- dwSize -= nBytes;
- lpInBuf += nBytes;
- }
- return TRUE;
- }
- /****************************************************************************
- FUNCTION : MyWrite(int fh, VOID FAR *pv, DWORD ul)
- PURPOSE : Writes data in steps of 32k till all the data is written.
- Normal _lwrite uses a WORD as 3rd parameter, so it is
- limited to 32767 bytes, but this procedure is not.
- RETURNS : 0 - If write did not proceed correctly.
- number of bytes written otherwise.
-
- History: Date Author Reason
- 9/15/91 Mark Bader Based on DIBVIEW
- ****************************************************************************/
- DWORD PASCAL MyWrite(int iFileHandle, VOID FAR *lpBuffer, DWORD dwBytes)
- {
- DWORD dwBytesTmp = dwBytes; // Save # of bytes for return value
- BYTE huge *hpBuffer = (BYTE huge *)lpBuffer; // make a huge pointer to the data
- /*
- * Write out the data in 32767 byte chunks.
- */
- while (dwBytes > 32767)
- {
- if (_lwrite(iFileHandle, (LPSTR)hpBuffer, (WORD)32767) != 32767)
- return 0;
- dwBytes -= 32767;
- hpBuffer += 32767;
- }
- /* Write out the last chunk (which is < 32767 bytes) */
- if (_lwrite(iFileHandle, (LPSTR)hpBuffer, (WORD)dwBytes) != (WORD)dwBytes)
- return 0;
- return dwBytesTmp;
- }
- // ajw added
- // Added to allow "loading" from a location in memory.
- // A modification of ReadDIBFile(), above.
- //***********************************************************************************************
- HDIB LoadDIB_FromMemory( const unsigned char* pData, DWORD dwBitsSize )
- {
- BITMAPFILEHEADER bmfHeader;
- UINT nNumColors; // Number of colors in table
- HANDLE hDIB;
- HANDLE hDIBtmp; // Used for GlobalRealloc() //MPB
- LPBITMAPINFOHEADER lpbi;
- DWORD offBits;
- const unsigned char* const pDataStart = pData;
- const unsigned char* pDataEnd = pData + dwBitsSize; // One char past end of "file".
- // Allocate memory for header & color table. We'll enlarge this
- // memory as needed.
- // debugprint( "LoadDIB_FromMemory, GlobalAlloc\n" );
- hDIB = GlobalAlloc(GMEM_MOVEABLE, (DWORD)(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)));
- // debugprint( "hDIB from GlobalALloc is %i\n", hDIB );
- if (!hDIB)
- {
- // debugprint( "LoadDIB_FromMemory error: failed alloc\n" );
- return NULL;
- }
- // debugprint( "LoadDIB_FromMemory, lpbi Lock\n" );
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
- // debugprint( "lpbi is %i\n", lpbi );
- if (!lpbi)
- {
- // debugprint( "LoadDIB_FromMemory error: failed lock\n" );
- GlobalFree(hDIB);
- return NULL;
- }
- // read the BITMAPFILEHEADER from our file
- // if (sizeof (BITMAPFILEHEADER) != _lread (hFile, (LPSTR)&bmfHeader, sizeof (BITMAPFILEHEADER)))
- // goto ErrExit;
- if( pData + sizeof( BITMAPFILEHEADER ) >= pDataEnd )
- {
- // debugprint( "LoadDIB_FromMemory error: bad size\n" );
- goto ErrExit;
- }
- // debugprint( "LoadDIB_FromMemory, memcpy BITMAPFILEHEADER %i bytes\n", sizeof( BITMAPFILEHEADER ) );
- memcpy( &bmfHeader, pData, sizeof( BITMAPFILEHEADER ) );
- pData += sizeof( BITMAPFILEHEADER );
- if (bmfHeader.bfType != 0x4d42) /* 'BM' */
- {
- // debugprint( "LoadDIB_FromMemory error: no BM\n" );
- goto ErrExit;
- }
- // read the BITMAPINFOHEADER
- // if (sizeof(BITMAPINFOHEADER) != _lread (hFile, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
- // goto ErrExit;
- if( pData + sizeof( BITMAPINFOHEADER ) >= pDataEnd )
- {
- // debugprint( "LoadDIB_FromMemory error: bad size 2\n" );
- goto ErrExit;
- }
- // debugprint( "LoadDIB_FromMemory, memcpy BITMAPINFOHEADER %i bytes\n", sizeof( BITMAPINFOHEADER ) );
- memcpy( lpbi, pData, sizeof( BITMAPINFOHEADER ) );
- pData += sizeof( BITMAPINFOHEADER );
- // Check to see that it's a Windows DIB -- an OS/2 DIB would cause
- // strange problems with the rest of the DIB API since the fields
- // in the header are different and the color table entries are
- // smaller.
- //
- // If it's not a Windows DIB (e.g. if biSize is wrong), return NULL.
- if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
- {
- // debugprint( "LoadDIB_FromMemory error: lpbi->biSize bad\n" );
- goto ErrExit;
- }
- if( lpbi->biCompression != BI_RGB )
- {
- // debugprint( "LoadDIB_FromMemory error: Image is compressed\n" );
- goto ErrExit;
- }
- // Now determine the size of the color table and read it. Since the
- // bitmap bits are offset in the file by bfOffBits, we need to do some
- // special processing here to make sure the bits directly follow
- // the color table (because that's the format we are susposed to pass
- // back)
- nNumColors = (UINT)lpbi->biClrUsed;
- if (!nNumColors)
- {
- // no color table for 24-bit, default size otherwise
- if (lpbi->biBitCount != 24)
- nNumColors = 1 << lpbi->biBitCount; /* standard size table */
- }
- // fill in some default values if they are zero
- if (lpbi->biClrUsed == 0)
- lpbi->biClrUsed = nNumColors;
- // debugprint( "biSizeImage is %i. I would say it was %i, because the bpp is %i.\n", lpbi->biSizeImage, ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3) * lpbi->biHeight, lpbi->biBitCount );
- if (lpbi->biSizeImage == 0)
- {
- lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3) * lpbi->biHeight;
- }
- // get a proper-sized buffer for header, color table and bits
- GlobalUnlock(hDIB);
- // debugprint( "LoadDIB_FromMemory, GlobalReAlloc: lpbi->biSize=%i, nNumColors=%i, lpbi->biSizeImage=%i\n", lpbi->biSize, nNumColors,lpbi->biSizeImage );
- hDIBtmp = GlobalReAlloc(hDIB, lpbi->biSize + nNumColors * sizeof(RGBQUAD) + lpbi->biSizeImage, 0);
- if (!hDIBtmp) // can't resize buffer for loading
- {
- // debugprint( "LoadDIB_FromMemory error: realloc failed\n" );
- goto ErrExitNoUnlock; //MPB
- }
- else
- hDIB = hDIBtmp;
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
- // read the color table
- // _lread (hFile, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
- // debugprint( "LoadDIB_FromMemory, memcpy color table %i colors, so %i bytes\n", nNumColors, nNumColors * sizeof(RGBQUAD) );
- memcpy( (LPSTR)(lpbi) + lpbi->biSize, pData, nNumColors * sizeof(RGBQUAD) );
- pData += nNumColors * sizeof(RGBQUAD);
- // offset to the bits from start of DIB header
- offBits = lpbi->biSize + nNumColors * sizeof(RGBQUAD);
- // If the bfOffBits field is non-zero, then the bits might *not* be
- // directly following the color table in the file. Use the value in
- // bfOffBits to seek the bits.
- if (bmfHeader.bfOffBits != 0L)
- // _llseek(hFile, bmfHeader.bfOffBits, SEEK_SET);
- pData = pDataStart + bmfHeader.bfOffBits;
- // debugprint( "bmfHeader.bfOffBits is %i\n", bmfHeader.bfOffBits );
- // if (MyRead(hFile, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
- // goto OKExit;
- // debugprint( "Checking that pData(%i) + biSizeImage(%i), which is %i, is equal to pDataEnd(%i)\n",
- // pData, lpbi->biSizeImage, pData + lpbi->biSizeImage, pDataEnd );
- // if( pData + lpbi->biSizeImage != pDataEnd ) condition relaxed
- // {
- // debugprint( "LoadDIB_FromMemory error: bad size 3\n" );
- // goto ErrExit;
- // }
- // debugprint( "LoadDIB_FromMemory, memcpy the bits, %i bytes. Image is w %i, h.%i\n",
- // lpbi->biSizeImage, lpbi->biWidth, lpbi->biHeight );
- // debugprint( "Writing to lpbi (%i) + offBits (%i)\n", lpbi, offBits );
- memcpy( (LPSTR)lpbi + offBits, pData, lpbi->biSizeImage );
- // pData += lpbi->biSizeImage;
- // if( pData != pDataEnd ) // Should end up one byte past end of data. - condition relaxed
- // debugprint( "LoadDIB_FromMemory: ERROR! Ended up at %i instead of %i\n", pData, pDataEnd );
- goto OKExit;
- ErrExit:
- GlobalUnlock(hDIB);
- ErrExitNoUnlock:
- GlobalFree(hDIB);
- // debugprint( "LoadDIB_FromMemory Error!\n" );
- return NULL;
- OKExit:
- GlobalUnlock(hDIB);
- return hDIB;
- }
|