Annotation of mstools/samples/sdktools/imagedit/image.c, revision 1.1.1.1

1.1       root        1: /****************************************************************************/
                      2: /*                                                                          */
                      3: /*                         Microsoft Confidential                           */
                      4: /*                                                                          */
                      5: /*                 Copyright (c) Microsoft Corp.  1987, 1991                */
                      6: /*                           All Rights Reserved                            */
                      7: /*                                                                          */
                      8: /****************************************************************************/
                      9: /****************************** Module Header *******************************
                     10: * Module Name: image.c
                     11: *
                     12: * Routines for opening and saving images.
                     13: *
                     14: * History:
                     15: *
                     16: ****************************************************************************/
                     17: 
                     18: #include "imagedit.h"
                     19: 
                     20: #include <stdio.h>
                     21: #include <string.h>
                     22: 
                     23: 
                     24: 
                     25: /************************************************************************
                     26: * ImageNew
                     27: *
                     28: * Creates a new image for the specified device.
                     29: *
                     30: * Arguments:
                     31: *
                     32: * History:
                     33: *
                     34: ************************************************************************/
                     35: 
                     36: BOOL ImageNew(
                     37:     PDEVICE pDevice)
                     38: {
                     39:     PIMAGEINFO pImage;
                     40: 
                     41:     if (!(pImage = ImageLinkAlloc(pDevice, pDevice->cx, pDevice->cy,
                     42:             0, 0, pDevice->nColors)))
                     43:         return FALSE;
                     44: 
                     45:     /*
                     46:      * Allocate work space for the new image.
                     47:      */
                     48:     if (!ImageDCCreate(pDevice->iType, pImage->cx, pImage->cy,
                     49:             pImage->nColors)) {
                     50:         ImageLinkFree(pImage);
                     51:         return FALSE;
                     52:     }
                     53: 
                     54:     gpImageCur = pImage;
                     55:     gnImages++;
                     56:     giType = pDevice->iType;
                     57: 
                     58:     /*
                     59:      * Initialize the pick rectangle to encompass the entire image.
                     60:      */
                     61:     PickSetRect(0, 0, gcxImage - 1, gcyImage - 1);
                     62: 
                     63:     /*
                     64:      * Mark the newly created image as dirty to be sure it gets saved.
                     65:      */
                     66:     fImageDirty = TRUE;
                     67: 
                     68:     /*
                     69:      * Update the palettes.
                     70:      */
                     71:     SetColorPalette(gnColors, giType, FALSE);
                     72:     PropBarUpdate();
                     73:     ToolboxUpdate();
                     74:     ViewReset();
                     75: 
                     76:     /*
                     77:      * Reset the workspace window and then show it.
                     78:      */
                     79:     WorkReset();
                     80:     ShowWindow(ghwndWork, SW_SHOWNORMAL);
                     81: 
                     82:     return TRUE;
                     83: }
                     84: 
                     85: 
                     86: 
                     87: /************************************************************************
                     88: * ImageNewBitmap
                     89: *
                     90: * Creates a new bitmap image given a set of characteristics.  After
                     91: * device link is created for those characteristics, ImageNew() is
                     92: * called to do the actual work.
                     93: *
                     94: * Arguments:
                     95: *
                     96: * History:
                     97: *
                     98: ************************************************************************/
                     99: 
                    100: BOOL ImageNewBitmap(
                    101:     INT cx,
                    102:     INT cy,
                    103:     INT nColors)
                    104: {
                    105:     PDEVICE pDevice;
                    106: 
                    107:     if (!(pDevice = DeviceLinkAlloc(FT_BITMAP, NULL, nColors, cx, cy)))
                    108:         return FALSE;
                    109: 
                    110:     return ImageNew(pDevice);
                    111: }
                    112: 
                    113: 
                    114: 
                    115: /************************************************************************
                    116: * ImageOpen
                    117: *
                    118: * Determines what has to be done to open the specified image.  If it
                    119: * is not already the current image, it will save the current image
                    120: * then will call ImageOpen2() to open the new one.
                    121: *
                    122: * Arguments:
                    123: *
                    124: * History:
                    125: *
                    126: ************************************************************************/
                    127: 
                    128: BOOL ImageOpen(
                    129:     PIMAGEINFO pImage)
                    130: {
                    131:     /*
                    132:      * New image is already current.  Return success.
                    133:      */
                    134:     if (pImage == gpImageCur)
                    135:         return TRUE;
                    136: 
                    137:     /*
                    138:      * Is this an image for a known device?
                    139:      */
                    140:     if (pImage->pDevice) {
                    141:         /*
                    142:          * Save away the current image.
                    143:          */
                    144:         ImageSave();
                    145: 
                    146:         /*
                    147:          * Do the real open of the new image.
                    148:          */
                    149:         return ImageOpen2(pImage);
                    150:     }
                    151:     else {
                    152:         Message(MSG_CANTEDITIMAGE);
                    153:         return FALSE;
                    154:     }
                    155: }
                    156: 
                    157: 
                    158: 
                    159: /************************************************************************
                    160: * ImageOpen2
                    161: *
                    162: * Unconditionally opens up the specified image for editing.  This involves
                    163: * parsing the DIB into various globals, putting the bits onto the screen
                    164: * and updating the different palettes appropriately.
                    165: *
                    166: * Arguments:
                    167: *
                    168: * History:
                    169: *
                    170: ************************************************************************/
                    171: 
                    172: BOOL ImageOpen2(
                    173:     PIMAGEINFO pImage)
                    174: {
                    175:     HCURSOR hcurOld;
                    176:     LPBITMAPINFO lpbi;
                    177:     INT iBitCount;
                    178:     INT cx;
                    179:     INT cy;
                    180:     INT nColors;
                    181:     DWORD cbColorTable;
                    182:     DWORD cbBits;
                    183:     LPBYTE lpDIBBits;
                    184:     HBITMAP hbmMono;
                    185:     HBITMAP hbmImage;
                    186:     PBITMAPINFO pbi;
                    187: 
                    188:     hcurOld = SetCursor(hcurWait);
                    189: 
                    190:     lpbi = (LPBITMAPINFO)pImage->DIBPtr;
                    191:     iBitCount = lpbi->bmiHeader.biBitCount;
                    192: 
                    193:     cx = (INT)lpbi->bmiHeader.biWidth;
                    194:     cy = (INT)lpbi->bmiHeader.biHeight;
                    195:     if (giType != FT_BITMAP)
                    196:         cy /= 2;
                    197: 
                    198:     nColors = pImage->nColors;
                    199: 
                    200:     /*
                    201:      * Allocate work space for the image.
                    202:      */
                    203:     if (!ImageDCCreate(giType, cx, cy, nColors))
                    204:         goto Error1;
                    205: 
                    206:     /*
                    207:      * Create a temporary bitmap.
                    208:      */
                    209:     if (!(hbmMono = CreateBitmap(1, 1, 1, 1, NULL))) {
                    210:         Message(MSG_OUTOFMEMORY);
                    211:         goto Error2;
                    212:     }
                    213: 
                    214:     cbColorTable = (1 << iBitCount) * sizeof(RGBQUAD);
                    215:     lpDIBBits = (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + cbColorTable;
                    216:     cbBits = (((((DWORD)cx * iBitCount) + 31) & 0xffffffe0) >> 3) * cy;
                    217: 
                    218:     /*
                    219:      * Make a copy of the info header and color table.
                    220:      */
                    221:     if (!(pbi = (PBITMAPINFO)MyAlloc(
                    222:             sizeof(BITMAPINFOHEADER) + (INT)cbColorTable)))
                    223:         goto Error3;
                    224: 
                    225:     memcpy((LPBYTE)pbi, lpbi, sizeof(BITMAPINFOHEADER) + (INT)cbColorTable);
                    226: 
                    227:     /*     * Adjust some fields.  The size field in an icon/cursor dib
                    228:      * includes the AND mask bits, which we don't want to include
                    229:      * right now.
                    230:      */
                    231:     pbi->bmiHeader.biHeight = cy;
                    232:     pbi->bmiHeader.biSizeImage = cbBits;
                    233: 
                    234:     /*
                    235:      * Set the bits into the XOR mask.
                    236:      */
                    237:     hbmImage = SelectObject(ghdcImage, hbmMono);
                    238:     SetDIBits(ghdcImage, hbmImage, 0, cy, lpDIBBits, pbi, DIB_RGB_COLORS);
                    239:     SelectObject(ghdcImage, hbmImage);
                    240: 
                    241:     /*
                    242:      * If we are editing an icon or cursor, we need to set the bits
                    243:      * for the AND mask also now.
                    244:      */
                    245:     if (giType != FT_BITMAP) {
                    246:         /*
                    247:          * Skip past the XOR mask bits to the AND bits that follow.
                    248:          */
                    249:         lpDIBBits += cbBits;
                    250: 
                    251:         cbColorTable = 2 * sizeof(RGBQUAD);
                    252: 
                    253:         /*
                    254:          * Adjust some fields in the copy of the bitmap info structure,
                    255:          * then copy a monochrome color table into it.  Note that we
                    256:          * are using the same allocated copy, which is ok because there
                    257:          * will always be enough room allocated for the monochrome
                    258:          * color table.
                    259:          */
                    260:         pbi->bmiHeader.biBitCount = 1;
                    261:         pbi->bmiHeader.biSizeImage =
                    262:                 cy * ((((DWORD)cx + 31) & 0xffffffe0) >> 3);
                    263:         pbi->bmiHeader.biClrImportant = 0;
                    264:         pbi->bmiHeader.biClrUsed = 0;
                    265:         memcpy((PBYTE)pbi->bmiColors, (PBYTE)gargbColorTable2,
                    266:                 (INT)cbColorTable);
                    267: 
                    268:         /*
                    269:          * Set the bits into the AND mask.
                    270:          */
                    271:         hbmImage = SelectObject(ghdcANDMask, hbmMono);
                    272:         SetDIBits(ghdcANDMask, hbmImage, 0, cy, lpDIBBits, pbi,
                    273:                 DIB_RGB_COLORS);
                    274:         SelectObject(ghdcANDMask, hbmImage);
                    275: 
                    276:         /*
                    277:          * Combine the XOR and AND masks into a viewable image.
                    278:          */
                    279:         ImageDCCombine(ghdcImage, gcxImage, gcyImage, ghdcANDMask);
                    280:     }
                    281: 
                    282:     MyFree(pbi);
                    283:     DeleteObject(hbmMono);
                    284: 
                    285:     /*
                    286:      * Set the current image pointer.
                    287:      */
                    288:     gpImageCur = pImage;
                    289:     fImageDirty = FALSE;
                    290:     /*
                    291:      * Initialize the pick rectangle to encompass the entire image.
                    292:      */
                    293:     PickSetRect(0, 0, gcxImage - 1, gcyImage - 1);
                    294: 
                    295:     SetColorPalette(gnColors, giType, FALSE);
                    296: 
                    297:     /*
                    298:      * Update the properties bar info and toolbox.
                    299:      */
                    300:     PropBarUpdate();
                    301:     ToolboxUpdate();
                    302: 
                    303:     ViewReset();
                    304: 
                    305:     /*
                    306:      * Reset the workspace window and then show it.
                    307:      */
                    308:     WorkReset();
                    309:     ShowWindow(ghwndWork, SW_SHOWNORMAL);
                    310: 
                    311:     SetCursor(hcurOld);
                    312: 
                    313:     return TRUE;
                    314: 
                    315: Error3:
                    316:     DeleteObject(hbmMono);
                    317: 
                    318: Error2:
                    319:     ImageDCDelete();
                    320: 
                    321: Error1:
                    322:     SetCursor(hcurOld);
                    323: 
                    324:     return FALSE;
                    325: }
                    326: 
                    327: 
                    328: 
                    329: /************************************************************************
                    330: * ImageSave
                    331: *
                    332: * Saves the state of the current image into the image list (if it
                    333: * is dirty).
                    334: *
                    335: * History:
                    336: *
                    337: ************************************************************************/
                    338: 
                    339: VOID ImageSave(VOID)
                    340: {
                    341:     HCURSOR hcurOld;
                    342:     INT iBitCount;
                    343:     DWORD cbColorTable;
                    344:     DWORD cbXORBits;
                    345:     DWORD cbANDBits;
                    346:     HANDLE hDIB;
                    347:     DWORD dwDIBSize;
                    348:     LPBITMAPINFOHEADER lpbih;
                    349:     LPBYTE lpBits;
                    350:     HBITMAP hbmMono;
                    351:     HBITMAP hbmImage;
                    352: 
                    353:     if (!fImageDirty)
                    354:         return;
                    355: 
                    356:     hcurOld = SetCursor(hcurWait);
                    357: 
                    358:     /*
                    359:      * Separate out the XOR and AND masks for ico/cur images.
                    360:      */
                    361:     if (giType != FT_BITMAP)
                    362:         ImageDCSeparate(ghdcImage, gcxImage, gcyImage, ghdcANDMask, grgbScreen);
                    363: 
                    364:     /*
                    365:      * Create a temporary bitmap.
                    366:      */
                    367:     if (!(hbmMono = CreateBitmap(1, 1, 1, 1, NULL))) {
                    368:         Message(MSG_OUTOFMEMORY);
                    369:         goto Error1;
                    370:     }
                    371: 
                    372:     switch (gpImageCur->nColors) {
                    373:         case 2:
                    374:             iBitCount = 1;
                    375:             break;
                    376: 
                    377:         case 16:
                    378:             iBitCount = 4;
                    379:             break;
                    380:     }
                    381: 
                    382:     cbColorTable = (DWORD)gpImageCur->nColors * sizeof(RGBQUAD);
                    383:     cbXORBits = (((((DWORD)gpImageCur->cx * iBitCount) + 31)
                    384:             & 0xffffffe0) >> 3) * gpImageCur->cy;
                    385: 
                    386:     switch (giType) {
                    387:         case FT_BITMAP:
                    388:             cbANDBits = 0;
                    389:             break;
                    390: 
                    391:         case FT_ICON:
                    392:         case FT_CURSOR:
                    393:             cbANDBits = (DWORD)gpImageCur->cy *
                    394:                     ((((DWORD)gpImageCur->cx + 31) & 0xffffffe0) >> 3);
                    395:             break;
                    396:     }
                    397: 
                    398:     dwDIBSize = sizeof(BITMAPINFOHEADER) + cbColorTable + cbXORBits +
                    399:             cbANDBits;
                    400: 
                    401:     /*
                    402:      * Allocate space for the DIB for this image.
                    403:      */
                    404:     if (!(hDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwDIBSize))) {
                    405:         Message(MSG_OUTOFMEMORY);
                    406:         goto Error2;
                    407:     }
                    408: 
                    409:     lpbih = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
                    410: 
                    411:     /*
                    412:      * For icons and cursors, we need to get the AND mask bits first.
                    413:      */
                    414:     if (giType != FT_BITMAP) {
                    415:         /*
                    416:          * Point to where the AND bits should go.
                    417:          */
                    418:         lpBits = (LPBYTE)lpbih + sizeof(BITMAPINFOHEADER) +
                    419:                 cbColorTable + cbXORBits;
                    420: 
                    421:         /*
                    422:          * Fill in the bitmap info header for getting the AND bits.
                    423:          */
                    424:         lpbih->biSize          = sizeof(BITMAPINFOHEADER);
                    425:         lpbih->biWidth         = gpImageCur->cx;
                    426:         lpbih->biHeight        = gpImageCur->cy;
                    427:         lpbih->biPlanes        = 1;
                    428:         lpbih->biBitCount      = 1;
                    429:         lpbih->biCompression   = BI_RGB;
                    430:         lpbih->biSizeImage     = cbANDBits;
                    431:         lpbih->biXPelsPerMeter = 0;
                    432:         lpbih->biYPelsPerMeter = 0;
                    433:         lpbih->biClrImportant  = 0;
                    434:         lpbih->biClrUsed       = 0;
                    435: 
                    436:         /*
                    437:          * Get the bits from the AND mask.
                    438:          */
                    439:         hbmImage = SelectObject(ghdcANDMask, hbmMono);
                    440:         GetDIBits(ghdcANDMask, hbmImage, 0, gpImageCur->cy, lpBits,
                    441:                 (LPBITMAPINFO)lpbih, DIB_RGB_COLORS);
                    442:         SelectObject(ghdcANDMask, hbmImage);
                    443:     }
                    444: 
                    445:     /*
                    446:      * Fill in the bitmap info header for getting the XOR bits.
                    447:      */
                    448:     lpbih->biSize          = sizeof(BITMAPINFOHEADER);
                    449:     lpbih->biWidth         = gpImageCur->cx;
                    450:     lpbih->biHeight        = gpImageCur->cy;
                    451:     lpbih->biPlanes        = 1;
                    452:     lpbih->biBitCount      = iBitCount;
                    453:     lpbih->biCompression   = BI_RGB;
                    454:     lpbih->biSizeImage     = cbXORBits;
                    455:     lpbih->biXPelsPerMeter = 0;
                    456:     lpbih->biYPelsPerMeter = 0;
                    457:     lpbih->biClrImportant  = 0;
                    458:     lpbih->biClrUsed       = 0;
                    459: 
                    460:     /*
                    461:      * Point to where the XOR bits should go.
                    462:      */
                    463:     lpBits = (LPBYTE)lpbih + sizeof(BITMAPINFOHEADER) + cbColorTable;
                    464: 
                    465:     /*
                    466:      * Get the bits from the XOR mask.
                    467:      */
                    468:     hbmImage = SelectObject(ghdcImage, hbmMono);
                    469:     GetDIBits(ghdcImage, hbmImage, 0, gpImageCur->cy, lpBits,
                    470:             (LPBITMAPINFO)lpbih, DIB_RGB_COLORS);
                    471:     SelectObject(ghdcImage, hbmImage);
                    472: 
                    473:     /*
                    474:      * For icons and cursors, we have a few extra steps.
                    475:      */
                    476:     if (giType != FT_BITMAP) {
                    477:         /*
                    478:          * Set the fields in the info structure to their final
                    479:          * values.  The saved value in the bitmap info header for the
                    480:          * height in an icon/cursor DIB is really twice the height of
                    481:          * the image, and the size of the image is the size of both
                    482:          * the XOR and the AND mask bits.
                    483:          */
                    484:         lpbih->biHeight *= 2;
                    485:         lpbih->biSizeImage = cbXORBits + cbANDBits;
                    486: 
                    487:         /*
                    488:          * Recombine the XOR and AND masks now that we have their bits.
                    489:          */
                    490:         ImageDCCombine(ghdcImage, gcxImage, gcyImage, ghdcANDMask);
                    491:     }
                    492: 
                    493:     /*
                    494:      * Free any old DIB.
                    495:      */
                    496:     if (gpImageCur->DIBhandle) {
                    497:         GlobalUnlock(gpImageCur->DIBhandle);
                    498:         GlobalFree(gpImageCur->DIBhandle);
                    499:     }
                    500: 
                    501:     /*
                    502:      * Set the image structure to point to the newly created DIB.
                    503:      */
                    504:     gpImageCur->DIBSize = dwDIBSize;
                    505:     gpImageCur->DIBhandle = hDIB;
                    506:     gpImageCur->DIBPtr = (LPBYTE)lpbih;
                    507: 
                    508:     fFileDirty = TRUE;
                    509:     fImageDirty = FALSE;
                    510: 
                    511: Error2:
                    512:     DeleteObject(hbmMono);
                    513: 
                    514: Error1:
                    515:     SetCursor (hcurOld);
                    516: }

unix.superglobalmegacorp.com

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