Annotation of mstools/samples/showdib/dib.c, revision 1.1.1.1

1.1       root        1: /*******************************************************************************
                      2:  *                                                                            *
                      3:  *  MODULE     : DIB.C                                                        *
                      4:  *                                                                            *
                      5:  *  DESCRIPTION : Routines for dealing with Device Independent Bitmaps.        *
                      6:  *                                                                            *
                      7:  *  FUNCTIONS  : OpenDIB()           - Opens DIB file and creates a memory DIB*
                      8:  *                                                                            *
                      9:  *               WriteDIB()          - Writes a global handle in CF_DIB format*
                     10:  *                                     to a file.                             *
                     11:  *                                                                            *
                     12:  *               DibInfo()           - Retrieves the info. block associated   *
                     13:  *                                     with a CF_DIB format memory block.     *
                     14:  *                                                                            *
                     15:  *               CreateBIPalette()   - Creates a GDI palette given a pointer  *
                     16:  *                                     to a BITMAPINFO structure.             *
                     17:  *                                                                            *
                     18:  *               CreateDibPalette()  - Creates a GDI palette given a HANDLE   *
                     19:  *                                     to a BITMAPINFO structure.             *
                     20:  *                                                                            *
                     21:  *               ReadDibBitmapInfo() - Reads a file in DIB format and returns *
                     22:  *                                     a global handle to it's BITMAPINFO     *
                     23:  *                                                                            *
                     24:  *               PaletteSize()       - Calculates the palette size in bytes   *
                     25:  *                                     of given DIB                           *
                     26:  *                                                                            *
                     27:  *               DibNumColors()      - Determines the number of colors in DIB *
                     28:  *                                                                            *
                     29:  *               BitmapFromDib()     - Creates a DDB given a global handle to *
                     30:  *                                     a block in CF_DIB format.              *
                     31:  *                                                                            *
                     32:  *               DibFromBitmap()     - Creates a DIB repr. the DDB passed in. *
                     33:  *                                                                            *
                     34:  *               DrawBitmap()        - Draws a bitmap at specified position   *
                     35:  *                                     in the DC.                             *
                     36:  *                                                                            *
                     37:  *               DibBlt()            - Draws a bitmap in CIF_DIB format using *
                     38:  *                                     SetDIBitsToDevice()                    *
                     39:  *                                                                            *
                     40:  *               StretchDibBlt()     - Draws a bitmap in CIF_DIB format using *
                     41:  *                                     StretchDIBits()                        *
                     42:  *                                                                            *
                     43:  *               lread()             - Private routine to read more than 64k  *
                     44:  *                                                                            *
                     45:  *               lwrite()            - Private routine to write more than 64k *
                     46:  *                                                                            *
                     47:  *******************************************************************************/
                     48: 
                     49: #include <windows.h>
                     50: #include "showdib.h"
                     51: static  HCURSOR hcurSave;
                     52: 
                     53: /****************************************************************************
                     54:  *                                                                         *
                     55:  *  FUNCTION   :OpenDIB(LPSTR szFile)                                      *
                     56:  *                                                                         *
                     57:  *  PURPOSE    :Open a DIB file and create a MEMORY DIB, a memory handle    *
                     58:  *             containing BITMAPINFO, palette data and the bits.           *
                     59:  *                                                                         *
                     60:  *  RETURNS    :A handle to the DIB.                                       *
                     61:  *                                                                         *
                     62:  ****************************************************************************/
                     63: HANDLE OpenDIB (LPSTR szFile)
                     64: {
                     65:     HFILE              fh;
                     66:     BITMAPINFOHEADER   bi;
                     67:     LPBITMAPINFOHEADER  lpbi;
                     68:     DWORD              dwLen = 0;
                     69:     DWORD              dwBits;
                     70:     HANDLE             hdib;
                     71:     HANDLE              h;
                     72:     OFSTRUCT           of;
                     73: 
                     74:     /* Open the file and read the DIB information */
                     75:     fh = OpenFile(szFile, &of, (UINT)OF_READ);
                     76:     if (fh == -1)
                     77:        return NULL;
                     78: 
                     79:     hdib = ReadDibBitmapInfo(fh);
                     80:     if (!hdib)
                     81:        return NULL;
                     82:     DibInfo(hdib,&bi);
                     83: 
                     84:     /* Calculate the memory needed to hold the DIB */
                     85:     dwBits = bi.biSizeImage;
                     86:     dwLen  = bi.biSize + (DWORD)PaletteSize (&bi) + dwBits;
                     87: 
                     88:     /* Try to increase the size of the bitmap info. buffer to hold the DIB */
                     89:     h = GlobalReAlloc(hdib, dwLen, GHND);
                     90:     if (!h){
                     91:        GlobalFree(hdib);
                     92:        hdib = NULL;
                     93:     }
                     94:     else
                     95:        hdib = h;
                     96: 
                     97:     /* Read in the bits */
                     98:     if (hdib){
                     99: 
                    100:         lpbi = (VOID FAR *)GlobalLock(hdib);
                    101:        lread(fh, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi), dwBits);
                    102:        GlobalUnlock(hdib);
                    103:     }
                    104:     _lclose(fh);
                    105: 
                    106:     return hdib;
                    107: }
                    108: 
                    109: /****************************************************************************
                    110:  *                                                                         *
                    111:  *  FUNCTION   : WriteDIB(LPSTR szFile,HANDLE hdib)                        *
                    112:  *                                                                         *
                    113:  *  PURPOSE    : Write a global handle in CF_DIB format to a file.         *
                    114:  *                                                                         *
                    115:  *  RETURNS    : TRUE  - if successful.                                    *
                    116:  *              FALSE - otherwise                                          *
                    117:  *                                                                         *
                    118:  ****************************************************************************/
                    119: BOOL WriteDIB (
                    120:     LPSTR szFile,
                    121:     HANDLE hdib)
                    122: {
                    123:     BITMAPFILEHEADER   hdr;
                    124:     LPBITMAPINFOHEADER  lpbi;
                    125:     HFILE               fh;
                    126:     OFSTRUCT            of;
                    127: 
                    128:     if (!hdib)
                    129:        return FALSE;
                    130: 
                    131:     fh = OpenFile(szFile, &of, (UINT)OF_CREATE|OF_READWRITE);
                    132:     if (fh == -1)
                    133:        return FALSE;
                    134: 
                    135:     lpbi = (VOID FAR *)GlobalLock (hdib);
                    136: 
                    137:     /* Fill in the fields of the file header */
                    138:     hdr.bfType         = BFT_BITMAP;
                    139:     hdr.bfSize         = GlobalSize (hdib) + SIZEOF_BITMAPFILEHEADER_PACKED;
                    140:     hdr.bfReserved1     = 0;
                    141:     hdr.bfReserved2     = 0;
                    142:     hdr.bfOffBits       = (DWORD) (SIZEOF_BITMAPFILEHEADER_PACKED + lpbi->biSize +
                    143:                           PaletteSize(lpbi));
                    144: 
                    145:     /* Write the file header */
                    146: #ifdef         FIXDWORDALIGNMENT
                    147:     _lwrite(fh, (LPSTR)&hdr, (UINT)(SIZEOF_BITMAPFILEHEADER_PACKED));
                    148: #else
                    149:        WriteMapFileHeaderandConvertFromDwordAlignToPacked(fh, &hdr);
                    150: #endif
                    151: 
                    152:        /* this struct already DWORD aligned!*/
                    153:     /* Write the DIB header and the bits */
                    154:     lwrite (fh, (LPSTR)lpbi, GlobalSize (hdib));
                    155: 
                    156:     GlobalUnlock (hdib);
                    157:     _lclose(fh);
                    158:     return TRUE;
                    159: }
                    160: 
                    161: /****************************************************************************
                    162:  *                                                                         *
                    163:  *  FUNCTION   : DibInfo(HANDLE hbi,LPBITMAPINFOHEADER lpbi)               *
                    164:  *                                                                         *
                    165:  *  PURPOSE    : Retrieves the DIB info associated with a CF_DIB           *
                    166:  *              format memory block.                                       *
                    167:  *                                                                         *
                    168:  *  RETURNS    : TRUE  - if successful.                                    *
                    169:  *              FALSE - otherwise                                          *
                    170:  *                                                                         *
                    171:  ****************************************************************************/
                    172: BOOL DibInfo (
                    173:     HANDLE hbi,
                    174:     LPBITMAPINFOHEADER lpbi)
                    175: {
                    176:     if (hbi){
                    177:        *lpbi = *(LPBITMAPINFOHEADER)GlobalLock (hbi);
                    178: 
                    179:        /* fill in the default fields */
                    180:        if (lpbi->biSize != sizeof (BITMAPCOREHEADER)){
                    181:             if (lpbi->biSizeImage == 0L)
                    182:                                lpbi->biSizeImage = WIDTHBYTES(lpbi->biWidth*lpbi->biBitCount) * lpbi->biHeight;
                    183: 
                    184:             if (lpbi->biClrUsed == 0L)
                    185:                                lpbi->biClrUsed = DibNumColors (lpbi);
                    186:     }
                    187:        GlobalUnlock (hbi);
                    188:        return TRUE;
                    189:     }
                    190:     return FALSE;
                    191: }
                    192: 
                    193: /****************************************************************************
                    194:  *                                                                         *
                    195:  *  FUNCTION   : CreateBIPalette(LPBITMAPINFOHEADER lpbi)                  *
                    196:  *                                                                         *
                    197:  *  PURPOSE    : Given a Pointer to a BITMAPINFO struct will create a      *
                    198:  *              a GDI palette object from the color table.                 *
                    199:  *                                                                         *
                    200:  *  RETURNS    : A handle to the palette.                                  *
                    201:  *                                                                         *
                    202:  ****************************************************************************/
                    203: HPALETTE CreateBIPalette (LPBITMAPINFOHEADER lpbi)
                    204: {
                    205:     LOGPALETTE          *pPal;
                    206:     HPALETTE            hpal = NULL;
                    207:     WORD                nNumColors;
                    208:     BYTE                red;
                    209:     BYTE                green;
                    210:     BYTE                blue;
                    211:     WORD                i;
                    212:     RGBQUAD        FAR *pRgb;
                    213: 
                    214:     if (!lpbi)
                    215:        return NULL;
                    216: 
                    217:     if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
                    218:        return NULL;
                    219: 
                    220:     /* Get a pointer to the color table and the number of colors in it */
                    221:     pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
                    222:     nNumColors = DibNumColors(lpbi);
                    223: 
                    224:     if (nNumColors){
                    225:        /* Allocate for the logical palette structure */
                    226:         pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
                    227:        if (!pPal)
                    228:            return NULL;
                    229: 
                    230:         pPal->palNumEntries = nNumColors;
                    231:        pPal->palVersion    = PALVERSION;
                    232: 
                    233:        /* Fill in the palette entries from the DIB color table and
                    234:         * create a logical color palette.
                    235:         */
                    236:        for (i = 0; i < nNumColors; i++){
                    237:             pPal->palPalEntry[i].peRed   = pRgb[i].rgbRed;
                    238:             pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
                    239:             pPal->palPalEntry[i].peBlue  = pRgb[i].rgbBlue;
                    240:             pPal->palPalEntry[i].peFlags = (BYTE)0;
                    241:         }
                    242:         hpal = CreatePalette(pPal);
                    243:         LocalFree((HANDLE)pPal);
                    244:     }
                    245:     else if (lpbi->biBitCount == 24){
                    246:        /* A 24 bitcount DIB has no color table entries so, set the number of
                    247:         * to the maximum value (256).
                    248:         */
                    249:        nNumColors = MAXPALETTE;
                    250:         pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
                    251:         if (!pPal)
                    252:            return NULL;
                    253: 
                    254:        pPal->palNumEntries = nNumColors;
                    255:        pPal->palVersion    = PALVERSION;
                    256: 
                    257:        red = green = blue = 0;
                    258: 
                    259:        /* Generate 256 (= 8*8*4) RGB combinations to fill the palette
                    260:         * entries.
                    261:         */
                    262:        for (i = 0; i < pPal->palNumEntries; i++){
                    263:             pPal->palPalEntry[i].peRed   = red;
                    264:             pPal->palPalEntry[i].peGreen = green;
                    265:             pPal->palPalEntry[i].peBlue  = blue;
                    266:             pPal->palPalEntry[i].peFlags = (BYTE)0;
                    267: 
                    268:            if (!(red += 32))
                    269:                if (!(green += 32))
                    270:                    blue += 64;
                    271:         }
                    272:         hpal = CreatePalette(pPal);
                    273:         LocalFree((HANDLE)pPal);
                    274:     }
                    275:     return hpal;
                    276: }
                    277: 
                    278: /****************************************************************************
                    279:  *                                                                         *
                    280:  *  FUNCTION   : CreateDibPalette(HANDLE hbi)                              *
                    281:  *                                                                         *
                    282:  *  PURPOSE    : Given a Global HANDLE to a BITMAPINFO Struct              *
                    283:  *              will create a GDI palette object from the color table.     *
                    284:  *              (BITMAPINFOHEADER format DIBs only)                                     *
                    285:  *                                                                         *
                    286:  *  RETURNS    : A handle to the palette.                                  *
                    287:  *                                                                         *
                    288:  ****************************************************************************/
                    289: HPALETTE CreateDibPalette (HANDLE hbi)
                    290: {
                    291:     HPALETTE hpal;
                    292: 
                    293:     if (!hbi)
                    294:        return NULL;
                    295:     hpal = CreateBIPalette((LPBITMAPINFOHEADER)GlobalLock(hbi));
                    296:     GlobalUnlock(hbi);
                    297:     return hpal;
                    298: }
                    299: 
                    300: /****************************************************************************
                    301:  *                                                                         *
                    302:  *  FUNCTION   : ReadDibBitmapInfo(int fh)                                 *
                    303:  *                                                                         *
                    304:  *  PURPOSE    : Will read a file in DIB format and return a global HANDLE  *
                    305:  *              to it's BITMAPINFO.  This function will work with both     *
                    306:  *              "old" (BITMAPCOREHEADER) and "new" (BITMAPINFOHEADER)      *
                    307:  *              bitmap formats, but will always return a "new" BITMAPINFO  *
                    308:  *                                                                         *
                    309:  *  RETURNS    : A handle to the BITMAPINFO of the DIB in the file.        *
                    310:  *                                                                         *
                    311:  ****************************************************************************/
                    312: HANDLE ReadDibBitmapInfo (INT fh)
                    313: {
                    314:     DWORD     off;
                    315:     HANDLE    hbi = NULL;
                    316:     INT       size;
                    317:     INT       i;
                    318:     WORD      nNumColors;
                    319: 
                    320:     RGBQUAD FAR       *pRgb;
                    321:     BITMAPINFOHEADER   bi;
                    322:     BITMAPCOREHEADER   bc;
                    323:     LPBITMAPINFOHEADER lpbi;
                    324:     BITMAPFILEHEADER   bf;
                    325:     DWORD             dwWidth = 0;
                    326:     DWORD             dwHeight = 0;
                    327:     WORD              wPlanes, wBitCount;
                    328: 
                    329:     if (fh == -1)
                    330:         return NULL;
                    331: #ifdef FIXDWORDALIGNMENT
                    332:     /* Reset file pointer and read file header */
                    333:     off = _llseek(fh, 0L, (UINT)SEEK_CUR);
                    334:     if ((SIZEOF_BITMAPFILEHEADER_PACKED)  != _lread(fh, (LPSTR)&bf, (UINT)sizeof (SIZEOF_BITMAPFILEHEADER_PACKED)))
                    335:         return FALSE;
                    336: #else
                    337:        ReadBitMapFileHeaderandConvertToDwordAlign(fh, &bf, &off);
                    338:        /* at this point we have read the file into bf*/
                    339: #endif
                    340: 
                    341:     /* Do we have a RC HEADER? */
                    342:     if (!ISDIB (bf.bfType)) {   
                    343:         bf.bfOffBits = 0L;              
                    344:                _llseek(fh, off, (UINT)SEEK_SET); /*seek back to beginning of file*/
                    345:     }
                    346:     if (sizeof (bi) != _lread(fh, (LPSTR)&bi, (UINT)sizeof(bi)))
                    347:         return FALSE;
                    348: 
                    349:     nNumColors = DibNumColors (&bi);
                    350: 
                    351:     /* Check the nature (BITMAPINFO or BITMAPCORE) of the info. block
                    352:      * and extract the field information accordingly. If a BITMAPCOREHEADER,
                    353:      * transfer it's field information to a BITMAPINFOHEADER-style block
                    354:      */
                    355:     switch (size = (INT)bi.biSize){
                    356:        case sizeof (BITMAPINFOHEADER):
                    357:             break;
                    358: 
                    359:        case sizeof (BITMAPCOREHEADER):
                    360: 
                    361:            bc = *(BITMAPCOREHEADER*)&bi;
                    362: 
                    363:            dwWidth   = (DWORD)bc.bcWidth;
                    364:            dwHeight  = (DWORD)bc.bcHeight;
                    365:            wPlanes   = bc.bcPlanes;
                    366:            wBitCount = bc.bcBitCount;
                    367: 
                    368:         bi.biSize           = sizeof(BITMAPINFOHEADER);
                    369:            bi.biWidth              = dwWidth;
                    370:            bi.biHeight             = dwHeight;
                    371:            bi.biPlanes             = wPlanes;
                    372:            bi.biBitCount           = wBitCount;
                    373: 
                    374:             bi.biCompression        = BI_RGB;
                    375:             bi.biSizeImage          = 0;
                    376:             bi.biXPelsPerMeter      = 0;
                    377:             bi.biYPelsPerMeter      = 0;
                    378:             bi.biClrUsed            = nNumColors;
                    379:             bi.biClrImportant       = nNumColors;
                    380: 
                    381:            _llseek(fh, (LONG)sizeof (BITMAPCOREHEADER) - sizeof (BITMAPINFOHEADER), (UINT)SEEK_CUR);
                    382:             break;
                    383: 
                    384:        default:
                    385:            /* Not a DIB! */
                    386:            return NULL;
                    387:     }
                    388: 
                    389:     /* Fill in some default values if they are zero */
                    390:     if (bi.biSizeImage == 0){
                    391:        bi.biSizeImage = WIDTHBYTES ((DWORD)bi.biWidth * bi.biBitCount)
                    392:                         * bi.biHeight;
                    393:     }
                    394:     if (bi.biClrUsed == 0)
                    395:        bi.biClrUsed = DibNumColors(&bi);
                    396: 
                    397:     /* Allocate for the BITMAPINFO structure and the color table. */
                    398:     hbi = GlobalAlloc (GHND, (LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
                    399:     if (!hbi)
                    400:         return NULL;
                    401:     lpbi = (VOID FAR *)GlobalLock (hbi);
                    402:     *lpbi = bi;
                    403: 
                    404:     /* Get a pointer to the color table */
                    405:     pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + bi.biSize);
                    406:     if (nNumColors){
                    407:        if (size == sizeof(BITMAPCOREHEADER)){
                    408:            /* Convert a old color table (3 byte RGBTRIPLEs) to a new
                    409:             * color table (4 byte RGBQUADs)
                    410:              */
                    411:            _lread(fh, (LPSTR)pRgb, (UINT)nNumColors * sizeof(RGBTRIPLE));
                    412: 
                    413:            for (i = nNumColors - 1; i >= 0; i--){
                    414:                 RGBQUAD rgb;
                    415: 
                    416:                 rgb.rgbRed      = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
                    417:                 rgb.rgbBlue     = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
                    418:                 rgb.rgbGreen    = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
                    419:                 rgb.rgbReserved = (BYTE)0;
                    420: 
                    421:                 pRgb[i] = rgb;
                    422:             }
                    423:         }
                    424:        else
                    425:            _lread(fh, (LPSTR)pRgb, (UINT)nNumColors * sizeof(RGBQUAD));
                    426:     }
                    427: 
                    428:     if (bf.bfOffBits != 0L){
                    429:        _llseek(fh, off + bf.bfOffBits, (UINT)SEEK_SET);
                    430:        }
                    431:     GlobalUnlock(hbi);
                    432:     return hbi;
                    433: }
                    434: 
                    435: /****************************************************************************
                    436:  *                                                                         *
                    437:  *  FUNCTION   :  PaletteSize(VOID FAR * pv)                               *
                    438:  *                                                                         *
                    439:  *  PURPOSE    :  Calculates the palette size in bytes. If the info. block  *
                    440:  *               is of the BITMAPCOREHEADER type, the number of colors is  *
                    441:  *               multiplied by 3 to give the palette size, otherwise the   *
                    442:  *               number of colors is multiplied by 4.                                                          *
                    443:  *                                                                         *
                    444:  *  RETURNS    :  Palette size in number of bytes.                         *
                    445:  *                                                                         *
                    446:  ****************************************************************************/
                    447: WORD PaletteSize (VOID FAR * pv)
                    448: {
                    449:     LPBITMAPINFOHEADER lpbi;
                    450:     WORD              NumColors;
                    451: 
                    452:     lpbi      = (LPBITMAPINFOHEADER)pv;
                    453:     NumColors = DibNumColors(lpbi);
                    454: 
                    455:     if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
                    456:         return (WORD)(NumColors * sizeof(RGBTRIPLE));
                    457:     else
                    458:         return (WORD)(NumColors * sizeof(RGBQUAD));
                    459: }
                    460: 
                    461: /****************************************************************************
                    462:  *                                                                         *
                    463:  *  FUNCTION   : DibNumColors(VOID FAR * pv)                               *
                    464:  *                                                                         *
                    465:  *  PURPOSE    : Determines the number of colors in the DIB by looking at   *
                    466:  *              the BitCount filed in the info block.                      *
                    467:  *                                                                         *
                    468:  *  RETURNS    : The number of colors in the DIB.                          *
                    469:  *                                                                         *
                    470:  ****************************************************************************/
                    471: WORD DibNumColors (VOID FAR * pv)
                    472: {
                    473:     INT                bits;
                    474:     LPBITMAPINFOHEADER lpbi;
                    475:     LPBITMAPCOREHEADER lpbc;
                    476: 
                    477:     lpbi = ((LPBITMAPINFOHEADER)pv);
                    478:     lpbc = ((LPBITMAPCOREHEADER)pv);
                    479: 
                    480:     /* With the BITMAPINFO format headers, the size of the palette
                    481:      * is in biClrUsed, whereas in the BITMAPCORE - style headers, it
                    482:      * is dependent on the bits per pixel ( = 2 raised to the power of
                    483:      * bits/pixel).
                    484:      */
                    485:     if (lpbi->biSize != sizeof(BITMAPCOREHEADER)){
                    486:         if (lpbi->biClrUsed != 0)
                    487:             return (WORD)lpbi->biClrUsed;
                    488:         bits = lpbi->biBitCount;
                    489:     }
                    490:     else
                    491:         bits = lpbc->bcBitCount;
                    492: 
                    493:     switch (bits){
                    494:        case 1:
                    495:                return 2;
                    496:        case 4:
                    497:                return 16;
                    498:        case 8:
                    499:                return 256;
                    500:        default:
                    501:                /* A 24 bitcount DIB has no color table */
                    502:                return 0;
                    503:     }
                    504: }
                    505: /****************************************************************************
                    506:  *                                                                         *
                    507:  *  FUNCTION   : DibFromBitmap()                                           *
                    508:  *                                                                         *
                    509:  *  PURPOSE    : Will create a global memory block in DIB format that      *
                    510:  *              represents the Device-dependent bitmap (DDB) passed in.    *
                    511:  *                                                                         *
                    512:  *  RETURNS    : A handle to the DIB                                       *
                    513:  *                                                                         *
                    514:  ****************************************************************************/
                    515: HANDLE DibFromBitmap (
                    516:     HBITMAP      hbm,
                    517:     DWORD           biStyle,
                    518:     WORD            biBits,
                    519:     HPALETTE     hpal)
                    520: {
                    521:     BITMAP               bm;
                    522:     BITMAPINFOHEADER     bi;
                    523:     BITMAPINFOHEADER FAR *lpbi;
                    524:     DWORD                dwLen;
                    525:     HANDLE               hdib;
                    526:     HANDLE               h;
                    527:     HDC                  hdc;
                    528: 
                    529:     if (!hbm)
                    530:        return NULL;
                    531: 
                    532:     if (hpal == NULL)
                    533:         hpal = GetStockObject(DEFAULT_PALETTE);
                    534: 
                    535:     GetObject(hbm,sizeof(bm),(LPSTR)&bm);
                    536: 
                    537:     if (biBits == 0)
                    538:        biBits =  bm.bmPlanes * bm.bmBitsPixel;
                    539: 
                    540:     bi.biSize               = sizeof(BITMAPINFOHEADER);
                    541:     bi.biWidth              = bm.bmWidth;
                    542:     bi.biHeight             = bm.bmHeight;
                    543:     bi.biPlanes             = 1;
                    544:     bi.biBitCount           = biBits;
                    545:     bi.biCompression        = biStyle;
                    546:     bi.biSizeImage          = 0;
                    547:     bi.biXPelsPerMeter      = 0;
                    548:     bi.biYPelsPerMeter      = 0;
                    549:     bi.biClrUsed            = 0;
                    550:     bi.biClrImportant       = 0;
                    551: 
                    552:     dwLen  = bi.biSize + PaletteSize(&bi);
                    553: 
                    554:     hdc = GetDC(NULL);
                    555:     hpal = SelectPalette(hdc,hpal,FALSE);
                    556:         RealizePalette(hdc);
                    557: 
                    558:     hdib = GlobalAlloc(GHND,dwLen);
                    559: 
                    560:     if (!hdib){
                    561:        SelectPalette(hdc,hpal,FALSE);
                    562:        ReleaseDC(NULL,hdc);
                    563:        return NULL;
                    564:     }
                    565: 
                    566:     lpbi = (VOID FAR *)GlobalLock(hdib);
                    567: 
                    568:     *lpbi = bi;
                    569: 
                    570:     /* call GetDIBits with a NULL lpBits param, so it will calculate the
                    571:      *  biSizeImage field for us
                    572:      */
                    573:     GetDIBits(hdc, hbm, 0L, (DWORD)bi.biHeight,
                    574:         (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
                    575: 
                    576:     bi = *lpbi;
                    577:     GlobalUnlock(hdib);
                    578: 
                    579:     /* If the driver did not fill in the biSizeImage field, make one up */
                    580:     if (bi.biSizeImage == 0){
                    581:         bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
                    582: 
                    583:         if (biStyle != BI_RGB)
                    584:             bi.biSizeImage = (bi.biSizeImage * 3) / 2;
                    585:     }
                    586: 
                    587:     /* realloc the buffer big enough to hold all the bits */
                    588:     dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage;
                    589:     if (h = GlobalReAlloc(hdib,dwLen,0))
                    590:         hdib = h;
                    591:     else{
                    592:         GlobalFree(hdib);
                    593:        hdib = NULL;
                    594: 
                    595:        SelectPalette(hdc,hpal,FALSE);
                    596:        ReleaseDC(NULL,hdc);
                    597:        return hdib;
                    598:     }
                    599: 
                    600:     /* call GetDIBits with a NON-NULL lpBits param, and actualy get the
                    601:      *  bits this time
                    602:      */
                    603:     lpbi = (VOID FAR *)GlobalLock(hdib);
                    604: 
                    605:     if (GetDIBits( hdc,
                    606:                   hbm,
                    607:                   0L,
                    608:                   (DWORD)bi.biHeight,
                    609:                   (LPBYTE)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),
                    610:                   (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS) == 0){
                    611:         GlobalUnlock(hdib);
                    612:         hdib = NULL;
                    613:         SelectPalette(hdc,hpal,FALSE);
                    614:         ReleaseDC(NULL,hdc);
                    615:         return NULL;
                    616:     }
                    617: 
                    618:     bi = *lpbi;
                    619:     GlobalUnlock(hdib);
                    620: 
                    621:     SelectPalette(hdc,hpal,FALSE);
                    622:     ReleaseDC(NULL,hdc);
                    623:     return hdib;
                    624: }
                    625: 
                    626: /****************************************************************************
                    627:  *                                                                         *
                    628:  *  FUNCTION   : BitmapFromDib(HANDLE hdib, HPALETTE hpal)                 *
                    629:  *                                                                         *
                    630:  *  PURPOSE    : Will create a DDB (Device Dependent Bitmap) given a global *
                    631:  *              handle to a memory block in CF_DIB format                  *
                    632:  *                                                                         *
                    633:  *  RETURNS    : A handle to the DDB.                                      *
                    634:  *                                                                         *
                    635:  ****************************************************************************/
                    636: HBITMAP BitmapFromDib (
                    637:     HANDLE        hdib,
                    638:     HPALETTE   hpal)
                    639: {
                    640:     LPBITMAPINFOHEADER lpbi;
                    641:     HPALETTE           hpalT;
                    642:     HDC                hdc;
                    643:     HBITMAP            hbm;
                    644: 
                    645:     StartWait();
                    646: 
                    647:     if (!hdib)
                    648:        return NULL;
                    649: 
                    650:     lpbi = (VOID FAR *)GlobalLock(hdib);
                    651: 
                    652:     if (!lpbi)
                    653:        return NULL;
                    654: 
                    655:     hdc = GetDC(NULL);
                    656: 
                    657:     if (hpal){
                    658:         hpalT = SelectPalette(hdc,hpal,FALSE);
                    659:         RealizePalette(hdc);     // GDI Bug...????
                    660:     }
                    661: 
                    662:     hbm = CreateDIBitmap(hdc,
                    663:                 (LPBITMAPINFOHEADER)lpbi,
                    664:                 (LONG)CBM_INIT,
                    665:                 (LPSTR)lpbi + lpbi->biSize + PaletteSize(lpbi),
                    666:                 (LPBITMAPINFO)lpbi,
                    667:                 DIB_RGB_COLORS );
                    668: 
                    669:     if (hpal)
                    670:         SelectPalette(hdc,hpalT,FALSE);
                    671: 
                    672:     ReleaseDC(NULL,hdc);
                    673:     GlobalUnlock(hdib);
                    674: 
                    675:     EndWait();
                    676: 
                    677:     return hbm;
                    678: }
                    679: /****************************************************************************
                    680:  *                                                                         *
                    681:  *  FUNCTION   : DrawBitmap(HDC hdc, int x, int y, HBITMAP hbm, DWORD rop)  *
                    682:  *                                                                         *
                    683:  *  PURPOSE    : Draws bitmap <hbm> at the specifed position in DC <hdc>    *
                    684:  *                                                                         *
                    685:  *  RETURNS    : Return value of BitBlt()                                  *
                    686:  *                                                                         *
                    687:  ****************************************************************************/
                    688: BOOL DrawBitmap (
                    689:     HDC           hdc,
                    690:     INT           x,
                    691:     INT           y,
                    692:     HBITMAP    hbm,
                    693:     DWORD         rop)
                    694: {
                    695:     HDC       hdcBits;
                    696:     BITMAP    bm;
                    697: //    HPALETTE  hpalT; 
                    698:     BOOL      f;
                    699: 
                    700:     if (!hdc || !hbm)
                    701:         return FALSE;
                    702: 
                    703:     hdcBits = CreateCompatibleDC(hdc);
                    704:     GetObject(hbm,sizeof(BITMAP),(LPSTR)&bm);
                    705:     SelectObject(hdcBits,hbm);
                    706:     f = BitBlt(hdc,0,0,bm.bmWidth,bm.bmHeight,hdcBits,0,0,rop);
                    707:     DeleteDC(hdcBits);
                    708: 
                    709:     return f;
                    710:        UNREFERENCED_PARAMETER(y);
                    711:        UNREFERENCED_PARAMETER(x);
                    712: }
                    713: /****************************************************************************
                    714:  *                                                                         *
                    715:  *  FUNCTION   : DibBlt( HDC hdc,                                          *
                    716:  *                      int x0, int y0,                                    *
                    717:  *                      int dx, int dy,                                    *
                    718:  *                      HANDLE hdib,                                       *
                    719:  *                      int x1, int y1,                                    *
                    720:  *                      LONG rop)                                          *
                    721:  *                                                                         *
                    722:  *  PURPOSE    : Draws a bitmap in CF_DIB format, using SetDIBits to device.*
                    723:  *              taking the same parameters as BitBlt().                    *
                    724:  *                                                                         *
                    725:  *  RETURNS    : TRUE  - if function succeeds.                             *
                    726:  *              FALSE - otherwise.                                         *
                    727:  *                                                                         *
                    728:  ****************************************************************************/
                    729: BOOL DibBlt (
                    730:     HDC           hdc,
                    731:     INT           x0,
                    732:     INT           y0,
                    733:     INT           dx,
                    734:     INT           dy,
                    735:     HANDLE hdib,
                    736:     INT           x1,
                    737:     INT           y1,
                    738:     LONG   rop)
                    739: {
                    740:     LPBITMAPINFOHEADER  lpbi;
                    741: //    HPALETTE          hpal,hpalT;
                    742:     LPSTR               pBuf;
                    743: //    HDC               hdcMem;
                    744: //    HBITMAP           hbm,hbmT;
                    745: 
                    746:     if (!hdib)
                    747:        return PatBlt(hdc,x0,y0,dx,dy,rop);
                    748: 
                    749:     lpbi = (VOID FAR *)GlobalLock(hdib);
                    750: 
                    751:     if (!lpbi)
                    752:        return FALSE;
                    753: 
                    754:     pBuf = (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi);
                    755:     SetDIBitsToDevice (hdc, x0, y0, dx, dy,
                    756:                       x1,y1,
                    757:                       x1,
                    758:                       dy,
                    759:                       pBuf, (LPBITMAPINFO)lpbi,
                    760:                       DIB_RGB_COLORS );
                    761: 
                    762:     GlobalUnlock(hdib);
                    763:     return TRUE;
                    764: }
                    765: /****************************************************************************
                    766:  *                                                                         *
                    767:  *  FUNCTION   : StretchDibBlt( HDC hdc,                                   *
                    768:  *                             int x, int y,                               *
                    769:  *                             int dx, int dy,                             *
                    770:  *                             HANDLE hdib,                                *
                    771:  *                             int x0, int y0,                             *
                    772:  *                             int dx0, int dy0,                           *
                    773:  *                             LONG rop)                                   *
                    774:  *                                                                         *
                    775:  *  PURPOSE    : Draws a bitmap in CF_DIB format, using StretchDIBits()     *
                    776:  *              taking the same parameters as StretchBlt().                *
                    777:  *                                                                         *
                    778:  *  RETURNS    : TRUE  - if function succeeds.                             *
                    779:  *              FALSE - otherwise.                                         *
                    780:  *                                                                         *
                    781:  ****************************************************************************/
                    782: BOOL StretchDibBlt (
                    783:     HDC hdc,
                    784:     INT x,
                    785:     INT y,
                    786:     INT dx,
                    787:     INT dy,
                    788:     HANDLE hdib,
                    789:     INT x0,
                    790:     INT y0,
                    791:     INT dx0,
                    792:     INT dy0,
                    793:     LONG rop)
                    794: 
                    795: {
                    796:     LPBITMAPINFOHEADER lpbi;
                    797:     LPSTR        pBuf;
                    798:     BOOL         f;
                    799: 
                    800:     if (!hdib)
                    801:         return PatBlt(hdc,x,y,dx,dy,rop);
                    802: 
                    803:     lpbi = (VOID FAR *)GlobalLock(hdib);
                    804: 
                    805:     if (!lpbi)
                    806:         return FALSE;
                    807: 
                    808:     pBuf = (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi);
                    809: 
                    810:     f = StretchDIBits ( hdc,
                    811:                        x, y,
                    812:                        dx, dy,
                    813:                        x0, y0,
                    814:                        dx0, dy0,
                    815:                        pBuf, (LPBITMAPINFO)lpbi,
                    816:                        DIB_RGB_COLORS,
                    817:                        rop);
                    818: 
                    819:     GlobalUnlock(hdib);
                    820:     return f;
                    821: }
                    822: 
                    823:  /************* PRIVATE ROUTINES TO READ/WRITE MORE THAN 64K ***************/
                    824: /****************************************************************************
                    825:  *                                                                         *
                    826:  *  FUNCTION   : lread(int fh, VOID FAR *pv, DWORD ul)                     *
                    827:  *                                                                         *
                    828:  *  PURPOSE    : Reads data in steps of 32k till all the data has been read.*
                    829:  *                                                                         *
                    830:  *  RETURNS    : 0 - If read did not proceed correctly.                    *
                    831:  *              number of bytes read otherwise.                            *
                    832:  *                                                                         *
                    833:  ****************************************************************************/
                    834: DWORD PASCAL lread (
                    835:     INT              fh,
                    836:     VOID FAR      *pv,
                    837:     DWORD            ul)
                    838: {
                    839:     DWORD     ulT = ul;
                    840:     BYTE HUGE_T *hp = pv;
                    841: 
                    842:     while (ul > (DWORD)MAXREAD) {
                    843:        if (_lread(fh, (LPSTR)hp, (UINT)MAXREAD) != MAXREAD)
                    844:                return 0;
                    845:        ul -= MAXREAD;
                    846:        hp += MAXREAD;
                    847:     }
                    848:     if (_lread(fh, (LPSTR)hp, (UINT)ul) != (UINT)ul)
                    849:        return 0;
                    850:     return ulT;
                    851: }
                    852: 
                    853: /****************************************************************************
                    854:  *                                                                         *
                    855:  *  FUNCTION   : lwrite(int fh, VOID FAR *pv, DWORD ul)                    *
                    856:  *                                                                         *
                    857:  *  PURPOSE    : Writes data in steps of 32k till all the data is written.  *
                    858:  *                                                                         *
                    859:  *  RETURNS    : 0 - If write did not proceed correctly.                   *
                    860:  *              number of bytes written otherwise.                         *
                    861:  *                                                                         *
                    862:  ****************************************************************************/
                    863: DWORD PASCAL lwrite (
                    864:     INT             fh,
                    865:     VOID FAR     *pv,
                    866:     DWORD           ul)
                    867: {
                    868:     DWORD     ulT = ul;
                    869:     BYTE HUGE_T *hp = pv;
                    870: 
                    871:     while (ul > MAXREAD) {
                    872:        if (_lwrite(fh, (LPSTR)hp, (UINT)MAXREAD) != MAXREAD)
                    873:                return 0;
                    874:        ul -= MAXREAD;
                    875:        hp += MAXREAD;
                    876:     }
                    877:     if (_lwrite(fh, (LPSTR)hp, (UINT)ul) != (UINT)ul)
                    878:        return 0;                 
                    879: 
                    880:     return ulT;
                    881: }
                    882: 
                    883: /****************************************************************************
                    884:  *                                                                         *
                    885:  *  FUNCTION   : ReadBitMapFileHeaderandConvertToDwordAlign(HFILE fh, LPBITMAPFILEHEADER pbf)
                    886:  *                                                                         *
                    887:  *  PURPOSE    : read file header (which is packed) and convert into unpacked BITMAPFILEHEADER strucutre
                    888:  *                                                                         *
                    889:  *  RETURNS    : VOID
                    890:  *                                                                         *
                    891:  ****************************************************************************/
                    892: 
                    893: VOID ReadBitMapFileHeaderandConvertToDwordAlign(HFILE fh, LPBITMAPFILEHEADER pbf, LPDWORD lpdwoff)
                    894: {
                    895:        DWORD off;
                    896: 
                    897:        off = _llseek(fh, 0L, (UINT) SEEK_CUR);
                    898:        *lpdwoff = off;
                    899: 
                    900: /*             BITMAPFILEHEADER STRUCUTURE is as follows 
                    901:  *             BITMAPFILEHEADER
                    902:  *             WORD    bfType 
                    903:  >          ....                 <     add WORD if packed here!
                    904:  *             DWORD   bfSize 
                    905:  *             WORD    bfReserved1
                    906:  *             WORD    bfReserved2
                    907:  *             DWORD   bfOffBits 
                    908:  *                     This is the packed format, unpacked adds a WORD after bfType
                    909:  */
                    910: 
                    911:        /* read in bfType*/
                    912:        _lread(fh, (LPSTR) &pbf->bfType, sizeof(WORD));
                    913:        /* read in last 3 dwords*/
                    914:        _lread(fh, (LPSTR) &pbf->bfSize, sizeof(DWORD) * 3);
                    915: 
                    916: }
                    917: 
                    918: 
                    919: 
                    920: /****************************************************************************
                    921:  *                                                                         *
                    922:  *  FUNCTION   : WriteMapFileHeaderandConvertFromDwordAlignToPacked(HFILE fh, LPBITMAPFILEHEADER pbf)
                    923:  *                                                                         *
                    924:  *  PURPOSE    : write header structure (which NOT packed) and write it PACKED
                    925:  *                                                                         *
                    926:  *  RETURNS    : VOID
                    927:  *                                                                         *
                    928:  ****************************************************************************/
                    929: 
                    930: VOID WriteMapFileHeaderandConvertFromDwordAlignToPacked(HFILE fh, LPBITMAPFILEHEADER pbf)
                    931: {
                    932: 
                    933:        /* write bfType*/
                    934:     _lwrite(fh, (LPSTR)&pbf->bfType, (UINT)sizeof (WORD));
                    935:        /* now pass over extra word, and only write next 3 DWORDS!*/
                    936:        _lwrite(fh, (LPSTR)&pbf->bfSize, sizeof(DWORD) * 3);
                    937: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.