home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / imagedit / rwbmp.c < prev    next >
Text File  |  1996-06-12  |  8KB  |  263 lines

  1.     /****************************************************************************/
  2.     /*                                                                          */
  3.     /*                 Copyright (C) 1987-1996 Microsoft Corp.                */
  4.     /*                           All Rights Reserved                            */
  5.     /*                                                                          */
  6.     /****************************************************************************/
  7.     /****************************** Module Header *******************************
  8.     * Module Name: rwbmp.c
  9.     *
  10.     * Routines for reading and writing bitmap files.
  11.     *
  12.     * History:
  13.     *
  14.     ****************************************************************************/
  15.     
  16.     #include "imagedit.h"
  17.     
  18.     #include <stdio.h>
  19.     #include <io.h>
  20.     #include <fcntl.h>                          // For NT fstat().
  21.     #include <sys\types.h>                      // For fstat() types.
  22.     #include <sys\stat.h>                       // For fstat() function.
  23.     
  24.     
  25.     
  26.     /************************************************************************
  27.     * LoadBitmapFile
  28.     *
  29.     * Loads the specified bitmap file.  With ImagEdit, this must be a
  30.     * Windows 3.0 DIB.
  31.     *
  32.     * Arguments:
  33.     *   PSTR pszFullFileName - Name of the bitmap file to load.
  34.     *
  35.     * Returns:
  36.     *   TRUE if successful, FALSE otherwise.
  37.     *
  38.     * History:
  39.     *
  40.     ************************************************************************/
  41.     
  42.     BOOL LoadBitmapFile(
  43.         PSTR pszFullFileName)
  44.     {
  45.         HFILE hf;
  46.         OFSTRUCT OfStruct;
  47.         struct stat FileStatus;
  48.         DWORD dwFileSize;
  49.         DWORD dwDIBSize;
  50.         BITMAPFILEHEADER bfh;
  51.         BITMAPINFOHEADER bih;
  52.         PIMAGEINFO pImage;
  53.         INT nColors;
  54.         HANDLE hDIB;
  55.         PDEVICE pDevice;
  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.         /*
  69.          * Read the Bitmap File Header.
  70.          */
  71.         if (!MyFileRead(hf, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER),
  72.                 pszFullFileName, FT_BITMAP))
  73.             goto Error1;
  74.     
  75.         /*
  76.          * Check for the "BM" at the start of the file, and the file size
  77.          * in the header must match the real file size.
  78.          */
  79.         if (bfh.bfType != 0x4D42 || bfh.bfSize != dwFileSize) {
  80.             Message(MSG_BADBMPFILE, pszFullFileName);
  81.             goto Error1;
  82.         }
  83.     
  84.         /*
  85.          * Read the Bitmap Info Header.
  86.          */
  87.         if (!MyFileRead(hf, (LPSTR)&bih, sizeof(BITMAPINFOHEADER),
  88.                 pszFullFileName, FT_BITMAP))
  89.             goto Error1;
  90.     
  91.         /*
  92.          * The DIB size should be the size of the file less the bitmap
  93.          * file header.
  94.          */
  95.         dwDIBSize = dwFileSize - sizeof(BITMAPFILEHEADER);
  96.     
  97.         if (!IsValidDIB((LPBITMAPINFO)&bih, dwDIBSize, FALSE)) {
  98.             Message(MSG_BADBMPFILE, pszFullFileName);
  99.             goto Error1;
  100.         }
  101.     
  102.         /*
  103.          * There is a limit to the size of image we will edit.  For icons
  104.          * and cursors, the field that carries the dimensions is a byte,
  105.          * so the size cannot be greater than 256.  This is also what
  106.          * we limit bitmaps to.
  107.          */
  108.         if (bih.biWidth > MAXIMAGEDIM || bih.biHeight > MAXIMAGEDIM) {
  109.             Message(MSG_BADBMPSIZE, MAXIMAGEDIM, MAXIMAGEDIM);
  110.             goto Error1;
  111.         }
  112.     
  113.         switch (bih.biBitCount) {
  114.             case 1:
  115.                 nColors = 2;
  116.                 break;
  117.     
  118.             case 4:
  119.                 nColors = 16;
  120.                 break;
  121.     
  122.             default:
  123.                 Message(MSG_NOTSUPPORT);
  124.                 goto Error1;
  125.         }
  126.     
  127.         if (!(pDevice = DeviceLinkAlloc(FT_BITMAP, NULL, nColors,
  128.                 (INT)bih.biWidth, (INT)bih.biHeight))) {
  129.             goto Error1;
  130.         }
  131.     
  132.         if (!(pImage = ImageLinkAlloc(pDevice,
  133.                 (INT)bih.biWidth, (INT)bih.biHeight, 0, 0, nColors)))
  134.             goto Error1;
  135.     
  136.         /*
  137.          * Allocate space for the DIB for this image.
  138.          */
  139.         if (!(hDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwDIBSize))) {
  140.             Message(MSG_OUTOFMEMORY);
  141.             goto Error2;
  142.         }
  143.     
  144.         pImage->DIBSize = dwDIBSize;
  145.         pImage->DIBhandle = hDIB;
  146.         pImage->DIBPtr = (LPSTR)GlobalLock(hDIB);
  147.     
  148.         /*
  149.          * Jump back to the start of the DIB.
  150.          */
  151.         SetFilePointer((HANDLE)hf, sizeof(BITMAPFILEHEADER), NULL, (DWORD)0);
  152.     
  153.         /*
  154.          * Read the entire DIB (including info and color table) into
  155.          * the allocated memory for it.
  156.          */
  157.         if (!MyFileRead(hf, pImage->DIBPtr, (DWORD)pImage->DIBSize,
  158.                 pszFullFileName, FT_BITMAP))
  159.             goto Error2;
  160.     
  161.         _lclose((HFILE)hf);
  162.     
  163.         fFileDirty = FALSE;
  164.         SetFileName(pszFullFileName);
  165.         giType = FT_BITMAP;
  166.     
  167.         /*
  168.          * Bitmaps only have one "image" in the file.
  169.          */
  170.         gnImages = 1;
  171.     
  172.         ImageOpen2(pImage);
  173.     
  174.         return TRUE;
  175.     
  176.     Error2:
  177.         ImageLinkFreeList();
  178.     
  179.     Error1:
  180.         _lclose((HFILE)hf);
  181.     
  182.         return FALSE;
  183.     }
  184.     
  185.     
  186.     
  187.     /************************************************************************
  188.     * SaveBitmapFile
  189.     *
  190.     *
  191.     *
  192.     * Arguments:
  193.     *
  194.     * Returns:
  195.     *   TRUE if successful, FALSE otherwise.
  196.     *
  197.     * History:
  198.     *
  199.     ************************************************************************/
  200.     
  201.     BOOL SaveBitmapFile(
  202.         PSTR pszFullFileName)
  203.     {
  204.         HCURSOR hcurOld;
  205.         BITMAPFILEHEADER bfh;
  206.         HFILE hf;
  207.         OFSTRUCT OfStruct;
  208.     
  209.         hcurOld = SetCursor(hcurWait);
  210.     
  211.         /*
  212.          * Save the bits of the current image.
  213.          */
  214.         ImageSave();
  215.     
  216.         /*
  217.          * Open the file for writing.
  218.          */
  219.         if ((hf = (HFILE)OpenFile(pszFullFileName, &OfStruct, OF_CREATE | OF_READWRITE))
  220.                 == (HFILE)-1) {
  221.             Message(MSG_CANTCREATE, pszFullFileName);
  222.             goto Error1;
  223.         }
  224.     
  225.         bfh.bfType = 0x4D42;
  226.         bfh.bfSize = sizeof(BITMAPFILEHEADER) + gpImageCur->DIBSize;
  227.         bfh.bfReserved1 = 0;
  228.         bfh.bfReserved2 = 0;
  229.         bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  230.                 (gpImageCur->nColors * sizeof(RGBQUAD));
  231.     
  232.         /*
  233.          * Write the header to disk.
  234.          */
  235.         if (!MyFileWrite(hf, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER),
  236.                 pszFullFileName))
  237.             goto Error2;
  238.     
  239.         /*
  240.          * Now write the DIB (a bitmap file only has one).
  241.          */
  242.         if (!MyFileWrite(hf, (LPSTR)gpImageCur->DIBPtr,
  243.                 (DWORD)gpImageCur->DIBSize, pszFullFileName))
  244.             goto Error2;
  245.     
  246.         _lclose((HFILE)hf);
  247.     
  248.         fFileDirty = FALSE;
  249.         SetFileName(pszFullFileName);
  250.     
  251.         SetCursor(hcurOld);
  252.     
  253.         return TRUE;
  254.     
  255.     Error2:
  256.         _lclose((HFILE)hf);
  257.     
  258.     Error1:
  259.         SetCursor(hcurOld);
  260.     
  261.         return FALSE;
  262.     }
  263.