- while (ul > (DWORD) MAXREAD) {
- if (_lread(fh, (LPSTR) hp, (WORD) MAXREAD) != MAXREAD)
- return 0;
- ul -= MAXREAD;
- hp += MAXREAD;
- }
- if (_lread(fh, (LPSTR) hp, (WXUINT) ul) != (WXUINT) ul)
- return 0;
- return ulT;
-}
-
-/*
- * FUNCTION : lwrite(int fh, VOID FAR *pv, DWORD ul)
- * PURPOSE : Writes data in steps of 32k till all the data is written.
- * RETURNS : 0 - If write did not proceed correctly.
- * number of bytes written otherwise.
- */
-
-static DWORD lwrite(int fh, VOID FAR *pv, DWORD ul)
-{
- DWORD ulT = ul;
-#if defined(WINNT) || defined(__WIN32__) || defined(__WIN32__)
- BYTE *hp = (BYTE *) pv;
-#else
- BYTE huge *hp = (BYTE huge *) pv;
-#endif
- while (ul > MAXREAD) {
- if (_lwrite(fh, (LPSTR) hp, (WORD) MAXREAD) != MAXREAD)
- return 0;
- ul -= MAXREAD;
- hp += MAXREAD;
- }
- if (_lwrite(fh, (LPSTR) hp, (WXUINT) ul) != (WXUINT) ul)
- return 0;
- return ulT;
-}
-
-/*
- * FUNCTION : wxReadDIB(hWnd)
- * PURPOSE : Reads a DIB from a file, obtains a handle to its
- * BITMAPINFO struct. and loads the DIB. Once the DIB
- * is loaded, the function also creates a bitmap and
- * palette out of the DIB for a device-dependent form.
- * RETURNS : TRUE - DIB loaded and bitmap/palette created
- * The DIBINIT structure pointed to by pInfo is
- * filled with the appropriate handles.
- * FALSE - otherwise
- */
-
-bool wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
-{
- int fh;
- LPBITMAPINFOHEADER lpbi;
- OFSTRUCT of;
- BITMAPFILEHEADER bf;
- WORD nNumColors;
- bool result = FALSE;
- WORD offBits;
- HDC hDC;
- bool bCoreHead = FALSE;
- HANDLE hDIB = 0;
-
- /* Open the file and get a handle to it's BITMAPINFO */
-
- fh = OpenFile (wxConvertWX2MB(lpFileName), &of, OF_READ);
- if (fh == -1) {
- wxLogError(_("Can't open file '%s'"), lpFileName);
- return (0);
- }
-
- hDIB = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) +
- 256 * sizeof(RGBQUAD)));
- if (!hDIB)
- return(0);
-
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
-
- /* read the BITMAPFILEHEADER */
- if (sizeof (bf) != _lread (fh, (LPSTR)&bf, sizeof (bf)))
- goto ErrExit;
-
- if (bf.bfType != 0x4d42) /* 'BM' */
- goto ErrExit;
-
- if (sizeof(BITMAPCOREHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER)))
- goto ErrExit;
-
- if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
- {
- lpbi->biSize = sizeof(BITMAPINFOHEADER);
- lpbi->biBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
- lpbi->biPlanes = ((LPBITMAPCOREHEADER)lpbi)->bcPlanes;
- lpbi->biHeight = ((LPBITMAPCOREHEADER)lpbi)->bcHeight;
- lpbi->biWidth = ((LPBITMAPCOREHEADER)lpbi)->bcWidth;
- bCoreHead = TRUE;
- }
- else
- {
- // get to the start of the header and read INFOHEADER
- _llseek(fh,sizeof(BITMAPFILEHEADER),SEEK_SET);
- if (sizeof(BITMAPINFOHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
- goto ErrExit;
- }
-
- nNumColors = (WORD)lpbi->biClrUsed;
- if ( nNumColors == 0 )
- {
- /* 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);
- hDIB = GlobalReAlloc(hDIB, lpbi->biSize +
- nNumColors * sizeof(RGBQUAD) +
- lpbi->biSizeImage, 0);
- if (!hDIB) /* can't resize buffer for loading */
- goto ErrExit2;
-
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
-
- /* read the color table */
- if (!bCoreHead)
- _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
- else
- {
- signed int i;
- RGBQUAD FAR *pQuad;
- RGBTRIPLE FAR *pTriple;
-
- _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE));
-
- pQuad = (RGBQUAD FAR *)((LPSTR)lpbi + lpbi->biSize);
- pTriple = (RGBTRIPLE FAR *) pQuad;
- for (i = nNumColors - 1; i >= 0; i--)
- {
- pQuad[i].rgbRed = pTriple[i].rgbtRed;
- pQuad[i].rgbBlue = pTriple[i].rgbtBlue;
- pQuad[i].rgbGreen = pTriple[i].rgbtGreen;
- pQuad[i].rgbReserved = 0;
- }
- }
-
- /* offset to the bits from start of DIB header */
- offBits = (WORD)(lpbi->biSize + nNumColors * sizeof(RGBQUAD));
-
- if (bf.bfOffBits != 0L)
- {
- _llseek(fh,bf.bfOffBits,SEEK_SET);
- }
-
- if (lpbi->biSizeImage == lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
- {
- GlobalUnlock(hDIB);
-
- hDC = GetDC(NULL);
- if (!wxMakeBitmapAndPalette(hDC, hDIB, palette,
- bitmap))
- {
- ReleaseDC(NULL,hDC);
- goto ErrExit2;
- }
- else
- {
- ReleaseDC(NULL,hDC);
- GlobalFree(hDIB);
- result = TRUE;
- }
- }
- else
- {
-ErrExit:
- GlobalUnlock(hDIB);
-ErrExit2:
- GlobalFree(hDIB);
- }
-
- _lclose(fh);
- return(result);
-}
-
-/*
- * FUNCTION : wxMakeBitmapAndPalette
- * PURPOSE : Given a DIB, creates a bitmap and corresponding palette
- * to be used for a device-dependent representation of
- * of the image.
- * RETURNS : TRUE --> success. phPal and phBitmap are filled with
- * appropriate handles. Caller is responsible
- * for freeing objects.
- * FALSE --> unable to create objects. both pointer are
- * not valid
- */
-
-static bool wxMakeBitmapAndPalette(HDC hDC, HANDLE hDIB,
- HPALETTE * phPal, HBITMAP * phBitmap)
-{
- LPBITMAPINFOHEADER lpInfo;
- bool result = FALSE;
- HBITMAP hBitmap;
- HPALETTE hPalette, hOldPal;
- LPSTR lpBits;
-
- lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
-
- hPalette = wxMakeDIBPalette(lpInfo);
- if ( hPalette )
- {
- // Need to realize palette for converting DIB to bitmap.
- hOldPal = SelectPalette(hDC, hPalette, TRUE);
- RealizePalette(hDC);
-
- lpBits = (LPSTR)lpInfo + (WORD)lpInfo->biSize +
- (WORD)lpInfo->biClrUsed * sizeof(RGBQUAD);
- hBitmap = CreateDIBitmap(hDC, lpInfo, CBM_INIT, lpBits,
- (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS);
-
- SelectPalette(hDC, hOldPal, TRUE);
- RealizePalette(hDC);
-
- if (!hBitmap)
- DeleteObject(hPalette);
- else
- {
- *phBitmap = hBitmap;
- *phPal = hPalette;
- result = TRUE;
- }
- }
-
- GlobalUnlock (hDIB); // glt
-
- return(result);
-}
-
-/*
- * FUNCTION : wxMakeDIBPalette(lpInfo)
- * PURPOSE : Given a BITMAPINFOHEADER, create a palette based on
- * the color table.
- * RETURNS : non-zero - handle of a corresponding palette
- * zero - unable to create palette
- */
-
-HPALETTE wxMakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
-{
- LPLOGPALETTE npPal;
- RGBQUAD far *lpRGB;
- HPALETTE hLogPal;
- WORD i;
-
- /* since biClrUsed field was filled during the loading of the DIB,
- * we know it contains the number of colors in the color table.
- */
- if (lpInfo->biClrUsed)
- {
- npPal = (LPLOGPALETTE)malloc(sizeof(LOGPALETTE) +
- (WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
- if (!npPal)
- return NULL;
-
- npPal->palVersion = 0x300;
- npPal->palNumEntries = (WORD)lpInfo->biClrUsed;
-
- /* get pointer to the color table */
- lpRGB = (RGBQUAD FAR *)((LPSTR)lpInfo + lpInfo->biSize);
-
- /* copy colors from the color table to the LogPalette structure */
- for (i = 0; (DWORD)i < lpInfo->biClrUsed; i++, lpRGB++)
- {
- npPal->palPalEntry[i].peRed = lpRGB->rgbRed;
- npPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
- npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
- npPal->palPalEntry[i].peFlags = 0;
- }
-
- hLogPal = CreatePalette((LPLOGPALETTE)npPal);
- free(npPal);
-
- return(hLogPal);
- }
-
- /* 24-bit DIB with no color table. Return default palette. Another
- * option would be to create a 256 color "rainbow" palette to provide
- * some good color choices.
- */
- else
- return((HPALETTE) GetStockObject(DEFAULT_PALETTE));
-}
-
-/*
- *
- * Function: InitBitmapInfoHeader
- *
- * Purpose: Does a "standard" initialization of a BITMAPINFOHEADER,
- * given the Width, Height, and Bits per Pixel for the
- * DIB.
- *
- * By standard, I mean that all the relevant fields are set
- * to the specified values. biSizeImage is computed, the
- * biCompression field is set to "no compression," and all
- * other fields are 0.
- *
- * Note that DIBs only allow BitsPixel values of 1, 4, 8, or
- * 24. This routine makes sure that one of these values is
- * used (whichever is most appropriate for the specified
- * nBPP).
- *
- * Parms: lpBmInfoHdr == Far pointer to a BITMAPINFOHEADER structure
- * to be filled in.
- * dwWidth == Width of DIB (not in Win 3.0 & 3.1, high
- * word MUST be 0).
- * dwHeight == Height of DIB (not in Win 3.0 & 3.1, high
- * word MUST be 0).
- * nBPP == Bits per Pixel for the DIB.
- *
- */
-
-static void InitBitmapInfoHeader (LPBITMAPINFOHEADER lpBmInfoHdr,
- DWORD dwWidth,
- DWORD dwHeight,
- int nBPP)
-{
- // _fmemset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));
- memset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));
-
- lpBmInfoHdr->biSize = sizeof (BITMAPINFOHEADER);
- lpBmInfoHdr->biWidth = dwWidth;
- lpBmInfoHdr->biHeight = dwHeight;
- lpBmInfoHdr->biPlanes = 1;
-
- if (nBPP <= 1)
- nBPP = 1;
- else if (nBPP <= 4)
- nBPP = 4;
- else if (nBPP <= 8)
- nBPP = 8;
- /* Doesn't work
- else if (nBPP <= 16)
- nBPP = 16;
- */
- else
- nBPP = 24;
-
- lpBmInfoHdr->biBitCount = nBPP;
- lpBmInfoHdr->biSizeImage = WIDTHBYTES (dwWidth * nBPP) * dwHeight;
-}
-
-LPSTR wxFindDIBBits (LPSTR lpbi)
-{
- return (lpbi + *(LPDWORD)lpbi + wxPaletteSize (lpbi));
-}
-
-/*
- * Function: BitmapToDIB
- *
- * Purpose: Given a device dependent bitmap and a palette, returns
- * a handle to global memory with a DIB spec in it. The
- * DIB is rendered using the colors of the palette passed in.
- *
- * Parms: hBitmap == Handle to device dependent bitmap compatible
- * with default screen display device.
- * hPal == Palette to render the DDB with. If it's NULL,
- * use the default palette.
- */
-
-HANDLE wxBitmapToDIB (HBITMAP hBitmap, HPALETTE hPal)
-{
- BITMAP Bitmap;
- BITMAPINFOHEADER bmInfoHdr;
- LPBITMAPINFOHEADER lpbmInfoHdr;
- LPSTR lpBits;
- HDC hMemDC;
- HANDLE hDIB;
- HPALETTE hOldPal = NULL;
-
- // Do some setup -- make sure the Bitmap passed in is valid,
- // get info on the bitmap (like its height, width, etc.),
- // then setup a BITMAPINFOHEADER.
-
- if (!hBitmap)
- return NULL;
-
- if (!GetObject (hBitmap, sizeof (Bitmap), (LPSTR) &Bitmap))
- return NULL;
-
- InitBitmapInfoHeader (&bmInfoHdr,
- Bitmap.bmWidth,
- Bitmap.bmHeight,
- Bitmap.bmPlanes * Bitmap.bmBitsPixel);
-
- // Now allocate memory for the DIB. Then, set the BITMAPINFOHEADER
- // into this memory, and find out where the bitmap bits go.
-
- hDIB = GlobalAlloc (GHND, sizeof (BITMAPINFOHEADER) +
- wxPaletteSize ((LPSTR) &bmInfoHdr) + bmInfoHdr.biSizeImage);
-
- if (!hDIB)
- return NULL;
-
- lpbmInfoHdr = (LPBITMAPINFOHEADER) GlobalLock (hDIB);
-
- *lpbmInfoHdr = bmInfoHdr;
- lpBits = wxFindDIBBits ((LPSTR) lpbmInfoHdr);
-
-
- // Now, we need a DC to hold our bitmap. If the app passed us
- // a palette, it should be selected into the DC.
-
- hMemDC = GetDC (NULL);
-
- if (hPal)
- {
- hOldPal = SelectPalette (hMemDC, hPal, FALSE);
- RealizePalette (hMemDC);
- }
-
- // We're finally ready to get the DIB. Call the driver and let
- // it party on our bitmap. It will fill in the color table,
- // and bitmap bits of our global memory block.
-
- if (!GetDIBits (hMemDC, hBitmap, 0, Bitmap.bmHeight, lpBits,
- (LPBITMAPINFO) lpbmInfoHdr, DIB_RGB_COLORS))
- {
- GlobalUnlock (hDIB);
- GlobalFree (hDIB);
- hDIB = NULL;
- }
- else
- GlobalUnlock (hDIB);
-
- // Finally, clean up and return.
-
- if (hOldPal)
- SelectPalette (hMemDC, hOldPal, FALSE);
-
- ReleaseDC (NULL, hMemDC);
-
- return hDIB;
-}
-
-bool wxSaveBitmap(wxChar *filename, wxBitmap *bitmap, wxPalette *palette)
-{
- HPALETTE hPalette = 0;
-#if wxUSE_PALETTE
- if (palette)
- hPalette = (HPALETTE) palette->GetHPALETTE();
-#endif // wxUSE_PALETTE
-
- HANDLE dibHandle = wxBitmapToDIB((HBITMAP) bitmap->GetHBITMAP(), hPalette);
- if (dibHandle)
- {
- bool success = (wxWriteDIB(filename, dibHandle) != 0);
- GlobalFree(dibHandle);
- return success;
- }
- else return FALSE;
-}
-