00001 //------------------------------------------------------------------------------
00002 // DIBAPI.CPP --
00003 //
00004 // Original code from MicroSoft MSDN sample
00005 //
00006 //
00007 //------------------------------------------------------------------------------
00008 #define STRICT
00009 #include <windows.h>
00010 #pragma hdrstop
00011
00012 #include "dibapi.h"
00013
00014 WORD DIBNumColors (LPSTR lpbi)
00015 {
00016 WORD wBitCount;
00017
00018
00019 // If this is a Windows style DIB, the number of colors in the
00020 // color table can be less than the number of bits per pixel
00021 // allows for (i.e. lpbi->biClrUsed can be set to some value).
00022 // If this is the case, return the appropriate value.
00023
00024 if (IS_WIN3x_DIB (lpbi))
00025 {
00026 DWORD dwClrUsed;
00027
00028 dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;
00029
00030 if (dwClrUsed)
00031 return (WORD) dwClrUsed;
00032 }
00033
00034
00035 // Calculate the number of colors in the color table based on
00036 // the number of bits per pixel for the DIB.
00037
00038 if (IS_WIN3x_DIB (lpbi))
00039 wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount;
00040 else
00041 wBitCount = ((LPBITMAPCOREHEADER) lpbi)->bcBitCount;
00042
00043 switch (wBitCount)
00044 {
00045 case 1:
00046 return 2;
00047
00048 case 4:
00049 return 16;
00050
00051 case 8:
00052 return 256;
00053
00054 default:
00055 return 0;
00056 }
00057 }
00058
00059
00060 LPSTR FindDIBBits (LPSTR lpbi)
00061 {
00062 return (lpbi + *(LPDWORD)lpbi + PaletteSize (lpbi));
00063 }
00064
00065
00066
00067 WORD PaletteSize (LPSTR lpbi)
00068 {
00069 if (IS_WIN3x_DIB (lpbi))
00070 return (DIBNumColors (lpbi) * sizeof (RGBQUAD));
00071 else
00072 return (DIBNumColors (lpbi) * sizeof (RGBTRIPLE));
00073 }
00074
00075
00076 //
00077 // CreateDIBPalette
00078 //
00079 // Creates a palette from a DIB. Parameter passed in is the
00080 // handle to global memory containing the DIB.
00081 //
00082
00083 HPALETTE CreateDIBPalette (HANDLE hDIB)
00084 {
00085 LPLOGPALETTE lpPal;
00086 HANDLE hLogPal;
00087 HPALETTE hPal = NULL;
00088 int i, wNumColors;
00089 LPSTR lpbi;
00090 LPBITMAPINFO lpbmi;
00091 LPBITMAPCOREINFO lpbmc;
00092 BOOL bWinStyleDIB;
00093
00094 if(!hDIB)
00095 return NULL;
00096
00097 lpbi = (char *)GlobalLock (hDIB);
00098 lpbmi = (LPBITMAPINFO) lpbi;
00099 lpbmc = (LPBITMAPCOREINFO) lpbi;
00100 wNumColors = DIBNumColors (lpbi);
00101 bWinStyleDIB = IS_WIN3x_DIB (lpbi);
00102
00103 if (wNumColors)
00104 {
00105 hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
00106 sizeof (PALETTEENTRY) * wNumColors);
00107
00108 if (!hLogPal)
00109 {
00110 MessageBox (NULL, "Couldn't allocate memory for LOGPALETTE!", NULL, MB_OK);
00111 GlobalUnlock (hDIB);
00112 return NULL;
00113 }
00114
00115 lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
00116
00117 lpPal->palVersion = PALVERSION;
00118 lpPal->palNumEntries = wNumColors;
00119
00120 for (i = 0; i < wNumColors; i++)
00121 {
00122 if (bWinStyleDIB)
00123 {
00124 lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
00125 lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
00126 lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
00127 lpPal->palPalEntry[i].peFlags = 0;
00128 }
00129 else
00130 {
00131 lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
00132 lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
00133 lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
00134 lpPal->palPalEntry[i].peFlags = 0;
00135 }
00136 }
00137
00138 hPal = CreatePalette (lpPal);
00139
00140 if (!hPal)
00141 MessageBox (NULL, "CreatePalette() failed!", NULL, MB_OK);
00142
00143 GlobalUnlock (hLogPal);
00144 GlobalFree (hLogPal);
00145 }
00146
00147 GlobalUnlock (hDIB);
00148
00149 return hPal;
00150 }
00151
00152
00153
00154
00155 DWORD DIBHeight (LPSTR lpDIB)
00156 {
00157 LPBITMAPINFOHEADER lpbmi;
00158 LPBITMAPCOREHEADER lpbmc;
00159
00160 lpbmi = (LPBITMAPINFOHEADER) lpDIB;
00161 lpbmc = (LPBITMAPCOREHEADER) lpDIB;
00162
00163 if(lpbmi->biSize == sizeof (BITMAPINFOHEADER))
00164 return lpbmi->biHeight;
00165 else
00166 return (DWORD)lpbmc->bcHeight;
00167 }
00168
00169
00170
00171 DWORD DIBWidth (LPSTR lpDIB)
00172 {
00173 LPBITMAPINFOHEADER lpbmi;
00174 LPBITMAPCOREHEADER lpbmc;
00175
00176 lpbmi = (LPBITMAPINFOHEADER) lpDIB;
00177 lpbmc = (LPBITMAPCOREHEADER) lpDIB;
00178
00179 if (lpbmi->biSize == sizeof (BITMAPINFOHEADER))
00180 return lpbmi->biWidth;
00181 else
00182 return (DWORD) lpbmc->bcWidth;
00183 }
00184
00185
00186
00187
00188 // Given a handle to memory with a DIB, create/realize a palette into
00189 // the given DC. Returns old palette in the DC (or NULL on error).
00190
00191 HPALETTE RealizeDIBPalette(HDC hDC, HANDLE hDIB)
00192 {
00193 HPALETTE hPal, hOldPal = NULL;
00194
00195 if(hDIB && hDC)
00196 {
00197 if(hPal = CreateDIBPalette(hDIB))
00198 {
00199 hOldPal = SelectPalette(hDC, hPal, FALSE);
00200 if(hOldPal)
00201 RealizePalette(hDC);
00202 else
00203 DeleteObject(hPal);
00204 }
00205 }
00206 return hOldPal;
00207 }
00208
00209 void PaintDIBInBands(HDC hDC,
00210 HANDLE hDIB,
00211 int nDIBWidth,
00212 int nDIBHeight,
00213 int nBandHeight)
00214 {
00215 int y;
00216
00217 for (y = 0; y < nDIBHeight; y += nBandHeight)
00218 // if (gnZoomFactor == 1)
00219 DIBBlt (hDC,
00220 0, y,
00221 nDIBWidth, nBandHeight,
00222 hDIB,
00223 0, y,
00224 SRCCOPY);
00225 /*
00226 else
00227 StretchDIBBlt(hDC,
00228 0, y * gnZoomFactor,
00229 nDIBWidth * gnZoomFactor, nBandHeight * gnZoomFactor,
00230 hDIB,
00231 0, y,
00232 nDIBWidth, nBandHeight,
00233 SRCCOPY);
00234 */
00235 }
00236
00240 #pragma argsused
00241 BOOL DIBBlt(HDC hDC,
00242 int xDst,
00243 int yDst,
00244 int nWidth,
00245 int nHeight,
00246 HANDLE hDIB,
00247 int xSrc,
00248 int ySrc,
00249 DWORD dwROP)
00250 {
00251 LPSTR lpDIBHdr, lpDIBBits;
00252 BOOL bSuccess = TRUE;
00253 int nDIBWidth, nDIBHeight;
00254
00255
00256 // Make sure we've got proper handles.
00257 if (!hDIB || !hDC)
00258 return FALSE;
00259
00260 // Lock down the DIB, and get a pointer to the beginning of the bit
00261 // buffer. Then get the DIB's height/width. Translate
00262 // the passed in y coordinate into the DIB coord system.
00263 lpDIBHdr = (char *)GlobalLock(hDIB);
00264 lpDIBBits = FindDIBBits (lpDIBHdr);
00265 nDIBWidth = (int) DIBWidth (lpDIBHdr);
00266 nDIBHeight = (int) DIBHeight (lpDIBHdr);
00267 ySrc = (int) nDIBHeight - ySrc - nHeight;
00268
00269
00270 // Insure the x/y/widht/height are valid. Adjust if not, or abort
00271 // if no painting necessary.
00272
00273 if (xSrc > nDIBWidth)
00274 bSuccess = FALSE;
00275 else if (xSrc < 0)
00276 {
00277 nWidth += xSrc;
00278 xSrc = 0;
00279 }
00280
00281 if (ySrc > nDIBHeight)
00282 bSuccess = FALSE;
00283 else if (ySrc < 0)
00284 {
00285 nHeight -= ySrc;
00286 ySrc = 0;
00287 }
00288
00289
00290 // Do the SetDIBitsToDevice().
00291
00292 if (bSuccess)
00293 bSuccess = SetDIBitsToDevice (hDC, // hDC
00294 xDst, // DestX
00295 yDst, // DestY
00296 nWidth, // nDestWidth
00297 nHeight, // nDestHeight
00298 xSrc, // SrcX
00299 ySrc, // SrcY
00300 0, // nStartScan
00301 nDIBHeight, // nNumScans
00302 lpDIBBits, // lpBits
00303 (LPBITMAPINFO) lpDIBHdr, // lpBitsInfo
00304 DIB_RGB_COLORS) != 0; // wUsage
00305
00306
00307 // Clean up and get outta here.
00308 GlobalUnlock (hDIB);
00309
00310 return bSuccess;
00311 }
00312
00313 HBITMAP DIBToDDB (HANDLE hDIB, HPALETTE hPal)
00314 {
00315 LPSTR lpDIBHdr, lpDIBBits;
00316 HBITMAP hBitmap;
00317 HDC hDC;
00318 HPALETTE hOldPal = NULL;
00319
00320 if (!hDIB)
00321 return NULL;
00322
00323 lpDIBHdr = (char *)GlobalLock (hDIB);
00324 lpDIBBits = FindDIBBits (lpDIBHdr);
00325 hDC = GetDC (NULL);
00326
00327 if (!hDC)
00328 {
00329 GlobalUnlock (hDIB);
00330 return NULL;
00331 }
00332
00333 if (hPal)
00334 hOldPal = SelectPalette (hDC, hPal, FALSE);
00335
00336 RealizePalette (hDC);
00337
00338 hBitmap = CreateDIBitmap (hDC,
00339 (LPBITMAPINFOHEADER) lpDIBHdr,
00340 CBM_INIT,
00341 lpDIBBits,
00342 (LPBITMAPINFO) lpDIBHdr,
00343 DIB_RGB_COLORS);
00344
00345 if (!hBitmap)
00346 MessageBox (NULL, "CreateDIBitmap() failed!", NULL, MB_OK);
00347
00348 if (hOldPal)
00349 SelectPalette (hDC, hOldPal, FALSE);
00350
00351 ReleaseDC (NULL, hDC);
00352 GlobalUnlock (hDIB);
00353
00354 return hBitmap;
00355 }
00356
00357 BOOL AddDIBToListBox(HWND hList, LPSTR myStr, DIB * pBmp)
00358 {
00359 LRESULT dwIndex;
00360
00361 if(pBmp)
00362 {
00363 dwIndex = SendMessage(hList, LB_ADDSTRING, 0, (LONG)myStr);
00364 if((dwIndex != LB_ERR) && (dwIndex != LB_ERRSPACE))
00365 if(SendMessage(hList, LB_SETITEMDATA, (WPARAM)dwIndex, (LONG)pBmp) != LB_ERR)
00366 return TRUE;
00367 }
00368 return FALSE;
00369 }
00370
00371 void RemoveListBoxDIBs(HWND hList)
00372 {
00373 DIB * pBmp;
00374 DWORD cnt = (DWORD)SendMessage(hList, LB_GETCOUNT, 0, 0);
00375
00376 for(int i = 0; i < cnt; i++)
00377 {
00378 pBmp = (DIB *)SendMessage(hList, LB_GETITEMDATA, i, 0L);
00379 if(pBmp)
00380 delete pBmp;
00381 }
00382 }
00383
00384