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

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

unix.superglobalmegacorp.com

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