/****************************************************************************/ /* */ /* Copyright (C) 1987-1996 Microsoft Corp. */ /* All Rights Reserved */ /* */ /****************************************************************************/ /****************************** Module Header ******************************* * Module Name: rwbmp.c * * Routines for reading and writing bitmap files. * * History: * ****************************************************************************/ #include "imagedit.h" #include #include #include // For NT fstat(). #include // For fstat() types. #include // For fstat() function. /************************************************************************ * LoadBitmapFile * * Loads the specified bitmap file. With ImagEdit, this must be a * Windows 3.0 DIB. * * Arguments: * PSTR pszFullFileName - Name of the bitmap file to load. * * Returns: * TRUE if successful, FALSE otherwise. * * History: * ************************************************************************/ BOOL LoadBitmapFile( PSTR pszFullFileName) { HFILE hf; OFSTRUCT OfStruct; struct stat FileStatus; DWORD dwFileSize; DWORD dwDIBSize; BITMAPFILEHEADER bfh; BITMAPINFOHEADER bih; PIMAGEINFO pImage; INT nColors; HANDLE hDIB; PDEVICE pDevice; if ((hf = (HFILE)OpenFile(pszFullFileName, (LPOFSTRUCT)&OfStruct, OF_READ)) == (HFILE)-1) { Message(MSG_CANTOPEN, pszFullFileName); return FALSE; } fstat((INT)_open_osfhandle((long)(hf), (int)(O_RDONLY)), &FileStatus); dwFileSize = (DWORD)FileStatus.st_size; ImageLinkFreeList(); /* * Read the Bitmap File Header. */ if (!MyFileRead(hf, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER), pszFullFileName, FT_BITMAP)) goto Error1; /* * Check for the "BM" at the start of the file, and the file size * in the header must match the real file size. */ if (bfh.bfType != 0x4D42 || bfh.bfSize != dwFileSize) { Message(MSG_BADBMPFILE, pszFullFileName); goto Error1; } /* * Read the Bitmap Info Header. */ if (!MyFileRead(hf, (LPSTR)&bih, sizeof(BITMAPINFOHEADER), pszFullFileName, FT_BITMAP)) goto Error1; /* * The DIB size should be the size of the file less the bitmap * file header. */ dwDIBSize = dwFileSize - sizeof(BITMAPFILEHEADER); if (!IsValidDIB((LPBITMAPINFO)&bih, dwDIBSize, FALSE)) { Message(MSG_BADBMPFILE, pszFullFileName); goto Error1; } /* * There is a limit to the size of image we will edit. For icons * and cursors, the field that carries the dimensions is a byte, * so the size cannot be greater than 256. This is also what * we limit bitmaps to. */ if (bih.biWidth > MAXIMAGEDIM || bih.biHeight > MAXIMAGEDIM) { Message(MSG_BADBMPSIZE, MAXIMAGEDIM, MAXIMAGEDIM); goto Error1; } switch (bih.biBitCount) { case 1: nColors = 2; break; case 4: nColors = 16; break; default: Message(MSG_NOTSUPPORT); goto Error1; } if (!(pDevice = DeviceLinkAlloc(FT_BITMAP, NULL, nColors, (INT)bih.biWidth, (INT)bih.biHeight))) { goto Error1; } if (!(pImage = ImageLinkAlloc(pDevice, (INT)bih.biWidth, (INT)bih.biHeight, 0, 0, nColors))) goto Error1; /* * Allocate space for the DIB for this image. */ if (!(hDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwDIBSize))) { Message(MSG_OUTOFMEMORY); goto Error2; } pImage->DIBSize = dwDIBSize; pImage->DIBhandle = hDIB; pImage->DIBPtr = (LPSTR)GlobalLock(hDIB); /* * Jump back to the start of the DIB. */ SetFilePointer((HANDLE)hf, sizeof(BITMAPFILEHEADER), NULL, (DWORD)0); /* * Read the entire DIB (including info and color table) into * the allocated memory for it. */ if (!MyFileRead(hf, pImage->DIBPtr, (DWORD)pImage->DIBSize, pszFullFileName, FT_BITMAP)) goto Error2; _lclose((HFILE)hf); fFileDirty = FALSE; SetFileName(pszFullFileName); giType = FT_BITMAP; /* * Bitmaps only have one "image" in the file. */ gnImages = 1; ImageOpen2(pImage); return TRUE; Error2: ImageLinkFreeList(); Error1: _lclose((HFILE)hf); return FALSE; } /************************************************************************ * SaveBitmapFile * * * * Arguments: * * Returns: * TRUE if successful, FALSE otherwise. * * History: * ************************************************************************/ BOOL SaveBitmapFile( PSTR pszFullFileName) { HCURSOR hcurOld; BITMAPFILEHEADER bfh; HFILE hf; OFSTRUCT OfStruct; hcurOld = SetCursor(hcurWait); /* * Save the bits of the current image. */ ImageSave(); /* * Open the file for writing. */ if ((hf = (HFILE)OpenFile(pszFullFileName, &OfStruct, OF_CREATE | OF_READWRITE)) == (HFILE)-1) { Message(MSG_CANTCREATE, pszFullFileName); goto Error1; } bfh.bfType = 0x4D42; bfh.bfSize = sizeof(BITMAPFILEHEADER) + gpImageCur->DIBSize; bfh.bfReserved1 = 0; bfh.bfReserved2 = 0; bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (gpImageCur->nColors * sizeof(RGBQUAD)); /* * Write the header to disk. */ if (!MyFileWrite(hf, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER), pszFullFileName)) goto Error2; /* * Now write the DIB (a bitmap file only has one). */ if (!MyFileWrite(hf, (LPSTR)gpImageCur->DIBPtr, (DWORD)gpImageCur->DIBSize, pszFullFileName)) goto Error2; _lclose((HFILE)hf); fFileDirty = FALSE; SetFileName(pszFullFileName); SetCursor(hcurOld); return TRUE; Error2: _lclose((HFILE)hf); Error1: SetCursor(hcurOld); return FALSE; }