BOOL WINAPI DibTransparentBlt(PDIB pdibDst, LPBYTE pbitsDst, int xDst, int yDst, PDIB pdibSrc, LPBYTE pbitsSrc, int xSrc, int ySrc, int cx, int cy, BYTE transparent) { RECT rcDst, rcSrc; RECT rcBltDst, rcBltSrc; long cxBlt, cyBlt; DWORD offDst, offSrc; WORD selDst, selSrc; long pitchDst, pitchSrc; SetRect(&rcDst, 0, 0, (int)DibWidth(pdibDst), (int)DibHeight(pdibDst)); SetRect(&rcSrc, 0, 0, (int)DibWidth(pdibSrc), (int)DibHeight(pdibSrc)); SetRect(&rcBltDst, xDst, yDst, xDst + cx, yDst + cy); SetRect(&rcBltSrc, xSrc, ySrc, xSrc + cx, ySrc + cy); if ((IntersectRect(&rcBltDst, &rcDst, &rcBltDst) == FALSE) || (IntersectRect(&rcBltSrc, &rcSrc, &rcBltSrc) == FALSE)) { return FALSE; } cxBlt = min(rcBltDst.right - rcBltDst.left, rcBltSrc.right - rcBltSrc.left); cyBlt = min(rcBltDst.bottom - rcBltDst.top, rcBltSrc.bottom - rcBltSrc.top); selDst = HIWORD(pbitsDst); selSrc = HIWORD(pbitsSrc); if (pdibDst->biHeight < 0) { pitchDst = (long)DibPitch(pdibDst); offDst = LOWORD(pbitsDst) + DibPitch(pdibDst) * rcBltDst.top + rcBltDst.left; } else { pitchDst = - (long)DibPitch(pdibDst); offDst = LOWORD(pbitsDst) + DibPitch(pdibDst) * (DibHeight(pdibDst) - rcBltDst.top - 1) + rcBltDst.left; } if (pdibSrc->biHeight < 0) { pitchSrc = (long)DibPitch(pdibSrc); offSrc = LOWORD(pbitsSrc) + DibPitch(pdibSrc) * rcBltSrc.top + rcBltSrc.left; } else { pitchSrc = - (long)DibPitch(pdibSrc); offSrc = LOWORD(pbitsSrc) + DibPitch(pdibSrc) * (DibHeight(pdibSrc) - rcBltSrc.top - 1) + rcBltSrc.left; } CopyTransparentBits(selDst, offDst, pitchDst, selSrc, offSrc, pitchSrc, cxBlt, cyBlt, transparent); return TRUE; }
/* * EstimateBGFFileSize: Return an upper bound on the size of the BGF file * that will result from saving the given bitmaps. */ int EstimateBGFFileSize(Bitmaps *b) { Group *g; int len = 0, i; len += 56; // header stuff // Space for hotspots and bitmaps for (i=0; i < b->num_bitmaps; i++) { PDIB pdib = b->bitmaps[i]; len += 17 + 9 * b->hotspots[i].num_hotspots; len += DibHeight(pdib) * DibWidth(pdib); } // Write out indices for (i=0; i < b->num_groups; i++) { g = &b->groups[i]; len += 4 + 4 * g->num_indices; } len += 100; // just to be safe return len; }
// Get the bounding rectangle. void CDIB::GetRect(CRect* pRect) { pRect->top = 0; pRect->left = 0; pRect->bottom = DibHeight(); pRect->right = DibWidth(); }
void CDocWindow::HandleImageRecolor(int x, int y, CImageObject* pObject) { if (pObject == NULL) return; BITMAPINFOHEADER* pBitmap = pObject->GetDib(); if (pBitmap != NULL) { CRect DestRect = pObject->GetDestRect(); CFloodFill FloodFill; CAGMatrix Matrix; CPoint pt(x, y); if (m_pClientDC) m_pClientDC->GetViewToDeviceMatrix().Inverse().Transform(pt); double xScale = (double)DibWidth(pBitmap) / DestRect.Width(); double yScale = (double)DibHeight(pBitmap) / DestRect.Height(); Matrix.Translate(-DestRect.left, -DestRect.top); Matrix.Scale(xScale, yScale, 0, 0); Matrix.Transform(pt); FloodFill.Fill(pBitmap, &DestRect, pt.x, pt.y, (m_fUsePrimaryColor ? m_PrimaryColor : m_SecondaryColor)); } // Invalidate the image's current location InvalidateImage(pObject); pObject->SetModified(true); //if (pDIBNew) //{ // pObject->SetDib(pDIBNew); // free(pDIB); //} //else //{ // // Adjust the image's matrix // CRect DestRect = pObject->GetDestRect(); // CAGMatrix Matrix = pObject->GetMatrix(); // Matrix.Transform(DestRect); // Matrix.Scale((bFlipX ? -1 : 1), (bFlipY ? -1 : 1), // (DestRect.left + DestRect.right) / 2, // (DestRect.top + DestRect.bottom) / 2); // pObject->SetMatrix(Matrix); //} }
// Get a pointer to a pixel. // NOTE: DIB scan lines are DWORD aligned. The scan line // storage width may be wider than the scan line image width // so calc the storage width by rounding the image width // to the next highest DWORD value. void* CDIB::GetPixelAddress(int x, int y) { int iWidth; // Note: This version deals only with 8 bpp DIBs. ASSERT(m_pBMI->bmiHeader.biBitCount == 8); // Make sure it's in range and if it isn't return zero. if ((x >= DibWidth()) || (y >= DibHeight())) { TRACE("Attempt to get out of range pixel address"); return NULL; } // Calculate the scan line storage width. iWidth = StorageWidth(); return m_pBits + (DibHeight()-y-1) * iWidth + x; }
// Draw the DIB to a given DC void CDIB::Draw(CDC* pDC, CRect *pcrWindow) { ::StretchDIBits(pDC->GetSafeHdc(), pcrWindow->left, // Destination x pcrWindow->top, // Destination y pcrWindow->Width(), // Destination width pcrWindow->Height(), // Destination height 0, // Source x 0, // Source y DibWidth(), // Source width DibHeight(), // Source height GetBitsAddress(), // Pointer to bits GetBitmapInfoAddress(), // BITMAPINFO DIB_RGB_COLORS, // Options SRCCOPY); // Raster operation code (ROP) }
//////////////////////////////////////////////////////////// // TWallTextureontrol // ----------------- // void TWallTextureControl::BuildBitmapData (const char *texname, SHORT /*remapPlayer*/) { Bitmaps b; PDIB pdib; BYTE *bits; int size; if (DibOpenFile(texname, &b) == False) { Notify("Couldn't load texture %s", texname); return; } pdib = BitmapsGetPdib(b, 0, 0); if (pdib == NULL) { Notify("Missing bitmap 0 in texture %s", texname); return; } BitmapXSize = DibWidth(pdib); BitmapYSize = DibHeight(pdib); bits = DibPtr(pdib); size = BitmapXSize * BitmapYSize; pBitmapData = (BYTE *) GetMemory(size); memcpy(pBitmapData, bits, size); BitmapsFree(&b); // Mark used colors BYTE *ptrData = pBitmapData; for (int i = 0 ; i < size ; i++ ) { pUsedColors[*ptrData] = TRUE; ptrData++; } return; }
/* * DibReadBits: Read bits of an image into the given PDIB. The file pointer * for f must be positioned at the start of the image information. * version is version of BGF file. * Return True on success. */ Bool DibReadBits(file_node *f, PDIB pdib, int version) { BYTE *bits, type; int length, temp, compressed_length, retval; uLongf len; bits = DibPtr(pdib); length = DibWidth(pdib) * DibHeight(pdib); if (version < 10) return False; // See if image is compressed if (MappedFileRead(f, &type, 1) != 1) return False; switch (type) { case 0: if (MappedFileRead(f, &temp, 4) != 4) return False; // Skip unused bytes if (MappedFileRead(f, bits, length) != length) return False; break; case 1: if (MappedFileRead(f, &compressed_length, 4) != 4) return False; len = length; retval = uncompress((Bytef *) bits, &len, (const Bytef *) f->ptr, compressed_length); if (retval != Z_OK) { dprintf("DibReadBits error during decompression\n"); return False; } f->ptr += compressed_length; break; default: dprintf("DibReadBits got bad type byte %d\n", (int) type); return False; } return True; }
BOOL CImageBMP::ReadFile(const CString& imageFileName) { if (imageFileName != "") filename = imageFileName; if (lpbi = DibOpenFile((char *)(const char *)filename)) { Width = DibWidth(lpbi); Height = DibHeight(lpbi); Depth = DibBitCount(lpbi); RawImage = (ImagePointerType)DibPtr(lpbi); EffWidth = (long)(((long)Width*Depth + 31) / 32) * 4; HPALETTE palette; if (palette = MakePalette((const BITMAPINFO FAR*)lpbi, 0)) { imagePalette = new CImagePalette; imagePalette->Attach(palette); DibSetUsage(lpbi, (HPALETTE) (*imagePalette), CIMAGE_COLORS); ColorType = (COLORTYPE_PALETTE | COLORTYPE_COLOR); } return TRUE; } return FALSE; }
void AboutTimer(HWND hwnd, UINT id) { HWND hwndBitmap; HDC hdc; int i, j, k, x, y; RECT r; PDIB pdib; BYTE *bits, index; object_node *obj; // Copy bits to offscreen area for (i=0; i < scroll_height; i++) { int yBitmap = (scroll_y + i) % DibHeight(credits_pdib); BYTE *pSource = DibPtr(credits_pdib) + (yBitmap * DibWidth(credits_pdib)); BYTE *pDest = gBits + i*DIBWIDTH(gbits_width); memcpy(pDest,pSource,scroll_width); } scroll_y++; if (scroll_y >= DibHeight(credits_pdib)) scroll_y = 0; hwndBitmap = GetDlgItem(hwnd, IDC_SCROLL); hdc = GetDC(hwndBitmap); SelectPalette(hdc, hPal, FALSE); BitBlt(hdc, 0, 0, scroll_width, scroll_height, gDC, 0, 0, SRCCOPY); ReleaseDC(hwndBitmap, hdc); // Draw animated characters r.left = r.top = 0; r.right = gbits_width; r.bottom = gbits_height; FillRect(gDC, &r, GetSysColorBrush(COLOR_3DFACE)); GdiFlush(); hdc = GetDC(hwnd); for (i=0; i < NUM_DUDES; i++) { if (dudes[i].obj != NULL) { obj = dudes[i].obj; if (rand() % 30 == 0) { obj->animate->animation = ANIMATE_ONCE; obj->animate->group = obj->animate->group_low = 3; obj->animate->group_high = 4; obj->animate->group_final = 0; obj->animate->period = obj->animate->tick = 400; if (config.play_sound) { switch (dudes[i].obj->icon_res) { case ABOUT_RSC1: index = 3; break; case ABOUT_RSC2: index = 4; break; case ABOUT_RSC3: index = 5; break; default: index = rand() % num_sounds; break; } SoundPlayFile(sounds[index], SF_RANDOM_PITCH); } } AnimateObject(dudes[i].obj, ABOUT_INTERVAL); pdib = GetObjectPdib(dudes[i].obj->icon_res, dudes[i].angle, dudes[i].obj->animate->group); if (pdib == NULL) continue; bits = DibPtr(pdib); x = dudes[i].x - DibWidth(pdib) / 2; y = DUDE_MAX_HEIGHT - DibHeight(pdib); for (j=0; j < DibHeight(pdib); j++) { for (k=0; k < DibWidth(pdib); k++) { index = *(bits + j * DibWidth(pdib) + k); if (index != TRANSPARENT_INDEX) *(gBits + (j + y) * DIBWIDTH(gbits_width) + x + k) = index; } } } } SelectPalette(hdc, hPal, FALSE); BitBlt(hdc, dude_x, dude_y, DUDE_AREA_WIDTH, DUDE_MAX_HEIGHT, gDC, 0, 0, SRCCOPY); ReleaseDC(hwnd, hdc); }
/* * AboutInitDialog: Handle WM_INITDIALOG messages. */ BOOL AboutInitDialog(HWND hDlg, HWND hwndFocus, LPARAM lParam) { int i,sideBuffer,xEdge,yEdge; POINT pt; HWND hwndScroll = GetDlgItem(hDlg, IDC_SCROLL); RECT r, rcScrollClient, rcScroll, rcDlg, rcDlgClient; char buffer[80]; char format[80]; /* Load credits from bgf file */ if (DibOpenFile(credits_filename, &credits_b)) credits_pdib = BitmapsGetPdibByIndex(credits_b, credits_page); else debug(("AboutInitDialog unable to load file %s\n", credits_filename)); GetWindowRect(hwndScroll, &r); OffsetRect(&r, -r.left, -r.top); GetWindowRect(hDlg, &rcDlg); GetWindowRect(hwndScroll, &rcScroll); GetClientRect(hwndScroll, &rcScrollClient); sideBuffer = rcScroll.left - rcDlg.left; xEdge = (rcScroll.right-rcScroll.left) - rcScrollClient.right; yEdge = (rcScroll.bottom-rcScroll.top) - rcScrollClient.bottom; scroll_width = DibWidth(credits_pdib); scroll_height = rcScrollClient.bottom; SetWindowPos(hwndScroll,NULL,0,0,xEdge + scroll_width,rcScroll.bottom - rcScroll.top,SWP_NOZORDER|SWP_NOMOVE); SetWindowPos(hDlg,NULL,0,0,xEdge + sideBuffer*2 + scroll_width,rcDlg.bottom - rcDlg.top,SWP_NOZORDER|SWP_NOMOVE); GetWindowRect(hDlg, &rcDlg); GetClientRect(hDlg, &rcDlgClient); // Center windows horizontally CenterDlgItem(hDlg, IDC_NUMBER); CenterDlgItem(hDlg, IDC_SPECIAL1); CenterDlgItem(hDlg, IDC_SPECIAL2); CenterDlgItem(hDlg, IDC_SCROLL); CenterDlgItem(hDlg, IDOK); hAboutDlg = hDlg; CenterWindow(hDlg, GetParent(hDlg)); GetDlgItemText(hDlg, IDC_NUMBER, format, 80); sprintf(buffer, format, MAJOR_REV*100+MINOR_REV); SetDlgItemText(hDlg, IDC_NUMBER, buffer); if (config.technical) { sprintf(buffer, "Client Software Version %d:%d", MAJOR_REV, MINOR_REV); SetDlgItemText(hDlg, IDC_SPECIAL1, buffer); sprintf(buffer, "Server Host Address %s:%d", (LPCTSTR)config.comm.hostname, config.comm.sockport); SetDlgItemText(hDlg, IDC_SPECIAL2, buffer); } GetWindowRect(GetDlgItem(hDlg,IDC_SPECIAL2),&r); pt.x = r.left + (r.right-r.left)/2 - DUDE_AREA_WIDTH/2; pt.y = r.bottom + 10; ScreenToClient(hDlg,&pt); scroll_y = 0; dude_x = pt.x; dude_y = pt.y; gbits_width = max(scroll_width, DUDE_AREA_WIDTH); gbits_height = max(scroll_height, DUDE_MAX_HEIGHT); gDC = CreateMemBitmap(gbits_width, gbits_height, &gOldBitmap, &gBits); if (gDC == 0) debug(("AboutInitDialog couldn't create DC!\n")); timer_id = SetTimer(hDlg, TIMER_ABOUT, ABOUT_INTERVAL, NULL); if (state == STATE_GAME) { // Set up animated characters for (i=0; i < NUM_DUDES; i++) { object_node *obj; obj = dudes[i].obj = ObjectGetBlank(); obj->icon_res = ABOUT_RSC; obj->animate->animation = ANIMATE_NONE; if (i == 0) { dudes[i].angle = 3 * NUMDEGREES / 4; dudes[i].x = DUDE_X1; } else { dudes[i].angle = NUMDEGREES / 4; dudes[i].x = DUDE_X2; } } } CenterWindow(hDlg, GetParent(hDlg)); return TRUE; }
/* * WriteBGFFile: Write Bitmaps and Options structures out to given filename. * Return FALSE on error. */ BOOL WriteBGFFile(Bitmaps *b, Options *opts, char *filename) { int i, j, temp, max_indices, len; Group *g; file_node f; len = EstimateBGFFileSize(b); if (!MappedFileOpenWrite(filename, &f, len)) return FALSE; // Write magic number for (i=0; i < 4; i++) if (MappedFileWrite(&f, &magic[i], 1) < 0) return FALSE; // Write version temp = VERSION; if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE; // Write bitmap name if (MappedFileWrite(&f, &b->name, MAX_BITMAPNAME) < 0) return FALSE; // Write # of bitmaps if (MappedFileWrite(&f, &b->num_bitmaps, 4) < 0) return FALSE; // Write # of index groups if (MappedFileWrite(&f, &b->num_groups, 4) < 0) return FALSE; // Find most indices in a group max_indices = 0; for (i=0; i < b->num_groups; i++) if (b->groups[i].num_indices > max_indices) max_indices = b->groups[i].num_indices; if (MappedFileWrite(&f, &max_indices, 4) < 0) return FALSE; // Write shrink factor if (MappedFileWrite(&f, &opts->shrink, 4) < 0) return FALSE; // Write out bitmaps for (i=0; i < b->num_bitmaps; i++) { PDIB pdib = b->bitmaps[i]; // Write out bitmap size (swap width and height if rotated) if (opts->rotate) { temp = DibHeight(pdib); if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE; temp = DibWidth(pdib); if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE; } else { temp = DibWidth(pdib); if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE; temp = DibHeight(pdib); if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE; } // Write out x and y offsets temp = b->offsets[i].x; if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE; temp = b->offsets[i].y; if (MappedFileWrite(&f, &temp, 4) < 0) return FALSE; // Write out hotspots if (MappedFileWrite(&f, &b->hotspots[i].num_hotspots, 1) < 0) return FALSE; for (j=0; j < b->hotspots[i].num_hotspots; j++) { if (MappedFileWrite(&f, &b->hotspots[i].numbers[j], 1) < 0) return FALSE; if (MappedFileWrite(&f, &b->hotspots[i].positions[j].x, 4) < 0) return FALSE; if (MappedFileWrite(&f, &b->hotspots[i].positions[j].y, 4) < 0) return FALSE; } // Write out the bytes of the bitmap if (!WriteBitmap(&f, pdib, opts)) return FALSE; } // Write out indices for (i=0; i < b->num_groups; i++) { g = &b->groups[i]; if (MappedFileWrite(&f, &g->num_indices, 4) < 0) return FALSE; for (j=0; j < g->num_indices; j++) if (MappedFileWrite(&f, &g->indices[j], 4) < 0) return FALSE; } UnmapViewOfFile(f.mem); CloseHandle(f.mapfh); SetFilePointer(f.fh, (f.ptr - f.mem), NULL, FILE_BEGIN); SetEndOfFile(f.fh); CloseHandle(f.fh); return TRUE; }
/* * WriteBitmap: Write bytes of given PDIB out to given file. * Return FALSE on error. */ BOOL WriteBitmap(file_node *f, PDIB pdib, Options *options) { int width, height, row, col, len, temp; BYTE *bits; BYTE *buf, *bufptr, byte; width = DibWidth(pdib); height = DibHeight(pdib); buf = (BYTE *) malloc(width * height); bufptr = buf; if (options->rotate) { for (col=0; col < width; col++) { bits = (BYTE *) DibPtr(pdib) + col; for (row = 0; row < height; row++) { *bufptr++ = *bits; bits += DibWidthBytes(pdib); } } } else { for (row=0; row < height; row++) { // Watch out--rows are 4-bytes aligned bits = (BYTE *) DibPtr(pdib) + row * DibWidthBytes(pdib); memcpy(bufptr, bits, width); bufptr += width; } } // Leave space for # of bytes if (options->compress) { len = WrapCompress((char *) buf, f->ptr + 5, width * height); if (len > 0) { byte = 1; // Save compressed length MappedFileWrite(f, &byte, 1); MappedFileWrite(f, &len, 4); f->ptr += len; } } else len = -1; if (len < 0) { byte = 0; MappedFileWrite(f, &byte, 1); temp = 0; MappedFileWrite(f, &temp, 4); // Buffer is incompressible; just write out bits themselves MappedFileWrite(f, buf, width * height); } free(buf); return True; }
/* * IntroShowSplash: Display splash screen. */ void IntroShowSplash(void) { RECT rect; BYTE *gTitleBits; int i; Bitmaps b; PDIB pdib; if (cinfo->config->quickstart) { OfflineConnect(); return; } if (showing_splash) return; showing_splash = True; IntroFreeLogo(); hwndDialButton = CreateWindow("button", NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, cinfo->hMain, (HMENU) IDC_DIALBUTTON, hInst, NULL); SetWindowText(hwndDialButton, GetString(hInst, IDS_INTRO)); /* Subclass button */ lpfnDefButtonProc = SubclassWindow(hwndDialButton, MainButtonProc); /* Get bits of bitmap from bgf file */ if (DibOpenFile(splash_filename, &b)) { pdib = BitmapsGetPdibByIndex(b, 0); /* Get bitmap's size */ bm_width = DibWidth(pdib); bm_height = DibHeight(pdib); /* Create bitmap */ hTitleDC = CreateMemBitmap(bm_width, bm_height, &hOldTitleBitmap, &gTitleBits); if (hTitleDC == NULL) { debug(("IntroShowSplash couldn't create bitmap!\n")); BitmapsFree(&b); return; } /* Copy bits into bitmap */ for (i=0; i < bm_height; i++) memcpy(gTitleBits + i * DIBWIDTH(bm_width), DibPtr(pdib) + i * bm_width, bm_width); BitmapsFree(&b); } else { hTitleDC = NULL; bm_width = BUTTON_XSIZE; } button_width = bm_width; button_height = BUTTON_YSIZE; /* Simulate resize to get positions right */ GetClientRect(cinfo->hMain, &rect); EventResize(rect.right, rect.bottom, NULL); SetFocus(hwndDialButton); timer_id = SetTimer(NULL, 0, MUSIC_DELAY, PlayMusicProc); }
HDIB DibConvert (HDIB hdibSrc, int iBitCountDst) { HDIB hdibDst ; HPALETTE hPalette ; int i, x, y, cx, cy, iBitCountSrc, cColors ; PALETTEENTRY pe ; RGBQUAD rgb ; WORD wNumEntries ; cx = DibWidth (hdibSrc) ; cy = DibHeight (hdibSrc) ; iBitCountSrc = DibBitCount (hdibSrc) ; if (iBitCountSrc == iBitCountDst) return NULL ; // DIB with color table to DIB with larger color table: if ((iBitCountSrc < iBitCountDst) && (iBitCountDst <= 8)) { cColors = DibNumColors (hdibSrc) ; hdibDst = DibCreate (cx, cy, iBitCountDst, cColors) ; for (i = 0 ; i < cColors ; i++) { DibGetColor (hdibSrc, i, &rgb) ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibSetPixel (hdibDst, x, y, DibGetPixel (hdibSrc, x, y)) ; } } // Any DIB to DIB with no color table else if (iBitCountDst >= 16) { hdibDst = DibCreate (cx, cy, iBitCountDst, 0) ; for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixelColor (hdibDst, x, y, &rgb) ; } } // DIB with no color table to 8-bit DIB else if (iBitCountSrc >= 16 && iBitCountDst == 8) { hPalette = DibPalMedianCut (hdibSrc, 6) ; GetObject (hPalette, sizeof (WORD), &wNumEntries) ; hdibDst = DibCreate (cx, cy, 8, wNumEntries) ; for (i = 0 ; i < (int) wNumEntries ; i++) { GetPaletteEntries (hPalette, i, 1, &pe) ; rgb.rgbRed = pe.peRed ; rgb.rgbGreen = pe.peGreen ; rgb.rgbBlue = pe.peBlue ; rgb.rgbReserved = 0 ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixel (hdibDst, x, y, GetNearestPaletteIndex (hPalette, RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ; } DeleteObject (hPalette) ; } // Any DIB to monochrome DIB else if (iBitCountDst == 1) { hdibDst = DibCreate (cx, cy, 1, 0) ; hPalette = DibPalUniformGrays (2) ; for (i = 0 ; i < 2 ; i++) { GetPaletteEntries (hPalette, i, 1, &pe) ; rgb.rgbRed = pe.peRed ; rgb.rgbGreen = pe.peGreen ; rgb.rgbBlue = pe.peBlue ; rgb.rgbReserved = 0 ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixel (hdibDst, x, y, GetNearestPaletteIndex (hPalette, RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ; } DeleteObject (hPalette) ; } // All non-monochrome DIBs to 4-bit DIB else if (iBitCountSrc >= 8 && iBitCountDst == 4) { hdibDst = DibCreate (cx, cy, 4, 0) ; hPalette = DibPalVga () ; for (i = 0 ; i < 16 ; i++) { GetPaletteEntries (hPalette, i, 1, &pe) ; rgb.rgbRed = pe.peRed ; rgb.rgbGreen = pe.peGreen ; rgb.rgbBlue = pe.peBlue ; rgb.rgbReserved = 0 ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixel (hdibDst, x, y, GetNearestPaletteIndex (hPalette, RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ; } DeleteObject (hPalette) ; } // Should not be necessary else hdibDst = NULL ; return hdibDst ; }