home *** CD-ROM | disk | FTP | other *** search
/ Programming Tool Box / SIMS_2.iso / vb_tools / manythng / mnythdll.cpp < prev    next >
C/C++ Source or Header  |  1994-08-07  |  14KB  |  582 lines

  1. /*
  2.     Mnythdll.dll -- 7-31-94, Bruce McLean
  3.  
  4.     DLL for manythings screen saver, includes routines:
  5.  
  6.         1) ManyDibLoad -- reads DIB files into memory
  7.         2) ManyGifLoad -- reads GIF files into memory and converting to
  8.                              DIB format
  9.         3) ManyDibWrite -- writes DIB file in memory out to a file
  10.         4) ManyDibModPalette -- adds offsets to colors in palette
  11.         5) ManyDibCyclePalette -- shifts palette entries
  12.         6) ManyLoadLogPal -- retrieves DIB palette into a LOGPALETTE
  13.                                                         structure
  14.         7) ManyDibGet -- returns pointer to DIB in memory
  15.         8) ManyDibGetData -- returns pointer to bitmap data area of DIB in memory
  16.         9) ManyDibFree -- frees memory used by DIB in memory
  17.  
  18.     Warnings --
  19.         C++ by default modifies the names of functions to add parameter type
  20.             information, to make the functions callable by Visual Basic they need
  21.             to be declared as 'extern "C"' and 'pascal _export'.  See Mnythdll.h
  22.             for example.
  23.  
  24.         To use the project file, Directories under the Options menu will have to
  25.             be changed.
  26.  
  27. */
  28.  
  29. #define  STRICT
  30. #include <windows.h>
  31. #include <windowsx.h>
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include "mnythdll.h" // function prototypes for declaring as exported "C"
  35. #include    "bitmaps.h"
  36. #include "gif.h"
  37.  
  38. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  39.  
  40. // static DIB data
  41. BYTE huge * DIBPointer;
  42. int Width,Height;
  43. const int NumColors = 256;
  44.  
  45. // Write DIB to a file from memory, returns 0 on no error
  46. int FAR pascal _export ManyDibWrite (const FAR char * szFileName)
  47. {
  48.     FILE * WriteFile;
  49.  
  50.     if(DIBPointer == NULL)
  51.     {
  52.         return 1;
  53.     }
  54.  
  55.     WriteFile = fopen(szFileName,"wb");
  56.     if(WriteFile == NULL)
  57.     {
  58.         return 2;
  59.     }
  60.  
  61.     // get header pointer
  62.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  63.  
  64.   // get total file size
  65.     unsigned long Size = sizeof(BITMAPFILEHEADER) + BMapHeader->biSize
  66.             + BMapHeader->biClrUsed * sizeof (RGBQUAD) + BMapHeader->biSizeImage;
  67.  
  68.   //write type to file
  69.     fputc('B',WriteFile);
  70.     fputc('M',WriteFile);
  71.  
  72.     fwrite(&Size,4,1,WriteFile); // store file size
  73.  
  74.     // file reserved fields
  75.     fputc(0,WriteFile);
  76.     fputc(0,WriteFile);
  77.     fputc(0,WriteFile);
  78.     fputc(0,WriteFile);
  79.  
  80.     // get offset to data bits
  81.     unsigned long Offset = sizeof(BITMAPFILEHEADER) + BMapHeader->biSize
  82.       + BMapHeader->biClrUsed * sizeof (RGBQUAD);
  83.  
  84.     fwrite(&Offset,4,1,WriteFile); // store file size
  85.  
  86.     //write dib
  87.     const unsigned int WriteMaxSize = 32768u;
  88.     unsigned long DibSize = BMapHeader->biSize + BMapHeader->biSizeImage
  89.         + BMapHeader->biClrUsed * sizeof (RGBQUAD);
  90.     unsigned int BlockSize;
  91.     BYTE huge * OutPointer = DIBPointer;
  92.  
  93.     while(DibSize > 0)
  94.     {
  95.         if(DibSize > WriteMaxSize)
  96.         {
  97.             BlockSize = WriteMaxSize;
  98.         }
  99.         else
  100.         {
  101.             BlockSize = (unsigned int) DibSize;
  102.         }
  103.  
  104.         fwrite(OutPointer,BlockSize,1,WriteFile); // store dib data
  105.  
  106.         DibSize -= BlockSize;
  107.         OutPointer += BlockSize;
  108.  
  109.   } // while end
  110.  
  111.     fclose(WriteFile);
  112.  
  113.     return 0; // success
  114.  
  115. }
  116.  
  117. // Read a dib palette into Logical palette for Vbasic
  118. void pascal _export ManyLoadLogPal (LOGPALETTE & Pal,int Start,int MaxSize,int Flags)
  119. {
  120.     Pal.palVersion = 0x0300;
  121.  
  122.     if( DIBPointer == NULL )
  123.     {
  124.         Pal.palNumEntries = 0;
  125.         return;
  126.     }
  127.  
  128.     // get header pointer
  129.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  130.  
  131.     // get Palette pointer
  132.     BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
  133.  
  134.     BYTE huge * BPtr;
  135.  
  136.     Pal.palNumEntries = BMapHeader->biClrUsed;
  137.  
  138.   // check for funny palette size
  139.     if( (Pal.palNumEntries <= 0) || (Pal.palNumEntries >256) )
  140.     {
  141.         Pal.palNumEntries = 0;
  142.         return;
  143.     }
  144.  
  145.     if(Pal.palNumEntries > MaxSize)
  146.     {
  147.         Pal.palNumEntries = MaxSize;
  148.     }
  149.  
  150.     Pal.palNumEntries -= Start; // subtract off entries skipped
  151.  
  152.     // extract palette
  153.     for(int i=0;i<Pal.palNumEntries;i++)
  154.     {
  155.         BPtr = Palette + (i+Start)*4; // get address of palette entry
  156.  
  157.         Pal.palPalEntry[i].peRed = *(BPtr+2);
  158.         Pal.palPalEntry[i].peGreen = *(BPtr+1);
  159.         Pal.palPalEntry[i].peBlue = (*BPtr);
  160.         Pal.palPalEntry[i].peFlags = Flags;
  161.  
  162.         // set flags in palete
  163.         *(BPtr+3) = Flags;
  164.     }
  165. } // end ManyLoadLogPal
  166.  
  167. // Read a GIF from a file into memory
  168. long FAR pascal _export ManyGifLoad (const FAR char * szFileName,int FAR * width,int FAR * height)
  169. {
  170.  
  171.     int i = ManyDibFree();
  172.     if(i != 0) // free memory
  173.     {
  174.         return -6-i; // error codes 1 to n are mapped to -7 to -7-n
  175.   }
  176.  
  177.     // read gif file into memory
  178.     HDIB DibHandle = ReadGifFile(szFileName);
  179.  
  180.     if(DibHandle == NULL)
  181.     {
  182.     return -1;
  183.     }
  184.  
  185.     BITMAPINFOHEADER huge * BMapHeader    = (BITMAPINFOHEADER huge *) GlobalLock(DibHandle);
  186.     DIBPointer = (BYTE huge *) BMapHeader;
  187.  
  188.     if(DIBPointer == NULL)
  189.     {
  190.     return -2;
  191.     }
  192.  
  193.     // check if wrong style dib
  194.     if ((BMapHeader->biSize != 0x28 ) // check for funny header size
  195.          || (BMapHeader->biPlanes != 1)  // check for multiple planes
  196.          || (BMapHeader->biBitCount != 8) // make sure 256 color
  197.          || (BMapHeader->biClrUsed > 256) // check for consistency
  198.          || (BMapHeader->biClrUsed <= 0) ) // check for consistency
  199.     {
  200.         ManyDibFree(); // free memory
  201.         return -5 ;
  202.   }
  203.  
  204.     int Width = (int) BMapHeader->biWidth;
  205.     int Height = (int) BMapHeader->biHeight;
  206.  
  207.     *height = Height;
  208.     *width = Width;
  209.  
  210.     return (long) DIBPointer ;
  211.  
  212. } // end ManyGifLoad
  213.  
  214. // Read a DIB from a file into memory
  215. long FAR pascal _export ManyDibLoad (const FAR char * szFileName,int FAR * width,int FAR * height)
  216. {
  217.   BITMAPFILEHEADER bmfh ;
  218.     DWORD            dwDibSize, dwOffset;
  219.   int              hFile ;
  220.   WORD             wDibRead ;
  221.  
  222.     int i = ManyDibFree();
  223.     if(i != 0) // free memory
  224.     {
  225.         return -6-i; // error codes 1 to n are mapped to -7 to -7-n
  226.   }
  227.  
  228.     // try to open file
  229.     if (-1 == (hFile = _lopen (szFileName, OF_READ | OF_SHARE_DENY_WRITE)))
  230.     {
  231.         return -6 ;
  232.   }
  233.  
  234.   if (_lread (hFile, (LPSTR) &bmfh, sizeof (BITMAPFILEHEADER)) !=
  235.                                                                              sizeof (BITMAPFILEHEADER))
  236.   {
  237.     _lclose (hFile) ;
  238.     return -1 ;
  239.   }
  240.  
  241.   if (bmfh.bfType != * (WORD *) "BM")
  242.   {
  243.     _lclose (hFile) ;
  244.     return -2 ;
  245.   }
  246.  
  247.   dwDibSize = bmfh.bfSize - sizeof (BITMAPFILEHEADER) ;
  248.  
  249.     DIBPointer = (BYTE huge * ) GlobalAllocPtr (GMEM_MOVEABLE, dwDibSize) ;
  250.  
  251.     if (DIBPointer == NULL)
  252.   {
  253.     _lclose (hFile) ;
  254.     return -3 ;
  255.   }
  256.  
  257.   dwOffset = 0 ;
  258.  
  259.   while (dwDibSize > 0)
  260.   {
  261.         wDibRead = (WORD) MIN (32768ul, dwDibSize) ;
  262.  
  263.         if (wDibRead != _lread (hFile, (LPSTR) (DIBPointer + dwOffset), wDibRead))
  264.     {
  265.       _lclose (hFile) ;
  266.             ManyDibFree();
  267.       return -4 ;
  268.     }
  269.  
  270.     dwDibSize -= wDibRead ;
  271.     dwOffset  += wDibRead ;
  272.   }
  273.  
  274.   _lclose (hFile) ;
  275.  
  276.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  277.  
  278.   // check if wrong style dib
  279.     if ((BMapHeader->biSize != 0x28 ) // check for funny header size
  280.          || (BMapHeader->biPlanes != 1)  // check for multiple planes
  281.          || (BMapHeader->biBitCount != 8) // make sure 256 color
  282.          || (BMapHeader->biClrUsed > 256) // check for consistency
  283.          || (BMapHeader->biClrUsed <= 0) ) // check for consistency
  284.     {
  285.         ManyDibFree();
  286.         return -5 ;
  287.   }
  288.  
  289.     Width = (int) BMapHeader->biWidth;
  290.     Height = (int) BMapHeader->biHeight;
  291.  
  292.     *height = Height;
  293.     *width = Width;
  294.  
  295.     return (long) DIBPointer ;
  296. }
  297.  
  298. // returns pointer to memory for DIB data bytes
  299. long FAR pascal _export ManyDibGetData( void )
  300. {
  301.  
  302.     if(DIBPointer == NULL) // see if not allocated
  303.     {
  304.         return NULL;
  305.     }
  306.  
  307.     // get header pointer
  308.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  309.  
  310.     // get Palette pointer
  311.     BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
  312.  
  313.     // get data pointer
  314.     BYTE huge * DataBits = Palette + BMapHeader->biClrUsed * sizeof (RGBQUAD) ;
  315.  
  316.     return (long) DataBits; // no error, return pointer to data
  317.  
  318. }
  319.  
  320. // returns pointer to memory for DIB bitmap, also is pointer to header
  321. long FAR pascal _export ManyDibGet( void )
  322. {
  323.     return (long) DIBPointer; // return pointer
  324. }
  325.  
  326. // frees memory for DIB bitmap, returns 0 if successful
  327. int FAR pascal _export ManyDibFree( void )
  328. {
  329.     if(DIBPointer == NULL) // see if memory allocated
  330.     {
  331.         return 0; // no need to do anything
  332.     }
  333.  
  334.   // try to unlock memory
  335.     //GlobalFreePtr (DIBPointer) ;
  336.     int i = GlobalUnlock(GlobalPtrHandle(DIBPointer));
  337.     if (i != NULL )
  338.     {
  339.         return 2;
  340.     }
  341.  
  342.   // try to free memory
  343.     if(GlobalFree(GlobalPtrHandle(DIBPointer)) != NULL)
  344.     {
  345.         return 3;
  346.     }
  347.  
  348.     DIBPointer = NULL; // clear pointer
  349.   return 0;
  350.  
  351. }
  352.  
  353. // modify all palettes
  354. void FAR pascal _export ManyDibCyclePalette(int StepSize,int LowValue,int HighValue)
  355. {
  356.     if(DIBPointer == NULL) // see if memory allocated
  357.     {
  358.         return; // no need to do anything
  359.     }
  360.  
  361.     // get header pointer
  362.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  363.  
  364.     // get Palette pointer
  365.     BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
  366.  
  367.     // limit values
  368.     if(LowValue<0)
  369.     {
  370.         LowValue = 0;
  371.     }
  372.  
  373.     if(HighValue>BMapHeader->biClrUsed-1)
  374.     {
  375.         HighValue = (int) BMapHeader->biClrUsed-1;
  376.     }
  377.  
  378.     long huge * LPtr;
  379.     int Steps = abs(StepSize);
  380.  
  381.     for(int j = 0;j<Steps;j++)
  382.   {
  383.         if(StepSize>0) // if forward cycling
  384.       {
  385.             LPtr = (long huge *) ( Palette + 4*HighValue);
  386.             long Temp = *LPtr; // save first
  387.  
  388.             for(int i= (int) HighValue;i>0;i--) // change palette
  389.         {
  390.               LPtr = (long huge *) ( Palette + 4*i);
  391.         *LPtr = *(LPtr-1); // shift palette entry down
  392.           }
  393.             LPtr = (long huge *) ( Palette + 4*LowValue);
  394.             *LPtr = Temp; // put in first entry
  395.       }
  396.       else // reverse cycle
  397.     {
  398.             LPtr = (long huge *) ( Palette + 4*LowValue);
  399.             long Temp = *LPtr; // save first
  400.  
  401.             for(int i=LowValue+1;i<=HighValue;i++) // change palette
  402.         {
  403.               LPtr = (long huge *) ( Palette + 4*i);
  404.                 *(LPtr-1) = *(LPtr); // shift palette entry down
  405.           }
  406.             LPtr = (long huge *) ( Palette + 4*HighValue);
  407.       *LPtr = Temp; // put in first entry
  408.         }
  409.  
  410.   } // end for j
  411.  
  412. }
  413.  
  414. // modify all palettes
  415. void FAR pascal _export ManyDibModPalette(int red,int green,int blue)
  416. {
  417.     if(DIBPointer == NULL) // see if memory allocated
  418.     {
  419.         return; // no need to do anything
  420.     }
  421.  
  422.     // get header pointer
  423.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  424.  
  425.     // get Palette pointer
  426.     BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
  427.  
  428.     BYTE huge * BPtr;
  429.  
  430.     for(int i=0;i<BMapHeader->biClrUsed;i++) // change palette
  431.     {
  432.         BPtr = (BYTE huge *) ( Palette + 4*i);
  433.     *(BPtr+2) += red;
  434.         *(BPtr+1) += green;
  435.         *(BPtr) += blue;
  436.   }
  437.  
  438. }
  439.  
  440. // initializes a previously created DIB, returns value less than 10 on error
  441. // else returns pointer to data area
  442. long FAR pascal _export ManyDibInit()
  443. {
  444.   // check for invalid dib
  445.     if(DIBPointer == NULL) // not allocated
  446.     {
  447.     return 1;
  448.     }
  449.     if(Width == 0) // bad size
  450.     {
  451.     return 2;
  452.     }
  453.     if(Height == 0) // bad size
  454.     {
  455.         return 3;
  456.     }
  457.  
  458.   // make sure we have enough room
  459.     long Size = sizeof(BITMAPFILEHEADER) + (long) Width * Height
  460.                                  + NumColors * sizeof (RGBQUAD) ;
  461.     if(Size > GlobalSize(GlobalPtrHandle(DIBPointer)))
  462.     {
  463.         return 4;
  464.     }
  465.  
  466.     BYTE huge * BPtr;
  467.     long huge * LPtr;
  468.  
  469.   // get header pointer
  470.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  471.  
  472.     // get Palette pointer
  473.     BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
  474.  
  475.     // get data pointer
  476.     BYTE huge * DataBits = Palette + BMapHeader->biClrUsed * sizeof (RGBQUAD) ;
  477.  
  478.     for(int i=0;i<BMapHeader->biClrUsed;i++) // initialize palette
  479.     {
  480.         LPtr = (long huge *) ( Palette + 4*i);
  481.         *LPtr = ((long) i<<16) + ((long) i<<8) + i; // store value in palette as long word
  482.   }
  483.  
  484.     // initialize each line
  485.     for(i=0;i<Height;i++)
  486.     {
  487.     // for each column in row
  488.         for(int j=0;j<Width;j++)
  489.         {
  490.             BPtr = DataBits + (long) i * Width + j;
  491.             *BPtr = i+j; // store value in data
  492.     }
  493.     }
  494.  
  495.     return (long) DataBits; // no error, return pointer to data
  496.  
  497. }
  498.  
  499. // creates a 256 color DIB bitmap with dimensions given
  500. long FAR pascal _export ManyDibAlloc( int width,int height )
  501. {
  502.     Width = width; Height = height; // save dimensions
  503.  
  504.     long Size = sizeof (BITMAPFILEHEADER) + (long) width * height
  505.          + NumColors * sizeof (RGBQUAD) + 256;
  506.  
  507.     if(DIBPointer == NULL)
  508.     {
  509.     // allocate necessary memory
  510.         DIBPointer = (BYTE huge * ) GlobalAllocPtr(GMEM_MOVEABLE, Size) ;
  511.     }
  512.     else // now check for insufficient size
  513.     if(Size > GlobalSize(GlobalPtrHandle(DIBPointer)))
  514.     {
  515.         if(ManyDibFree() == 0) // try to free previously allocated mem
  516.         {
  517.             // allocate necessary memory
  518.             DIBPointer = (BYTE huge * ) GlobalAllocPtr(GMEM_MOVEABLE, Size) ;
  519.         }
  520.         else
  521.         {
  522.             Width = 0; Height = 0; // clear dimensions on error
  523.       return 0L;
  524.         }
  525.     }
  526.  
  527.     // return size if allocated
  528.     if (DIBPointer == NULL)
  529.     {
  530.       Width = 0; Height = 0; // clear dimensions on error
  531.         return 0L;
  532.     }
  533.     else // initialize dib and return size of block
  534.     {
  535.     // get header pointer
  536.         BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  537.  
  538.         // initialize header
  539.         BMapHeader->biSize = sizeof(BITMAPINFOHEADER);
  540.         BMapHeader->biWidth = width;
  541.         BMapHeader->biHeight = height;
  542.         BMapHeader->biPlanes = 1;
  543.         BMapHeader->biBitCount = 8; // 8 bits per pixel
  544.         BMapHeader->biCompression = 0; // no compress
  545.         BMapHeader->biSizeImage = (long) width * height;
  546.         BMapHeader->biXPelsPerMeter = 0; // use default
  547.         BMapHeader->biYPelsPerMeter = 0; // use default
  548.         BMapHeader->biClrUsed = NumColors; // number of colors in image
  549.         BMapHeader->biClrImportant = NumColors;
  550.  
  551.         return GlobalSize(GlobalPtrHandle(DIBPointer));
  552.   }
  553. }
  554.  
  555.  
  556. // this procedure is called when DLL initialized
  557. #pragma argsused
  558. int FAR PASCAL LibMain( HINSTANCE hInstance,
  559.             WORD wDataSegment,
  560.             WORD wHeapSize,
  561.             LPSTR lpszCmdLine )
  562. {
  563.   if ( wHeapSize != 0 )
  564.   {
  565.       UnlockData( 0 );
  566.   }
  567.  
  568.     DIBPointer = NULL; // pointer starts out to be NULL
  569.  
  570.   return 1;  
  571. }
  572.  
  573.  
  574.  
  575.  
  576.  
  577. #pragma argsused
  578. int FAR PASCAL WEP ( int bSystemExit )
  579. {
  580. return 1;
  581. }
  582.