ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

static int serializeIcon ( HICON  hIcon,
void **  ppBuffer,
unsigned int pLength 
) [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;
}

Generated on Wed May 23 2012 05:13:56 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.