Esempio n. 1
0
/*
 * 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 */
Esempio n. 2
0
/*
 * 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 */
Esempio n. 3
0
/*
 * 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);
}
Esempio n. 8
0
// 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;
}
Esempio n. 9
0
/*
 * 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 */