Annotation of mstools/samples/sdktools/imagedit/rwicocur.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: rwicocur.c
        !            11: *
        !            12: * Routines to read and write icon and cursor files.
        !            13: *
        !            14: * History:
        !            15: *
        !            16: ****************************************************************************/
        !            17: 
        !            18: #include "imagedit.h"
        !            19: 
        !            20: #include <io.h>
        !            21: #include <fcntl.h>                          // For NT fstat().
        !            22: #include <sys\types.h>                      // For fstat() types.
        !            23: #include <sys\stat.h>                       // For fstat() function.
        !            24: 
        !            25: 
        !            26: 
        !            27: /************************************************************************
        !            28: * LoadIconCursorFile
        !            29: *
        !            30: * Loads the specified icon or cursor file.  It reads the images into
        !            31: * a list, then prompts for which one to open initially.
        !            32: *
        !            33: * Arguments:
        !            34: *
        !            35: * History:
        !            36: *
        !            37: ************************************************************************/
        !            38: 
        !            39: BOOL LoadIconCursorFile(
        !            40:     PSTR pszFullFileName,
        !            41:     BOOL fIcon)
        !            42: {
        !            43:     HFILE hf;
        !            44:     INT i;
        !            45:     PIMAGEINFO pImage;
        !            46:     LPBITMAPINFO lpBitmapInfo;
        !            47:     HANDLE hDIB;                    // Handle to DIB bits.
        !            48:     OFSTRUCT OfStruct;
        !            49:     struct stat FileStatus;
        !            50:     ICOCURSORHDR hdr;               // Header structure of icon/cursor file.
        !            51:     INT nImages;
        !            52:     PICOCURSORDESC aIcoCurDesc;     // Array of ico/cur descriptors.
        !            53:     DWORD dwFilePos;
        !            54:     DWORD dwFileSize;
        !            55:     INT iType;
        !            56: 
        !            57:     if ((hf = (HFILE)OpenFile(pszFullFileName, (LPOFSTRUCT)&OfStruct, OF_READ))
        !            58:             == (HFILE)-1) {
        !            59:         Message(MSG_CANTOPEN, pszFullFileName);
        !            60:         return FALSE;
        !            61:     }
        !            62: 
        !            63:     fstat((INT)_open_osfhandle((long)(hf), (int)(O_RDONLY)), &FileStatus);
        !            64:     dwFileSize = (DWORD)FileStatus.st_size;
        !            65: 
        !            66:     ImageLinkFreeList();
        !            67: 
        !            68:     if (fIcon)
        !            69:         iType = FT_ICON;
        !            70:     else
        !            71:         iType = FT_CURSOR;
        !            72: 
        !            73:     /*
        !            74:      * Read the Icon/Cursor File header.
        !            75:      */
        !            76:     if (!MyFileRead(hf, (LPSTR)&hdr, sizeof(ICOCURSORHDR),
        !            77:             pszFullFileName, iType))
        !            78:         goto Error1;
        !            79: 
        !            80:     if (hdr.iReserved != 0) {
        !            81:         Message(MSG_BADICOCURFILE, pszFullFileName);
        !            82:         goto Error1;
        !            83:     }
        !            84: 
        !            85:     /*
        !            86:      * Get number of images in the file.
        !            87:      */
        !            88:     nImages = hdr.iResourceCount;
        !            89: 
        !            90:     if (!nImages || nImages > MAXIMAGES) {
        !            91:         Message(MSG_BADICOCURFILE, pszFullFileName);
        !            92:         goto Error1;
        !            93:     }
        !            94: 
        !            95:     if (hdr.iResourceType != 1 && hdr.iResourceType != 2) {
        !            96:         Message(MSG_BADICOCURFILE, pszFullFileName);
        !            97:         goto Error1;
        !            98:     }
        !            99: 
        !           100:     /*
        !           101:      * Allocate room for the descriptor records.
        !           102:      */
        !           103:     if (!(aIcoCurDesc = (PICOCURSORDESC)MyAlloc(
        !           104:             sizeof(ICOCURSORDESC) * nImages)))
        !           105:         goto Error1;
        !           106: 
        !           107:     /*
        !           108:      * Read in the descriptor records.
        !           109:      */
        !           110:     if (!MyFileRead(hf, (LPSTR)aIcoCurDesc, sizeof(ICOCURSORDESC) * nImages,
        !           111:             pszFullFileName, iType))
        !           112:         goto Error2;
        !           113: 
        !           114:     /*
        !           115:      * Get the current file position (after the descriptors).  This
        !           116:      * should be the start of the DIB's.
        !           117:      */
        !           118:     dwFilePos = (DWORD)SetFilePointer((HANDLE)hf, 0, NULL, (DWORD)1);
        !           119: 
        !           120:     /*
        !           121:      * Validate the descriptor records.
        !           122:      */
        !           123:     for (i = 0; i < nImages; i++) {
        !           124:         /*
        !           125:          * Make sure the DIB's are sequential (not overlapping)
        !           126:          * and they all fit within the file.
        !           127:          */
        !           128:         if (aIcoCurDesc[i].DIBOffset != dwFilePos ||
        !           129:                 dwFilePos + aIcoCurDesc[i].DIBSize > dwFileSize) {
        !           130:             Message(MSG_BADICOCURFILE, pszFullFileName);
        !           131:             goto Error2;
        !           132:         }
        !           133: 
        !           134:         /*
        !           135:          * Jump to the next DIB.
        !           136:          */
        !           137:         dwFilePos += aIcoCurDesc[i].DIBSize;
        !           138:     }
        !           139: 
        !           140:     for (i = 0; i < nImages; i++) {
        !           141:         pImage = ImageLinkAlloc(NULL, 0, 0,
        !           142:                 aIcoCurDesc[i].iHotspotX, aIcoCurDesc[i].iHotspotY,
        !           143:                 (aIcoCurDesc[i].iColorCount == (BYTE)8) ?
        !           144:                 aIcoCurDesc[i].iColorCount : 0);
        !           145: 
        !           146:         if (!pImage)
        !           147:             goto Error3;
        !           148: 
        !           149:         /*
        !           150:          * Allocate space for the DIB for this image.
        !           151:          */
        !           152:         if (!(hDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
        !           153:                 (DWORD)aIcoCurDesc[i].DIBSize))) {
        !           154:             Message(MSG_OUTOFMEMORY);
        !           155:             goto Error3;
        !           156:         }
        !           157: 
        !           158:         pImage->DIBSize = aIcoCurDesc[i].DIBSize;
        !           159:         pImage->DIBhandle = hDIB;
        !           160:         pImage->DIBPtr = (LPSTR)GlobalLock(hDIB);
        !           161:     }
        !           162: 
        !           163:     for (pImage = gpImageHead; pImage != NULL; pImage = pImage->pImageNext) {
        !           164:         if (!MyFileRead(hf, pImage->DIBPtr, (DWORD)pImage->DIBSize,
        !           165:                 pszFullFileName, iType))
        !           166:             goto Error3;
        !           167: 
        !           168:         lpBitmapInfo = (LPBITMAPINFO)pImage->DIBPtr;
        !           169: 
        !           170:         if (!IsValidDIB(lpBitmapInfo, pImage->DIBSize, TRUE)) {
        !           171:             Message(MSG_BADICOCURFILE, pszFullFileName);
        !           172:             goto Error3;
        !           173:         }
        !           174: 
        !           175:         /*
        !           176:          * Fill the x and y size fields in image node from
        !           177:          * information in the DIB header.
        !           178:          */
        !           179:         pImage->cx = (INT)lpBitmapInfo->bmiHeader.biWidth;
        !           180:         pImage->cy = (INT)lpBitmapInfo->bmiHeader.biHeight / 2;
        !           181:         if (pImage->nColors == 0)
        !           182:             pImage->nColors = (1 << lpBitmapInfo->bmiHeader.biBitCount);
        !           183: 
        !           184:         pImage->pDevice = DeviceLinkFind(
        !           185:                 fIcon ? gpIconDeviceHead : gpCursorDeviceHead,
        !           186:                 pImage->nColors, pImage->cx, pImage->cy);
        !           187:     }
        !           188: 
        !           189:     _lclose((HFILE)hf);
        !           190: 
        !           191:     fFileDirty = FALSE;
        !           192:     SetFileName(pszFullFileName);
        !           193:     giType = iType;
        !           194: 
        !           195:     gnImages = nImages;
        !           196: 
        !           197:     /*
        !           198:      * Update the PropBar and the Toolbox so that they show
        !           199:      * information about the opened file.  We do this now just
        !           200:      * in case the user cancels out of the Image Select Dialog.
        !           201:      */
        !           202:     PropBarUpdate();
        !           203:     ToolboxUpdate();
        !           204: 
        !           205:     /*
        !           206:      * Open up an image.  If there are multiple images in the file,
        !           207:      * show the Image Select dialog.  We also show the Image Select
        !           208:      * dialog if the file only has one image but it is not for a known
        !           209:      * device.
        !           210:      */
        !           211:     if (gnImages > 1 || !gpImageHead->pDevice)
        !           212:         ImageSelectDialog();
        !           213:     else
        !           214:         ImageOpen2(gpImageHead);
        !           215: 
        !           216:     return TRUE;
        !           217: 
        !           218: Error3:
        !           219:     ImageLinkFreeList();
        !           220: 
        !           221: Error2:
        !           222:     MyFree(aIcoCurDesc);
        !           223: 
        !           224: Error1:
        !           225:     _lclose((HFILE)hf);
        !           226: 
        !           227:     return FALSE;
        !           228: }
        !           229: 
        !           230: 
        !           231: 
        !           232: /************************************************************************
        !           233: * IsValidDIB
        !           234: *
        !           235: * This function determines if the given DIB is valid or not.  It does
        !           236: * this without touching memory outside the bounds of the cbDIBSize
        !           237: * passed in or the size of a BITMAPINFOHEADER, whichever is smaller.
        !           238: * Note that even if the DIB is valid, however, the current image
        !           239: * editor might not be able to edit it (the size might be too big, for
        !           240: * instance).
        !           241: *
        !           242: * Arguments:
        !           243: *   LPBITMAPINFO pDIB - Points to the DIB.
        !           244: *   DWORD cbDIBSize   - The size of the DIB.
        !           245: *   BOOL fIcoCur      - TRUE if this is an icon or cursor.  This effects
        !           246: *                       whether an AND mask is expected to be in the DIB.
        !           247: *
        !           248: * History:
        !           249: *
        !           250: ************************************************************************/
        !           251: 
        !           252: BOOL IsValidDIB(
        !           253:     LPBITMAPINFO pDIB,
        !           254:     DWORD cbDIBSize,
        !           255:     BOOL fIcoCur)
        !           256: {
        !           257:     DWORD cbANDMask;
        !           258:     DWORD cbXORMask;
        !           259:     DWORD cbColorTable;
        !           260:     DWORD nHeight;
        !           261: 
        !           262:     if (cbDIBSize < sizeof(BITMAPINFOHEADER))
        !           263:         return FALSE;
        !           264: 
        !           265:     if (pDIB->bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
        !           266:         return FALSE;
        !           267: 
        !           268:     if (pDIB->bmiHeader.biPlanes != 1)
        !           269:         return FALSE;
        !           270: 
        !           271:     if (pDIB->bmiHeader.biBitCount != 1 &&
        !           272:             pDIB->bmiHeader.biBitCount != 4 &&
        !           273:             pDIB->bmiHeader.biBitCount != 8 &&
        !           274:             pDIB->bmiHeader.biBitCount != 24)
        !           275:         return FALSE;
        !           276: 
        !           277:     if (fIcoCur) {
        !           278:         nHeight = pDIB->bmiHeader.biHeight / 2;
        !           279:         cbANDMask = (((pDIB->bmiHeader.biWidth + 31) & 0xffffffe0) >> 3) *
        !           280:                 nHeight;
        !           281:     }
        !           282:     else {
        !           283:         nHeight = pDIB->bmiHeader.biHeight;
        !           284:         cbANDMask = 0;
        !           285:     }
        !           286: 
        !           287:     cbColorTable = (1 << pDIB->bmiHeader.biBitCount) * sizeof(RGBQUAD);
        !           288:     cbXORMask = ((((pDIB->bmiHeader.biWidth * pDIB->bmiHeader.biBitCount) +
        !           289:             31) & 0xffffffe0) >> 3) * nHeight;
        !           290: 
        !           291:     /*
        !           292:      * Check the size field in the header.  This must be either zero
        !           293:      * or a valid size.
        !           294:      */
        !           295:     if (pDIB->bmiHeader.biSizeImage &&
        !           296:             pDIB->bmiHeader.biSizeImage != cbXORMask + cbANDMask)
        !           297:         return FALSE;
        !           298: 
        !           299:     if (cbDIBSize != sizeof(BITMAPINFOHEADER) + cbColorTable +
        !           300:             cbXORMask + cbANDMask)
        !           301:         return FALSE;
        !           302: 
        !           303:     return TRUE;
        !           304: }
        !           305: 
        !           306: 
        !           307: 
        !           308: /************************************************************************
        !           309: * SaveIconCursorFile
        !           310: *
        !           311: *
        !           312: *
        !           313: * Arguments:
        !           314: *
        !           315: * Returns:
        !           316: *   TRUE if successful, FALSE otherwise.
        !           317: *
        !           318: * History:
        !           319: *
        !           320: ************************************************************************/
        !           321: 
        !           322: BOOL SaveIconCursorFile(
        !           323:     PSTR pszFullFileName,
        !           324:     INT iType)
        !           325: {
        !           326:     ICOCURSORHDR IcoCurHdr;     // Header structure of icon/cursor file.
        !           327:     ICOCURSORDESC IcoCurDesc;   // Icon/cursor descriptor struct.
        !           328:     HCURSOR hcurOld;            // Handle to old cursor.
        !           329:     PIMAGEINFO pImage;          // Pointer to node in image list.
        !           330:     DWORD iBitsOffset;          // Offset of the actual DIB bits for image.
        !           331:     HFILE hf;
        !           332:     OFSTRUCT OfStruct;
        !           333: 
        !           334:     hcurOld = SetCursor(hcurWait);
        !           335: 
        !           336:     /*
        !           337:      * Save the bits of the current image.
        !           338:      */
        !           339:     ImageSave();
        !           340: 
        !           341:     /*
        !           342:      * Open the file for writing.
        !           343:      */
        !           344:     if ((hf = (HFILE)OpenFile(pszFullFileName, &OfStruct, OF_CREATE | OF_READWRITE))
        !           345:             == (HFILE)-1) {
        !           346:         Message(MSG_CANTCREATE, pszFullFileName);
        !           347:         goto Error1;
        !           348:     }
        !           349: 
        !           350:     /*
        !           351:      * This is crucial since this helps distinguish a 3.0 icon/cursor
        !           352:      * from an old, old (2.1 format) icon/cursor, which has meaningful
        !           353:      * information in this WORD.
        !           354:      */
        !           355:     IcoCurHdr.iReserved = (WORD)0;
        !           356: 
        !           357:     if (iType == FT_ICON)
        !           358:         IcoCurHdr.iResourceType = 1;        // Icon type.
        !           359:     else
        !           360:         IcoCurHdr.iResourceType = 2;        // Cursor type.
        !           361: 
        !           362:     IcoCurHdr.iResourceCount = (WORD)gnImages;
        !           363: 
        !           364:     /*
        !           365:      * Write the header to disk.
        !           366:      */
        !           367:     if (!MyFileWrite(hf, (LPSTR)&IcoCurHdr, sizeof(ICOCURSORHDR),
        !           368:             pszFullFileName))
        !           369:         goto Error2;
        !           370: 
        !           371:     /*
        !           372:      * Write all the descriptors.
        !           373:      */
        !           374:     iBitsOffset = sizeof(ICOCURSORHDR) + (gnImages * sizeof(ICOCURSORDESC));
        !           375:     for (pImage = gpImageHead; pImage; pImage = pImage->pImageNext) {
        !           376:         IcoCurDesc.iWidth = (BYTE)pImage->cx;
        !           377:         IcoCurDesc.iHeight = (BYTE)pImage->cy;
        !           378:         IcoCurDesc.iColorCount = (giType == FT_ICON) ?
        !           379:                 (BYTE)pImage->nColors : (BYTE)0;
        !           380:         IcoCurDesc.iUnused = 0;
        !           381:         IcoCurDesc.iHotspotX = (WORD)pImage->iHotspotX;
        !           382:         IcoCurDesc.iHotspotY = (WORD)pImage->iHotspotY;
        !           383:         IcoCurDesc.DIBSize = pImage->DIBSize;
        !           384:         IcoCurDesc.DIBOffset = iBitsOffset;
        !           385: 
        !           386:         if (!MyFileWrite(hf, (LPSTR)&IcoCurDesc, sizeof(ICOCURSORDESC),
        !           387:                 pszFullFileName))
        !           388:             goto Error2;
        !           389: 
        !           390:         iBitsOffset += IcoCurDesc.DIBSize;
        !           391:     }
        !           392: 
        !           393:     /*
        !           394:      * Now write the DIB's.
        !           395:      */
        !           396:     for (pImage = gpImageHead; pImage; pImage = pImage->pImageNext) {
        !           397:         if (!MyFileWrite(hf, (LPSTR)pImage->DIBPtr,
        !           398:                 (DWORD)pImage->DIBSize, pszFullFileName))
        !           399:             goto Error2;
        !           400:     }
        !           401: 
        !           402:     _lclose((HFILE)hf);
        !           403: 
        !           404:     fFileDirty = FALSE;
        !           405:     SetFileName(pszFullFileName);
        !           406: 
        !           407:     SetCursor(hcurOld);
        !           408: 
        !           409:     return TRUE;
        !           410: 
        !           411: Error2:
        !           412:     _lclose((HFILE)hf);
        !           413: 
        !           414: Error1:
        !           415:     SetCursor(hcurOld);
        !           416: 
        !           417:     return FALSE;
        !           418: }

unix.superglobalmegacorp.com

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