/* * GetAndBitmapInfo - Returns a pointer to a bitmap info structure ... memory * should be freed with FreeDIBitmapInfo. this is for * the and part. */ BITMAPINFO2 *GetAndBitmapInfo( img_node *node ) { long size; WPI_BITMAPINFO *bmi; WPI_BITMAPINFOHEADER bmih; WPI_PRES pres; WPI_PRES mempres; HDC memdc; HBITMAP oldbitmap; pres = _wpi_getpres( HWND_DESKTOP ); mempres = _wpi_createcompatiblepres( pres, Instance, &memdc ); _wpi_releasepres( HWND_DESKTOP, pres ); size = BMPINFO2_SIZE( 1 ); bmi = MemAlloc( size ); GetBitmapInfoHeader( &bmih, node ); // Adjustments for the and mask bmih.cBitCount = 1; bmih.cbImage = BITS_TO_BYTES( node->bitcount, node->height ); bmih.cclrUsed = 2; memcpy( bmi, &bmih, sizeof(WPI_BITMAPINFOHEADER) ); oldbitmap = _wpi_selectobject( mempres, node->handbitmap ); GpiQueryBitmapBits( mempres, 0, node->height, NULL, bmi ); _wpi_selectobject( mempres, oldbitmap ); _wpi_deletecompatiblepres( mempres, memdc ); bmi->cbImage = BITS_TO_BYTES( node->bitcount, 2*node->height ); bmi->cy = node->height * 2; return( bmi ); } /* GetAndBitmapInfo */
/* * GetXorBitmapInfo - Returns a pointer to a bitmap info structure ... memory * should be freed with FreeDIBitmapInfo. this is for * the xor part. */ BITMAPINFO2 *GetXorBitmapInfo( img_node *node ) { long size; WPI_BITMAPINFO *bmi; WPI_BITMAPINFOHEADER bmih; WPI_PRES pres; WPI_PRES mempres; HDC memdc; HBITMAP oldbitmap; pres = _wpi_getpres( HWND_DESKTOP ); mempres = _wpi_createcompatiblepres( pres, Instance, &memdc ); _wpi_releasepres( HWND_DESKTOP, pres ); size = BMPINFO2_SIZE( node->bitcount ); bmi = MemAlloc( size ); GetBitmapInfoHeader( &bmih, node ); memcpy( bmi, &bmih, sizeof(WPI_BITMAPINFOHEADER) ); oldbitmap = _wpi_selectobject( mempres, node->hxorbitmap ); GpiQueryBitmapBits( mempres, 0, node->height, NULL, bmi ); _wpi_selectobject( mempres, oldbitmap ); _wpi_deletecompatiblepres( mempres, memdc ); return( bmi ); } /* GetXorBitmapInfo */
/* * writeDataInPieces - writes the xor data for the bitmap in chunks */ static bool writeDataInPieces( BITMAPINFO2 *bmi, FILE *fp, img_node *node ) { WPI_PRES pres; WPI_PRES mempres; HDC memdc; int scanline_count; int one_scanline_size; long chunk_size; int start; int num_lines; long byte_count; BYTE *buffer; HBITMAP oldbitmap; pres = _wpi_getpres( HWND_DESKTOP ); mempres = _wpi_createcompatiblepres( pres, Instance, &memdc ); _wpi_releasepres( HWND_DESKTOP, pres ); oldbitmap = _wpi_selectobject( mempres, node->hxorbitmap ); byte_count = BITS_TO_BYTES( node->bitcount * node->width, node->height ); start = 0; num_lines = SCANLINE_SIZE; one_scanline_size = BITS_TO_BYTES( node->width*node->bitcount, 1 ); scanline_count = node->height; chunk_size = one_scanline_size * num_lines; while( chunk_size > MAX_CHUNK ) { chunk_size >>= 1; num_lines = chunk_size / one_scanline_size; } buffer = calloc( chunk_size, sizeof( BYTE ) ); while( scanline_count > num_lines ) { GpiQueryBitmapBits( mempres, start, num_lines, buffer, bmi ); fwrite( buffer, sizeof( BYTE ), chunk_size, fp ); scanline_count -= num_lines; start += num_lines; byte_count -= chunk_size; } GpiQueryBitmapBits( mempres, start, scanline_count, buffer, bmi ); fwrite( buffer, sizeof( BYTE ), one_scanline_size * scanline_count, fp ); free( buffer ); _wpi_selectobject( mempres, oldbitmap ); _wpi_deletecompatiblepres( mempres, memdc ); return( true ); } /* writeDataInPieces */
static void _cairo_os2_surface_get_pixels_from_screen (cairo_os2_surface_t *surface, HPS hps_begin_paint, PRECTL prcl_begin_paint_rect) { HPS hps; HDC hdc; HAB hab; SIZEL sizlTemp; HBITMAP hbmpTemp; BITMAPINFO2 bmi2Temp; POINTL aptlPoints[4]; int y; unsigned char *pchTemp; /* To copy pixels from screen to our buffer, we do the following steps: * * - Blit pixels from screen to a HBITMAP: * -- Create Memory Device Context * -- Create a PS into it * -- Create a HBITMAP * -- Select HBITMAP into memory PS * -- Blit dirty pixels from screen to HBITMAP * - Copy HBITMAP lines (pixels) into our buffer * - Free resources * * These steps will require an Anchor Block (HAB). However, * WinQUeryAnchorBlock () documentation says that HAB is not * used in current OS/2 implementations, OS/2 deduces all information * it needs from the TID. Anyway, we'd be in trouble if we'd have to * get a HAB where we only know a HPS... * So, we'll simply use a fake HAB. */ hab = (HAB) 1; /* OS/2 doesn't really use HAB... */ /* Create a memory device context */ hdc = DevOpenDC (hab, OD_MEMORY,"*",0L, NULL, NULLHANDLE); if (!hdc) { return; } /* Create a memory PS */ sizlTemp.cx = prcl_begin_paint_rect->xRight - prcl_begin_paint_rect->xLeft; sizlTemp.cy = prcl_begin_paint_rect->yTop - prcl_begin_paint_rect->yBottom; hps = GpiCreatePS (hab, hdc, &sizlTemp, PU_PELS | GPIT_NORMAL | GPIA_ASSOC); if (!hps) { DevCloseDC (hdc); return; } /* Create an uninitialized bitmap. */ /* Prepare BITMAPINFO2 structure for our buffer */ memset (&bmi2Temp, 0, sizeof (bmi2Temp)); bmi2Temp.cbFix = sizeof (BITMAPINFOHEADER2); bmi2Temp.cx = sizlTemp.cx; bmi2Temp.cy = sizlTemp.cy; bmi2Temp.cPlanes = 1; bmi2Temp.cBitCount = 32; hbmpTemp = GpiCreateBitmap (hps, (PBITMAPINFOHEADER2) &bmi2Temp, 0, NULL, NULL); if (!hbmpTemp) { GpiDestroyPS (hps); DevCloseDC (hdc); return; } /* Select the bitmap into the memory device context. */ GpiSetBitmap (hps, hbmpTemp); /* Target coordinates (Noninclusive) */ aptlPoints[0].x = 0; aptlPoints[0].y = 0; aptlPoints[1].x = sizlTemp.cx; aptlPoints[1].y = sizlTemp.cy; /* Source coordinates (Inclusive) */ aptlPoints[2].x = prcl_begin_paint_rect->xLeft; aptlPoints[2].y = surface->bitmap_info.cy - prcl_begin_paint_rect->yBottom; aptlPoints[3].x = prcl_begin_paint_rect->xRight; aptlPoints[3].y = surface->bitmap_info.cy - prcl_begin_paint_rect->yTop; /* Blit pixels from screen to bitmap */ GpiBitBlt (hps, hps_begin_paint, 4, aptlPoints, ROP_SRCCOPY, BBO_IGNORE); /* Now we have to extract the pixels from the bitmap. */ pchTemp = surface->pixels + (prcl_begin_paint_rect->yBottom)*surface->bitmap_info.cx*4 + prcl_begin_paint_rect->xLeft*4; for (y = 0; y < sizlTemp.cy; y++) { /* Get one line of pixels */ GpiQueryBitmapBits (hps, sizlTemp.cy - y - 1, /* lScanStart */ 1, /* lScans */ pchTemp, &bmi2Temp); /* Go for next line */ pchTemp += surface->bitmap_info.cx*4; } /* Clean up resources */ GpiSetBitmap (hps, (HBITMAP) NULL); GpiDeleteBitmap (hbmpTemp); GpiDestroyPS (hps); DevCloseDC (hdc); }
nsresult nsIconChannel::MakeInputStream(nsIInputStream **_retval, bool nonBlocking) { // get some details about this icon nsCOMPtr<nsIFile> localFile; uint32_t desiredImageSize; nsXPIDLCString contentType; nsAutoCString filePath; nsresult rv = ExtractIconInfoFromUrl(getter_AddRefs(localFile), &desiredImageSize, contentType, filePath); NS_ENSURE_SUCCESS(rv, rv); // if the file exists, get its path bool fileExists = false; if (localFile) { localFile->GetNativePath(filePath); localFile->Exists(&fileExists); } // get the file's icon from either the WPS or PM bool fWpsIcon = false; HPOINTER hIcon = GetIcon(filePath, fileExists, desiredImageSize <= 16, &fWpsIcon); if (hIcon == NULLHANDLE) return NS_ERROR_FAILURE; // get the color & mask bitmaps used by the icon POINTERINFO IconInfo; if (!WinQueryPointerInfo(hIcon, &IconInfo)) { DestroyIcon(hIcon, fWpsIcon); return NS_ERROR_FAILURE; } // if we need a mini-icon, use those bitmaps if present; // otherwise, signal that the icon needs to be shrunk bool fShrink = FALSE; if (desiredImageSize <= 16) { if (IconInfo.hbmMiniPointer) { IconInfo.hbmColor = IconInfo.hbmMiniColor; IconInfo.hbmPointer = IconInfo.hbmMiniPointer; } else { fShrink = TRUE; } } // various resources to be allocated PBITMAPINFO2 pBMInfo = 0; uint8_t* pInBuf = 0; uint8_t* pOutBuf = 0; HDC hdc = 0; HPS hps = 0; // using this dummy do{...}while(0) "loop" guarantees that resources will // be deallocated, but eliminates the need for nesting, and generally makes // testing for & dealing with errors pretty painless (just 'break') do { rv = NS_ERROR_FAILURE; // get the details for the color bitmap; if there isn't one // or this is 1-bit color, exit BITMAPINFOHEADER2 BMHeader; BMHeader.cbFix = sizeof(BMHeader); if (!IconInfo.hbmColor || !GpiQueryBitmapInfoHeader(IconInfo.hbmColor, &BMHeader) || BMHeader.cBitCount == 1) break; // alloc space for the color bitmap's info, including its color table uint32_t cbBMInfo = sizeof(BITMAPINFO2) + (sizeof(RGB2) * 255); pBMInfo = (PBITMAPINFO2)nsMemory::Alloc(cbBMInfo); if (!pBMInfo) break; // alloc space for the color bitmap data uint32_t cbInRow = ALIGNEDBPR(BMHeader.cx, BMHeader.cBitCount); uint32_t cbInBuf = cbInRow * BMHeader.cy; pInBuf = (uint8_t*)nsMemory::Alloc(cbInBuf); if (!pInBuf) break; memset(pInBuf, 0, cbInBuf); // alloc space for the BGRA32 bitmap we're creating uint32_t cxOut = fShrink ? BMHeader.cx / 2 : BMHeader.cx; uint32_t cyOut = fShrink ? BMHeader.cy / 2 : BMHeader.cy; uint32_t cbOutBuf = 2 + ALIGNEDBPR(cxOut, 32) * cyOut; pOutBuf = (uint8_t*)nsMemory::Alloc(cbOutBuf); if (!pOutBuf) break; memset(pOutBuf, 0, cbOutBuf); // create a DC and PS DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL}; hdc = DevOpenDC((HAB)0, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE); if (!hdc) break; SIZEL sizel = {0,0}; hps = GpiCreatePS((HAB)0, hdc, &sizel, GPIA_ASSOC | PU_PELS | GPIT_MICRO); if (!hps) break; // get the color bits memset(pBMInfo, 0, cbBMInfo); *((PBITMAPINFOHEADER2)pBMInfo) = BMHeader; GpiSetBitmap(hps, IconInfo.hbmColor); if (GpiQueryBitmapBits(hps, 0L, (LONG)BMHeader.cy, (BYTE*)pInBuf, pBMInfo) <= 0) break; // The first 2 bytes are the width & height of the icon in pixels, // the remaining bytes are BGRA32 (B in first byte, A in last) uint8_t* outPtr = pOutBuf; *outPtr++ = (uint8_t)cxOut; *outPtr++ = (uint8_t)cyOut; // convert the color bitmap pBMInfo->cbImage = cbInBuf; ConvertColorBitMap(pInBuf, pBMInfo, outPtr, fShrink); // now we need to tack on the alpha data, so jump back to the first // pixel in the output buffer outPtr = pOutBuf+2; // Get the mask info BMHeader.cbFix = sizeof(BMHeader); if (!GpiQueryBitmapInfoHeader(IconInfo.hbmPointer, &BMHeader)) break; // if the existing input buffer isn't large enough, reallocate it cbInRow = ALIGNEDBPR(BMHeader.cx, BMHeader.cBitCount); if ((cbInRow * BMHeader.cy) > cbInBuf) // Need more for mask { cbInBuf = cbInRow * BMHeader.cy; nsMemory::Free(pInBuf); pInBuf = (uint8_t*)nsMemory::Alloc(cbInBuf); memset(pInBuf, 0, cbInBuf); } // get the mask/alpha bits memset(pBMInfo, 0, cbBMInfo); *((PBITMAPINFOHEADER2)pBMInfo) = BMHeader; GpiSetBitmap(hps, IconInfo.hbmPointer); if (GpiQueryBitmapBits(hps, 0L, (LONG)BMHeader.cy, (BYTE*)pInBuf, pBMInfo) <= 0) break; // convert the mask/alpha bitmap pBMInfo->cbImage = cbInBuf; ConvertMaskBitMap(pInBuf, pBMInfo, outPtr, fShrink); // create a pipe nsCOMPtr<nsIInputStream> inStream; nsCOMPtr<nsIOutputStream> outStream; rv = NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream), cbOutBuf, cbOutBuf, nonBlocking); if (NS_FAILED(rv)) break; // put our data into the pipe uint32_t written; rv = outStream->Write(reinterpret_cast<const char*>(pOutBuf), cbOutBuf, &written); if (NS_FAILED(rv)) break; // success! so addref the pipe NS_ADDREF(*_retval = inStream); } while (0); // free all the resources we allocated if (pOutBuf) nsMemory::Free(pOutBuf); if (pInBuf) nsMemory::Free(pInBuf); if (pBMInfo) nsMemory::Free(pBMInfo); if (hps) { GpiAssociate(hps, NULLHANDLE); GpiDestroyPS(hps); } if (hdc) DevCloseDC(hdc); if (hIcon) DestroyIcon(hIcon, fWpsIcon); return rv; }
XBitmap XBitmap::operator = (const XBitmap & b) { /**** BITMAPINFOHEADER2 * head; head = (BITMAPINFOHEADER2 *) malloc( sizeof(BITMAPINFOHEADER2)); owner = b.owner; if (owner && hps == 0) hps = WinGetPS(owner->GetHandle()); if (hbm != 0) GpiDeleteBitmap(hbm); head->cbFix = sizeof(BITMAPINFOHEADER2); GpiSetBitmap(b.hps, b.hbm); if( GpiQueryBitmapInfoHeader(b.hbm, head) == FALSE) OOLThrow("error copying bitmap", 3); LONG offBits = sizeof(BITMAPINFO2) + (sizeof(RGB2) * (1 << head->cBitCount)); LONG size = (((head->cBitCount * head->cx) + 31) / 32) * 4 * head->cPlanes * head->cy; head = (BITMAPINFOHEADER2 *) realloc(head, offBits); void * buffer = malloc(size); if( GpiQueryBitmapBits(b.hps, 0, head->cy, (PBYTE) buffer, (BITMAPINFO2 *) head) == GPI_ALTERROR) OOLThrow("error query bitmap data", 3); // hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) &p->bmp, CBM_INIT, (PBYTE) p + p->offBits, (PBITMAPINFO2) &p->bmp); hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) head, CBM_INIT, (PBYTE) buffer, (PBITMAPINFO2) head); if(hbm == 0) XProcess::Beep(300,300); GpiSetBitmap(hps, hbm); XSize s; b.GetDimensions(&s); cx = s.GetWidth(); cy = s.GetHeight(); width = b.width; height = b.height; p = b.p; free(head); free(buffer); return *this; ****/ BITMAPFILEHEADER2 * head; owner = b.owner; if (owner && hps == 0) hps = WinGetPS(owner->GetHandle()); if (hbm != 0) GpiDeleteBitmap(hbm); head = (BITMAPFILEHEADER2 *) malloc(sizeof(BITMAPFILEHEADER2)); head->bmp2.cbFix = sizeof(BITMAPINFOHEADER2); GpiQueryBitmapInfoHeader(b.hbm, &head->bmp2); head->offBits = sizeof(BITMAPFILEHEADER2) + (sizeof(RGB2) * (1 << head->bmp2.cBitCount)); LONG size = head->offBits + (((head->bmp2.cBitCount * head->bmp2.cx) + 31) / 32) * 4 * head->bmp2.cPlanes * head->bmp2.cy; head = (BITMAPFILEHEADER2 *) realloc(head, size); head->usType = BFT_BMAP; head->xHotspot = head->yHotspot = 0; head->cbSize = sizeof(BITMAPFILEHEADER2); GpiSetBitmap(hps, b.hbm); /*** head->bmp2.cbFix=16; head->bmp2.cPlanes =1; head->bmp2.cBitCount = 1; ****/ GpiQueryBitmapBits(hps, 0, head->bmp2.cy, (PBYTE) head + head->offBits, (BITMAPINFO2 *) &head->bmp2); hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) &head->bmp2, CBM_INIT, (PBYTE) head + head->offBits, (PBITMAPINFO2) &head->bmp2); GpiSetBitmap(hps, hbm); XSize s; b.GetDimensions(&s); cx = s.GetWidth(); cy = s.GetHeight(); width = b.width; height = b.height; p = b.p; free(head); return *this; }
static void _cairo_os2_surface_get_pixels_from_screen (cairo_os2_surface_t *surface, HPS hps_begin_paint, PRECTL prcl_begin_paint_rect) { HPS hps; HDC hdc; SIZEL sizlTemp; HBITMAP hbmpTemp; BITMAPINFO2 bmi2Temp; POINTL aptlPoints[4]; int y; unsigned char *pchTemp; /* To copy pixels from screen to our buffer, we do the following steps: * * - Blit pixels from screen to a HBITMAP: * -- Create Memory Device Context * -- Create a PS into it * -- Create a HBITMAP * -- Select HBITMAP into memory PS * -- Blit dirty pixels from screen to HBITMAP * - Copy HBITMAP lines (pixels) into our buffer * - Free resources */ /* Create a memory device context */ hdc = DevOpenDC (0, OD_MEMORY,"*",0L, NULL, NULLHANDLE); if (!hdc) { return; } /* Create a memory PS */ sizlTemp.cx = prcl_begin_paint_rect->xRight - prcl_begin_paint_rect->xLeft; sizlTemp.cy = prcl_begin_paint_rect->yTop - prcl_begin_paint_rect->yBottom; hps = GpiCreatePS (0, hdc, &sizlTemp, PU_PELS | GPIT_NORMAL | GPIA_ASSOC); if (!hps) { DevCloseDC (hdc); return; } /* Create an uninitialized bitmap. */ /* Prepare BITMAPINFO2 structure for our buffer */ memset (&bmi2Temp, 0, sizeof (bmi2Temp)); bmi2Temp.cbFix = sizeof (BITMAPINFOHEADER2); bmi2Temp.cx = sizlTemp.cx; bmi2Temp.cy = sizlTemp.cy; bmi2Temp.cPlanes = 1; bmi2Temp.cBitCount = 32; hbmpTemp = GpiCreateBitmap (hps, (PBITMAPINFOHEADER2) &bmi2Temp, 0, NULL, NULL); if (!hbmpTemp) { GpiDestroyPS (hps); DevCloseDC (hdc); return; } /* Select the bitmap into the memory device context. */ GpiSetBitmap (hps, hbmpTemp); /* Target coordinates (Noninclusive) */ aptlPoints[0].x = 0; aptlPoints[0].y = 0; aptlPoints[1].x = sizlTemp.cx; aptlPoints[1].y = sizlTemp.cy; /* Source coordinates (Inclusive) */ aptlPoints[2].x = prcl_begin_paint_rect->xLeft; aptlPoints[2].y = surface->bitmap_info.cy - prcl_begin_paint_rect->yBottom; aptlPoints[3].x = prcl_begin_paint_rect->xRight; aptlPoints[3].y = surface->bitmap_info.cy - prcl_begin_paint_rect->yTop; /* Blit pixels from screen to bitmap */ GpiBitBlt (hps, hps_begin_paint, 4, aptlPoints, ROP_SRCCOPY, BBO_IGNORE); /* Now we have to extract the pixels from the bitmap. */ pchTemp = surface->pixels + (prcl_begin_paint_rect->yBottom)*surface->bitmap_info.cx*4 + prcl_begin_paint_rect->xLeft*4; for (y = 0; y < sizlTemp.cy; y++) { /* Get one line of pixels */ GpiQueryBitmapBits (hps, sizlTemp.cy - y - 1, /* lScanStart */ 1, /* lScans */ (PBYTE)pchTemp, &bmi2Temp); /* Go for next line */ pchTemp += surface->bitmap_info.cx*4; } /* Clean up resources */ GpiSetBitmap (hps, (HBITMAP) NULL); GpiDeleteBitmap (hbmpTemp); GpiDestroyPS (hps); DevCloseDC (hdc); }
// static QPixmap QPixmap::fromPmHBITMAP(HBITMAP hbm, HBITMAP hbmMask) { QPixmap res; if (hbm == NULLHANDLE) return res; // bitmap header + 2 palette entries (for the monochrome bitmap) char bmi[sizeof(BITMAPINFOHEADER2) + 4 * 2]; memset(bmi, 0, sizeof(bmi)); PBITMAPINFOHEADER2 bmh = (PBITMAPINFOHEADER2)bmi; bmh->cbFix = sizeof(BITMAPINFOHEADER2); PULONG pal = (PULONG)(bmi + sizeof(BITMAPINFOHEADER2)); if (!GpiQueryBitmapInfoHeader(hbm, bmh)) return res; HPS hps = qt_alloc_mem_ps(bmh->cx, bmh->cy * 2); if (hps == NULLHANDLE) return res; GpiSetBitmap(hps, hbm); QImage img; bool succeeded = false; if (bmh->cPlanes == 1 && bmh->cBitCount == 1) { // monochrome bitmap img = QImage(bmh->cx, bmh->cy, QImage::Format_Mono); if (GpiQueryBitmapBits(hps, 0, img.height(), (PBYTE)img.bits(), (PBITMAPINFO2)&bmi) != GPI_ALTERROR) { succeeded = true; // take the palette QVector<QRgb> colors(2); colors[0] = QRgb(pal[0]); colors[1] = QRgb(pal[1]); img.setColorTable(colors); } } else { // always convert to 32-bit otherwise img = QImage(bmh->cx, bmh->cy, QImage::Format_RGB32); bmh->cPlanes = 1; bmh->cBitCount = 32; if (GpiQueryBitmapBits(hps, 0, img.height(), (PBYTE)img.bits(), (PBITMAPINFO2)&bmi) != GPI_ALTERROR) { succeeded = true; // try to auto-detect if there is a real alpha channel bool allZero = true; for (int i = 0; i < img.numBytes(); ++i) { if (img.bits()[i] & 0xFF000000) { allZero = false; break; } } if (!allZero) { // assume we've got the alpha channel QImage alphaImg = QImage(bmh->cx, bmh->cy, QImage::Format_ARGB32); memcpy(alphaImg.bits(), img.bits(), img.numBytes()); img = alphaImg; } // flip the bitmap top to bottom to cancel PM inversion img = img.mirrored(); } } QImage mask; if (hbmMask != NULLHANDLE && GpiQueryBitmapInfoHeader(hbmMask, bmh)) { // get the AND+XOR mask if ((int)bmh->cx == img.width() && (int)bmh->cy == img.height() * 2 && bmh->cPlanes == 1 && bmh->cBitCount == 1) { GpiSetBitmap(hps, hbmMask); mask = QImage(bmh->cx, bmh->cy, QImage::Format_Mono); if (GpiQueryBitmapBits(hps, 0, mask.height(), (PBYTE)mask.bits(), (PBITMAPINFO2)&bmi) != GPI_ALTERROR) { // take the palette QVector<QRgb> colors(2); colors[0] = QRgb(pal[0]); colors[1] = QRgb(pal[1]); mask.setColorTable(colors); // flip the bitmap top to bottom to cancel PM inversion mask = mask.mirrored(false, true); // drop the XOR mask mask = mask.copy(0, 0, mask.width(), mask.height() / 2); // create a normal mask from the AND mask mask.invertPixels(); } else { mask = QImage(); } GpiSetBitmap(hps, NULLHANDLE); } else { Q_ASSERT(false); } } qt_free_mem_ps(hps); if (succeeded) { res = QPixmap::fromImage(img); if (!mask.isNull()) res.setMask(QBitmap::fromImage(mask)); } return res; }
/* * writeImageBits - writes the bits for the image */ static bool writeImageBits( FILE *fp, img_node *node ) { WPI_PRES pres; WPI_PRES mempres; HDC memdc; ULONG byte_count; img_node *new_image; BITMAPINFO2 *bmi; HBITMAP oldbitmap; HBITMAP inverse_bitmap; HBITMAP clr_bitmap; BYTE *buffer; bool ok; ok = true; pres = _wpi_getpres( HWND_DESKTOP ); mempres = _wpi_createcompatiblepres( pres, Instance, &memdc ); _wpi_releasepres( HWND_DESKTOP, pres ); for( new_image = node; new_image != NULL; new_image = new_image->nexticon ) { bmi = GetAndBitmapInfo(new_image); if( bmi == NULL ) { ok = false; break; } /* * first we write the PM XOR mask (inverse mask) then the PM AND * mask (and mask) and then the PM colour mask (xor mask). */ byte_count = BITS_TO_BYTES( new_image->width, new_image->height ); buffer = MemAlloc( byte_count ); inverse_bitmap = CreateInverseBitmap( new_image->handbitmap, new_image->hxorbitmap ); oldbitmap = _wpi_selectobject( mempres, inverse_bitmap ); GpiQueryBitmapBits( mempres, 0, new_image->height, buffer, bmi ); fwrite( buffer, sizeof( BYTE ), byte_count, fp ); _wpi_selectobject( mempres, oldbitmap ); _wpi_deletebitmap( inverse_bitmap ); oldbitmap = _wpi_selectobject( mempres, new_image->handbitmap ); GpiQueryBitmapBits( mempres, 0, new_image->height, buffer, bmi ); fwrite( buffer, sizeof( BYTE ), byte_count, fp ); _wpi_selectobject( mempres, oldbitmap ); MemFree( buffer ); FreeDIBitmapInfo( bmi ); bmi = GetXorBitmapInfo( new_image ); if( bmi == NULL ) { ok = false; break; } clr_bitmap = CreateColourBitmap( new_image->handbitmap, new_image->hxorbitmap ); oldbitmap = _wpi_selectobject( mempres, clr_bitmap ); byte_count = BITS_TO_BYTES( new_image->width * new_image->bitcount, new_image->height ); buffer = MemAlloc( byte_count ); GpiQueryBitmapBits( mempres, 0, node->height, buffer, bmi ); fwrite( buffer, sizeof( BYTE ), byte_count, fp ); MemFree( buffer ); FreeDIBitmapInfo( bmi ); _wpi_selectobject( mempres, oldbitmap ); _wpi_deletebitmap( clr_bitmap ); } _wpi_deletecompatiblepres( mempres, memdc ); return( ok ); } /* writeImageBits */