--- mstools/samples/mandel/loadbmp.c 2018/08/09 18:21:38 1.1.1.2 +++ mstools/samples/mandel/loadbmp.c 2018/08/09 18:23:41 1.1.1.3 @@ -18,67 +18,13 @@ * #include "jtypes.h" * \**************************************************************************/ -/**************************************************************************\ -* -* -* Summary: In Win32, saving or loading a bitmap in DIB format is basically -* the same as in Win16. However, care must be taken in DWORD -* alignment, especially on the MIPS platform. -* -* SYMPTOMS Exception on loading or saving a bitmap on the MIPS platform. -* In NTSD, get the error message of "data mis-alignment." -* -* CAUSE Passed a Non-DWORD aligned actual parameter to, say, GetDIBits(). -* -* STATUS/RESOLUTION -* -* The DIB file format contains the BITMAPFILEHEADER then followed -* immediately by the BITMAPINFOHEADER. Notice that the BITMAPFILEHEADER is -* not DWORD aligned. Thus, the structure that follows it, the -* BITMAPINFOHEADER is not on a DWORD boundary. If a pointer to this DWORD -* mis-aligned structure is passed to the 6th argument of GetDIBits(), an -* exception will occur. -* -* The remedy is to copy the data in the structure over to a DWORD -* aligned memory and passes the pointer to the latter structure to the -* function instead. See below for detail. -* -* -* ========================================================================= -* -* -* Summary: When saving a bitmap in DIB format in file, the GDI function is -* used to retrieve the bitmap information. Though the general use -* of this function and the technics for saving a bitmap in DIB -* format are largely unchanged, this article provide more details -* in the use of the Win32 version of the GetDIBits() api. -* -* -* The function can be used to retrieve the following information: -* 1. Just retrieving the data in the BitmapInfoHeader, no color table and -* no bits. -* -* 2. Retrieving the data in the BitmapInfoHeader and the color table. -* -* 3. Retrieving all the data, BitmapInfoHeader, color table and the bits. -* -* The 5th and the 6th parameters of the function are used to tell the -* graphics engine what exactly the appllication wants it to return. If the -* 5th parameteris NULL, then no bits will be returned. If the biBitCount -* is 0 in the 6th parameter, then no color table will be returned. In -* addition, the biSize field of the BitmapInfoHeader must be set to either -* the size of BitmapInfoHeader or BitmapCoreHeader for the function to work. -* See the following for details. -* -* -* -\**************************************************************************/ -//#define STRICT #include #include "jtypes.h" extern HWND ghwndMain; -extern VOID ErrorOut(); +extern VOID ErrorOut(char errstring[30]); +extern BOOL bSelectDIBPal(HDC, PINFO, LPBITMAPINFO, BOOL); +extern BOOL bFreeRleFile(PINFO); BOOL LoadBitmapFile(HDC, PINFO, PSTR); /******************************Public*Routine******************************\ @@ -90,25 +36,25 @@ BOOL LoadBitmapFile(HDC, PINFO, PSTR); * Warnings: pszFileName contains the full path * * History: +* 08-Feb-1993 Petrus Wong Keep DIB around for HT +* 22-Jan-1993 Petrus Wong 16,24,32 PM * 09-Jan-1992 -by- Petrus Wong * Wrote it. \**************************************************************************/ BOOL LoadBitmapFile(HDC hDC, PINFO pInfo, PSTR pszFileName) { - BOOL bSuccess; - HANDLE hFile, hMapFile; - LPVOID pMapFile; + BOOL bSuccess; + HANDLE hFile, hMapFile; + LPVOID pMapFile; LPBITMAPINFOHEADER pbmh; - LPBITMAPINFO pbmi; - PBYTE pjTmp; - ULONG sizBMI; - INT iNumClr; -#ifdef LATER - RGBQUAD *pRGBQuad; - RGBTRIPLE *pRGBTriple; - INT iEntry, i; -#endif + LPBITMAPINFO pbmi; + PBYTE pjTmp; + ULONG sizBMI; + INT iNumClr; + BOOL bCoreHdr; + PFILEINFO pFileInfo; + bSuccess = TRUE; @@ -123,7 +69,7 @@ BOOL LoadBitmapFile(HDC hDC, PINFO pInfo // Create a map file of the opened file // if ((hMapFile = CreateFileMapping(hFile, NULL, - PAGE_READONLY, 0, 0, "MapF")) == (HANDLE)-1) { + PAGE_READONLY, 0, 0, NULL)) == (HANDLE)-1) { ErrorOut("Fail in creating map file"); bSuccess = FALSE; goto ErrExit2; @@ -140,6 +86,16 @@ BOOL LoadBitmapFile(HDC hDC, PINFO pInfo } // + // Saving the DIB file handle, etc in pInfo... + // freeing existing objects, if any + // + bFreeRleFile(pInfo); + pFileInfo = &(pInfo->RleData.rgFileInfo[0]); + pFileInfo->hFile = hFile; + pFileInfo->hMapFile = hMapFile; + pFileInfo->lpvMapView = pMapFile; + + // // First check that it is a bitmap file // if (*((PWORD)pMapFile) != 0x4d42) { // 'BM' @@ -148,7 +104,6 @@ BOOL LoadBitmapFile(HDC hDC, PINFO pInfo goto ErrExit3; } -#ifndef LATER // // The file header doesn't end on DWORD boundary... // @@ -179,6 +134,8 @@ BOOL LoadBitmapFile(HDC hDC, PINFO pInfo // Use the size to determine if it is a BitmapCoreHeader or // BitmapInfoHeader // + // Does PM supports 16 and 32 bpp? How? + // if (bmch.bcSize == sizeof(BITMAPCOREHEADER)) { WORD wBitCount; @@ -186,17 +143,29 @@ BOOL LoadBitmapFile(HDC hDC, PINFO pInfo wBitCount = bmch.bcBitCount; iNumClr = ((wBitCount == 24) ? 0 : (1 << wBitCount)); sizBMI = sizeof(BITMAPCOREHEADER)+sizeof(RGBTRIPLE)*iNumClr; + bCoreHdr = TRUE; } else // BITMAPINFOHEADER { WORD wBitCount; wBitCount = bmih.biBitCount; - iNumClr = ((wBitCount == 24) ? 0 : (1 << wBitCount)); - sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*iNumClr; + switch (wBitCount) { + case 16: + case 32: + sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3; + break; + case 24: + sizBMI = sizeof(BITMAPINFOHEADER); + break; + default: + iNumClr = (1 << wBitCount); + sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*iNumClr; + break; + } + bCoreHdr = FALSE; } - } if ((pbmi = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED,sizBMI)) == NULL) { @@ -209,7 +178,6 @@ BOOL LoadBitmapFile(HDC hDC, PINFO pInfo // Make sure we pass in a DWORD aligned BitmapInfo to CreateDIBitmap // Otherwise, exception on the MIPS platform // CR!!! Equivalent to memcpy - // WARNING! This is not handling the RGBTRIPLE case correctly // pjTmp = (PBYTE)pbmi; @@ -217,66 +185,16 @@ BOOL LoadBitmapFile(HDC hDC, PINFO pInfo { *(((PBYTE)pjTmp)++) = *(((PBYTE)pbmh)++); } -#else - pbmh = (LPBITMAPINFOHEADER)((PBYTE)pMapFile + sizeof(BITMAPFILEHEADER)); - - if (pbmh->biSize == sizeof(BITMAPCOREHEADER)) - { - - DebugBreak(); - - iEntry = ((((LPBITMAPCOREHEADER)pbmh)->bcBitCount == 24) - ? 0 - : (1 << ((LPBITMAPCOREHEADER)pbmh)->bcBitCount)); - - sizBMI = sizeof(BITMAPCOREHEADER)+sizeof(RGBQUAD)*iEntry; - - if ((pbmi = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED,sizBMI)) == NULL) { - MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK); - bSuccess = FALSE; - goto ErrExit3; - } - - pjTmp = (PBYTE)pbmi; - - sizBMI = sizeof(BITMAPCOREHEADER); - while(sizBMI--) - { - *(((PBYTE)pjTmp)++) = *(((PBYTE)pbmh)++); - } - - ((PBYTE)pjTmp)--; - ((PBYTE)pbmh)--; - - pRGBQuad = (RGBQUAD *)pbmh; - pRGBTriple = (RGBTRIPLE *)pjTmp; - - for (i=0; i < iEntry; i++, pRGBTriple++, pRGBQuad++) - { - pRGBQuad->rgbBlue = pRGBTriple->rgbtBlue; - pRGBQuad->rgbGreen = pRGBTriple->rgbtGreen; - pRGBQuad->rgbRed = pRGBTriple->rgbtRed; - pRGBQuad->rgbReserved = 0x0; - } - - - } - else // BITMAPINFOHEADER - { - sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)* - ((pbmh->biBitCount == 24) ? 0 : (1 << pbmh->biBitCount)); - - while(sizBMI--) - { - *(((PBYTE)pjTmp)++) = *(((PBYTE)pbmh)++); - } - } - -#endif + // + // assuming CreateDIBitmap() is doing a byte fetch... + // pMapFile = (PBYTE)pMapFile + ((BITMAPFILEHEADER *)pMapFile)->bfOffBits; - + // + // Select the palette into the DC first before CreateDIBitmap() + // + bSelectDIBPal(hDC, pInfo, pbmi, bCoreHdr); if ((pInfo->hBmpSaved = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)pbmi, CBM_INIT, pMapFile, pbmi, DIB_RGB_COLORS)) == NULL) { ErrorOut("Fail in creating DIB bitmap from file!"); @@ -284,7 +202,21 @@ BOOL LoadBitmapFile(HDC hDC, PINFO pInfo goto ErrExit4; } + // + // Saving the DIB...free memory when the windows is closed. + // + pInfo->RleData.rgpjFrame[0] = pMapFile; + pInfo->RleData.rgpbmi[0] = pbmi; + pInfo->RleData.pbmi = (PBITMAPINFO) &(pInfo->RleData.rgpbmi[0]); + pInfo->RleData.ulFrames = 1; + pInfo->RleData.ulFiles = 1; + + // set flag to use original DIB as source for blting so HT can be done + pInfo->bUseDIB = TRUE; + + pInfo->bCoreHdr = bCoreHdr; + return (bSuccess); ErrExit4: LocalFree(pbmi);