Annotation of mstools/samples/sdktools/imagedit/image.c, revision 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.