Home | Info | Community | Development | myReactOS | Contact Us
[static]
Definition at line 1570 of file olepicture.c.
Referenced by OLEPictureImpl_Save().
{ ICONINFO infoIcon; int iSuccess = 0; *ppBuffer = NULL; *pLength = 0; if (GetIconInfo(hIcon, &infoIcon)) { HDC hDC; BITMAPINFO * pInfoBitmap; unsigned char * pIconData = NULL; unsigned int iDataSize = 0; pInfoBitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); /* Find out icon size */ hDC = GetDC(0); pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader); GetDIBits(hDC, infoIcon.hbmColor, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS); if (1) { /* Auxiliary pointers */ CURSORICONFILEDIR * pIconDir; CURSORICONFILEDIRENTRY * pIconEntry; BITMAPINFOHEADER * pIconBitmapHeader; unsigned int iOffsetPalette; unsigned int iOffsetColorData; unsigned int iOffsetMaskData; unsigned int iLengthScanLineMask; unsigned int iNumEntriesPalette; iLengthScanLineMask = ((pInfoBitmap->bmiHeader.biWidth + 31) >> 5) << 2; /* FIXME("DEBUG: bitmap size is %d x %d\n", pInfoBitmap->bmiHeader.biWidth, pInfoBitmap->bmiHeader.biHeight); FIXME("DEBUG: bitmap bpp is %d\n", pInfoBitmap->bmiHeader.biBitCount); FIXME("DEBUG: bitmap nplanes is %d\n", pInfoBitmap->bmiHeader.biPlanes); FIXME("DEBUG: bitmap biSizeImage is %u\n", pInfoBitmap->bmiHeader.biSizeImage); */ /* Let's start with one CURSORICONFILEDIR and one CURSORICONFILEDIRENTRY */ iDataSize += 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY) + sizeof(BITMAPINFOHEADER); pIconData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, iDataSize); /* Fill out the CURSORICONFILEDIR */ pIconDir = (CURSORICONFILEDIR *)pIconData; pIconDir->idType = 1; pIconDir->idCount = 1; /* Fill out the CURSORICONFILEDIRENTRY */ pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD)); pIconEntry->bWidth = (unsigned char)pInfoBitmap->bmiHeader.biWidth; pIconEntry->bHeight = (unsigned char)pInfoBitmap->bmiHeader.biHeight; pIconEntry->bColorCount = (pInfoBitmap->bmiHeader.biBitCount < 8) ? 1 << pInfoBitmap->bmiHeader.biBitCount : 0; pIconEntry->xHotspot = pInfoBitmap->bmiHeader.biPlanes; pIconEntry->yHotspot = pInfoBitmap->bmiHeader.biBitCount; pIconEntry->dwDIBSize = 0; pIconEntry->dwDIBOffset = 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY); /* Fill out the BITMAPINFOHEADER */ pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY)); *pIconBitmapHeader = pInfoBitmap->bmiHeader; /* Find out whether a palette exists for the bitmap */ if ( (pInfoBitmap->bmiHeader.biBitCount == 16 && pInfoBitmap->bmiHeader.biCompression == BI_RGB) || (pInfoBitmap->bmiHeader.biBitCount == 24) || (pInfoBitmap->bmiHeader.biBitCount == 32 && pInfoBitmap->bmiHeader.biCompression == BI_RGB)) { iNumEntriesPalette = pInfoBitmap->bmiHeader.biClrUsed; if (iNumEntriesPalette > 256) iNumEntriesPalette = 256; } else if ((pInfoBitmap->bmiHeader.biBitCount == 16 || pInfoBitmap->bmiHeader.biBitCount == 32) && pInfoBitmap->bmiHeader.biCompression == BI_BITFIELDS) { iNumEntriesPalette = 3; } else if (pInfoBitmap->bmiHeader.biBitCount <= 8) { iNumEntriesPalette = 1 << pInfoBitmap->bmiHeader.biBitCount; } else { iNumEntriesPalette = 0; } /* Add bitmap size and header size to icon data size. */ iOffsetPalette = iDataSize; iDataSize += iNumEntriesPalette * sizeof(DWORD); iOffsetColorData = iDataSize; iDataSize += pIconBitmapHeader->biSizeImage; iOffsetMaskData = iDataSize; iDataSize += pIconBitmapHeader->biHeight * iLengthScanLineMask; pIconBitmapHeader->biSizeImage += pIconBitmapHeader->biHeight * iLengthScanLineMask; pIconBitmapHeader->biHeight *= 2; pIconData = HeapReAlloc(GetProcessHeap(), 0, pIconData, iDataSize); pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD)); pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY)); pIconEntry->dwDIBSize = iDataSize - (3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY)); /* Get the actual bitmap data from the icon bitmap */ GetDIBits(hDC, infoIcon.hbmColor, 0, pInfoBitmap->bmiHeader.biHeight, pIconData + iOffsetColorData, pInfoBitmap, DIB_RGB_COLORS); if (iNumEntriesPalette > 0) { memcpy(pIconData + iOffsetPalette, pInfoBitmap->bmiColors, iNumEntriesPalette * sizeof(RGBQUAD)); } /* Reset all values so that GetDIBits call succeeds */ memset(pIconData + iOffsetMaskData, 0, iDataSize - iOffsetMaskData); memset(pInfoBitmap, 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader); /* if (!(GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS) && GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight, pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS))) { printf("ERROR: unable to get bitmap mask (error %u)\n", GetLastError()); } */ GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS); GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight, pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS); /* Write out everything produced so far to the stream */ *ppBuffer = pIconData; *pLength = iDataSize; iSuccess = 1; } else { /* printf("ERROR: unable to get bitmap information via GetDIBits() (error %u)\n", GetLastError()); */ } /* Remarks (from MSDN entry on GetIconInfo): GetIconInfo creates bitmaps for the hbmMask and hbmColor members of ICONINFO. The calling application must manage these bitmaps and delete them when they are no longer necessary. */ if (hDC) ReleaseDC(0, hDC); DeleteObject(infoIcon.hbmMask); if (infoIcon.hbmColor) DeleteObject(infoIcon.hbmColor); HeapFree(GetProcessHeap(), 0, pInfoBitmap); } else { printf("ERROR: Unable to get icon information (error %u)\n", GetLastError()); } return iSuccess; }