|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: savebmp.c ! 3: * ! 4: * ! 5: * Created: 06-Jan-1992 10:59:36 ! 6: * Author: Petrus Wong ! 7: * ! 8: * Copyright (c) 1990 Microsoft Corporation ! 9: * ! 10: * Contains the main routine, SaveBitmapFile, for saving a DDB into file ! 11: * in DIB format. ! 12: * ! 13: * Dependencies: ! 14: * ! 15: * (#defines) ! 16: * (#includes) ! 17: * #include <windows.h> ! 18: * #include "jtypes.h" ! 19: * ! 20: \**************************************************************************/ ! 21: #include <windows.h> ! 22: #include "jtypes.h" ! 23: ! 24: ! 25: extern HWND ghwndMain; ! 26: extern char gtext[256]; ! 27: BOOL SaveBitmapFile(HDC, HBITMAP, PSTR); ! 28: void ErrorOut(char errstring[30]); ! 29: ! 30: /******************************Public*Routine******************************\ ! 31: * SaveBitmapFile ! 32: * ! 33: * ! 34: * Effects: Save pInfo->hBmpSaved into disk specified by pszFileName ! 35: * ! 36: * Warnings: assumes hBmpSaved is not selected into window's DC other than ! 37: * pInfo->hwnd's DC ! 38: * ! 39: * History: ! 40: * 14-Jan-1992 -by- Petrus Wong ! 41: * Wrote it. ! 42: \**************************************************************************/ ! 43: ! 44: BOOL SaveBitmapFile(HDC hDC, HBITMAP hBmp, PSTR pszFileName) ! 45: { ! 46: int hFile; ! 47: OFSTRUCT ofReOpenBuff; ! 48: HBITMAP hTmpBmp, hBmpOld; ! 49: BOOL bSuccess; ! 50: BITMAPFILEHEADER bfh; ! 51: PBITMAPINFO pbmi; ! 52: PBYTE pBits; ! 53: BITMAPINFO bmi; ! 54: PBYTE pjTmp, pjTmpBmi; ! 55: ULONG sizBMI; ! 56: ! 57: ! 58: bSuccess = TRUE; ! 59: if (!hBmp) { ! 60: MessageBox(ghwndMain, "There's no Bitmap to save!", "Error", MB_OK); ! 61: return FALSE; ! 62: } ! 63: ! 64: // ! 65: // Let the graphics engine to retrieve the dimension of the bitmap for us ! 66: // GetDIBits uses the size to determine if it's BITMAPCOREINFO or BITMAPINFO ! 67: // if BitCount != 0, color table will be retrieved ! 68: // ! 69: bmi.bmiHeader.biSize = 0x28; // GDI need this to work ! 70: bmi.bmiHeader.biBitCount = 0; // don't get the color table ! 71: if ((GetDIBits(hDC, hBmp, 0, 0, (LPSTR)NULL, &bmi, DIB_RGB_COLORS)) == 0) { ! 72: MessageBox(ghwndMain, "GetDIBits failed!", "Error", MB_OK); ! 73: return FALSE; ! 74: } ! 75: ! 76: // ! 77: // Now that we know the size of the image, alloc enough memory to retrieve ! 78: // the actual bits ! 79: // ! 80: if ((pBits = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, ! 81: bmi.bmiHeader.biWidth * bmi.bmiHeader.biHeight)) == NULL) { ! 82: MessageBox(ghwndMain, "Failed in Memory Allocation for pBits!", "Error", MB_OK); ! 83: return FALSE; ! 84: } ! 85: ! 86: // ! 87: // Note: 24 bits per pixel has no color table. So, we don't have to ! 88: // allocate memory for retrieving that. Otherwise, we do. ! 89: // ! 90: pbmi = &bmi; // assume no color table ! 91: if (bmi.bmiHeader.biBitCount != 24) { // has color table ! 92: sizBMI = sizeof(BITMAPINFO)+sizeof(RGBQUAD)*(1<<bmi.bmiHeader.biBitCount); ! 93: // ! 94: // I need more memory for the color table ! 95: // ! 96: if ((pbmi = (PBITMAPINFO)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizBMI )) == NULL) { ! 97: MessageBox(ghwndMain, "Failed in Memory Allocation for pbmi!", "Error", MB_OK); ! 98: bSuccess = FALSE; ! 99: goto ErrExit1; ! 100: } ! 101: #if 0 ! 102: pbmi->bmiHeader.biSize = bmi.bmiHeader.biSize; ! 103: pbmi->bmiHeader.biWidth = bmi.bmiHeader.biWidth; ! 104: pbmi->bmiHeader.biHeight = bmi.bmiHeader.biHeight; ! 105: pbmi->bmiHeader.biPlanes = bmi.bmiHeader.biPlanes; ! 106: pbmi->bmiHeader.biBitCount = bmi.bmiHeader.biBitCount; ! 107: pbmi->bmiHeader.biCompression = bmi.bmiHeader.biCompression; ! 108: pbmi->bmiHeader.biSizeImage = bmi.bmiHeader.biSizeImage; ! 109: pbmi->bmiHeader.biXPelsPerMeter = bmi.bmiHeader.biXPelsPerMeter; ! 110: pbmi->bmiHeader.biYPelsPerMeter = bmi.bmiHeader.biYPelsPerMeter; ! 111: pbmi->bmiHeader.biClrUsed = bmi.bmiHeader.biClrUsed; ! 112: pbmi->bmiHeader.biClrImportant = bmi.bmiHeader.biClrImportant; ! 113: #endif ! 114: // ! 115: // Now that we've a bigger chunk of memory, let's copy the Bitmap ! 116: // info header data over ! 117: // ! 118: pjTmp = (PBYTE)pbmi; ! 119: pjTmpBmi = (PBYTE)&bmi; ! 120: sizBMI = sizeof(BITMAPINFOHEADER); ! 121: ! 122: while(sizBMI--) ! 123: { ! 124: *(((PBYTE)pjTmp)++) = *((pjTmpBmi)++); ! 125: } ! 126: ! 127: } ! 128: ! 129: // ! 130: // Let's open the file and get ready for writing ! 131: // ! 132: if ((hFile = OpenFile(pszFileName, (LPOFSTRUCT)&ofReOpenBuff, ! 133: OF_CREATE | OF_WRITE)) == -1) { ! 134: MessageBox(ghwndMain, "Failed in OpenFile!", "Error", MB_OK); ! 135: ErrorOut("OpenFile"); ! 136: goto ErrExit2; ! 137: } ! 138: ! 139: // ! 140: // But first, fill in the info for the BitmapFileHeader ! 141: // ! 142: bfh.bfType = 0x4D42; // 'BM' ! 143: bfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)* ! 144: ((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1<<pbmi->bmiHeader.biBitCount))+ ! 145: pbmi->bmiHeader.biSizeImage; ! 146: bfh.bfReserved1 = ! 147: bfh.bfReserved2 = 0; ! 148: bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ ! 149: sizeof(RGBQUAD)*((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1<<pbmi->bmiHeader.biBitCount)); ! 150: ! 151: // ! 152: // Write out the file header now ! 153: // ! 154: if (_lwrite(hFile, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER)) == -1) { ! 155: MessageBox(ghwndMain, "Failed in WriteFile!", "Error", MB_OK); ! 156: bSuccess = FALSE; ! 157: goto ErrExit3; ! 158: } ! 159: ! 160: // ! 161: // Bitmap can't be selected into a DC when calling GetDIBits ! 162: // Assume that the hDC is the DC where the bitmap would have been selected ! 163: // if indeed it has been selected ! 164: // ! 165: if (hTmpBmp = CreateCompatibleBitmap(hDC, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight)) { ! 166: hBmpOld = SelectObject(hDC, hTmpBmp); ! 167: if ((GetDIBits(hDC, hBmp, 0, pbmi->bmiHeader.biHeight, (LPSTR)pBits, pbmi, DIB_RGB_COLORS))==0){ ! 168: MessageBox(ghwndMain, "Failed in GetDIBits!", "Error", MB_OK); ! 169: bSuccess = FALSE; ! 170: goto ErrExit4; ! 171: } ! 172: } else { ! 173: MessageBox(ghwndMain, "Failed in creating bitmap!", "Error", MB_OK); ! 174: bSuccess = FALSE; ! 175: goto ErrExit3; ! 176: } ! 177: ! 178: // ! 179: // Now write out the BitmapInfoHeader and color table, if any ! 180: // ! 181: if (_lwrite(hFile, (LPSTR)pbmi, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * ! 182: ((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1 << pbmi->bmiHeader.biBitCount))) == -1) { ! 183: MessageBox(ghwndMain, "Failed in WriteFile!", "Error", MB_OK); ! 184: bSuccess = FALSE; ! 185: goto ErrExit4; ! 186: } ! 187: ! 188: // ! 189: // write the bits also ! 190: // ! 191: if (_lwrite(hFile, (LPSTR)pBits, pbmi->bmiHeader.biSizeImage) == -1) { ! 192: MessageBox(ghwndMain, "Failed in WriteFile!", "Error", MB_OK); ! 193: bSuccess = FALSE; ! 194: goto ErrExit4; ! 195: } ! 196: ! 197: ErrExit4: ! 198: SelectObject(hDC, hBmpOld); ! 199: DeleteObject(hTmpBmp); ! 200: ErrExit3: ! 201: _lclose(hFile); ! 202: ErrExit2: ! 203: GlobalFree(pbmi); ! 204: ErrExit1: ! 205: GlobalFree(pBits); ! 206: return bSuccess; ! 207: } ! 208: ! 209: /************************************************************************ ! 210: * void ErrorOut(char errstring[30]) ! 211: * ! 212: * Purpose: Print out an meainful error code by means of ! 213: * GetLastError and printf ! 214: * ! 215: * Inputs: errstring - the action that failed, passed by the ! 216: * calling proc. ! 217: * ! 218: * Returns: none ! 219: * ! 220: * Calls: GetLastError ! 221: * ! 222: * History: ! 223: * 09-13-91 Pete Grey Created. ! 224: * ! 225: \************************************************************************/ ! 226: ! 227: ! 228: void ErrorOut(char errstring[30]) ! 229: { ! 230: DWORD Error; ! 231: CHAR str[80]; ! 232: ! 233: Error= GetLastError(); ! 234: wsprintf((LPSTR) str, "Error on %s = %d\n", errstring, Error); ! 235: MessageBox(ghwndMain, (LPSTR)str, "Error", MB_OK); ! 236: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.