home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / wps / graphic / fractint / sources / pmfrsave.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-25  |  14.8 KB  |  535 lines

  1. /*--------------------------------------------------
  2.    PMFRSAVE.C -- FRACTINT for PM
  3.  
  4.       Save Processor
  5.  
  6.       This module contains both the code to write
  7.       GIF, BMP, MET, and PCX files, it also contains
  8.       the code used to put objects on the clipboard.
  9.  
  10.    04/16/91      Code by Donald P. Egen (with help)
  11.  
  12.    This module's first function (SaveDriver) is the
  13.    main save action function.
  14.  
  15.    **** WARNING **** WARNING **** WARNING ****
  16.    The functions in this module dealing with file I/O
  17.    are called as part of the background subthread.
  18.  
  19.    The functions dealing with Clipboard fetching
  20.    are called as part of the main foreground PM thread.
  21.  
  22.    Serialization is something we all hope for.
  23.  
  24.  ---------------------------------------------------*/
  25.  
  26. #define INCL_WIN
  27. #define INCL_GPI
  28. #define INCL_DOS
  29. #define INCL_PM
  30. #include <os2.h>
  31. #include <process.h>
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <setjmp.h>
  35. #include <float.h>
  36. #include <malloc.h>
  37. #include <string.h>
  38. #include <smplhelp.h>
  39.  
  40. #include "pmfract.h"
  41. #include "fractint.h"
  42.  
  43. /* routines in this module */
  44.  
  45. static int SaveDriverGIF(VOID);
  46. static int SaveDriverBMP(VOID);
  47. static int SaveDriverMET(VOID);
  48. static int SaveDriverWin3BMP(VOID);
  49. static int SaveDriverPCX(VOID);
  50.  
  51. extern HAB    habThread;
  52.  
  53. /* engine interface routines and variables */
  54.  
  55. extern int xdots, ydots, colors, maxiter;
  56. extern int ytop, ybottom, xleft, xright;
  57.  
  58. extern int fractype;
  59. extern int invert;
  60.  
  61. extern double ftemp, xxmin, xxmax, yymin, yymax;
  62.  
  63. extern long lm, linitx, linity;
  64. extern int maxit, bitshift, color, row, col;
  65.  
  66. extern int read_overlay(void);
  67. extern int gifview(void);
  68.  
  69. extern char usr_stdcalcmode, stdcalcmode;
  70. extern int  usr_distest, usr_floatflag, usr_periodicitycheck;
  71. extern double param[4];
  72. extern unsigned char trigndx[4];
  73. extern void set_trig_pointers(int which);
  74.  
  75. extern unsigned char dacbox[257][3];
  76. extern int decomp[2];
  77. extern int biomorph, inside, outside;
  78. extern int filexdots, fileydots, filecolors;
  79.  
  80. extern int save_system, save_release, win_release;
  81.  
  82. extern int reallyega;
  83. extern  void updatesavename(char *name);
  84.  
  85. int savetodisk(char *);
  86.  
  87. int  FAR SaveDriver (VOID)
  88.      {
  89.  
  90.      int rc;
  91.  
  92.      /* dispatch based on sub-function - What format? */
  93.  
  94.      switch (cp.sSubFunction)
  95.             {
  96.             case SUB_LOADSAVE_GIF:
  97.                  rc = SaveDriverGIF();
  98.                  break;
  99.  
  100.             case SUB_LOADSAVE_BMP:
  101.                  rc = SaveDriverBMP();
  102.                  break;
  103.  
  104.             case SUB_LOADSAVE_MET:
  105.                  rc = SaveDriverMET();
  106.                  break;
  107.  
  108.             case SUB_LOADSAVE_WIN3BMP:
  109.                  rc = SaveDriverWin3BMP();
  110.                  break;
  111.  
  112.             case SUB_LOADSAVE_PCX:
  113.                  rc = SaveDriverPCX();
  114.                  break;
  115.  
  116.             default:
  117.                  rc = 999;   /* let the caller figure it out */
  118.                  break;
  119.  
  120.             }
  121.  
  122.      /* and go back */
  123.  
  124.      return rc;
  125.  
  126.      }
  127.  
  128. /*--------------------------------------------------
  129.  
  130.  Save a GIF file using the FRACTINT for DOS code.
  131.  
  132.  ---------------------------------------------------*/
  133. static int SaveDriverGIF (VOID)
  134.      {
  135.  
  136.      char achSaveName[128];
  137.  
  138.      unsigned char _far *pcSrc;
  139.      unsigned char _far *pcDest;
  140.      int i;
  141.  
  142.    /* ensure the engine save routine is cognizant of the
  143.       description of the current image */
  144.  
  145.           xdots = filexdots = cp.cx;
  146.           ydots = fileydots = cp.cy;
  147.           usr_floatflag = cp.cFloatflag;
  148.           fractype = cp.iFractType;
  149.           xxmin = cp.XL;
  150.           xxmax = cp.XR;
  151.           yymin = cp.YB;
  152.           yymax = cp.YT;
  153.           xdots = cp.cx;
  154.           ydots = cp.cy;
  155.           param[0] = cp.param[0];
  156.           param[1] = cp.param[1];
  157.           param[2] = cp.param[2];
  158.           param[3] = cp.param[3];
  159.           trigndx[0] = cp.trigndx[0];
  160.           trigndx[1] = cp.trigndx[1];
  161.           trigndx[2] = cp.trigndx[2];
  162.           trigndx[3] = cp.trigndx[3];
  163.           set_trig_pointers(-1);
  164.           colors = cp.colors;
  165.           maxiter = cp.maxiter;
  166.           usr_distest = cp.distest;
  167.           usr_stdcalcmode = cp.stdCalcMode;
  168.           usr_periodicitycheck = cp.periodicitycheck;
  169.           biomorph = cp.biomorph;
  170.           decomp[0] = cp.decomp[0]; decomp[1] = cp.decomp[1];
  171.           inside = cp.inside;
  172.           outside = cp.outside;
  173.  
  174.      /* map the colors from the current selected palette
  175.         into the "dacbox" structure for saving.
  176.  
  177.         Unfortunately, PM uses "BGR", and dacbox uses "RGB"
  178.      */
  179.  
  180.      pcSrc = (unsigned char _far *) &(cp.pbmiMemory->argbColor[0]);
  181.      pcDest = (unsigned char _far *) &dacbox[0][0];
  182.  
  183.      for (i = 0; i < cp.colors; i++)
  184.          {
  185.          pcDest[0] = pcSrc[2] >> 2U;
  186.          pcDest[1] = pcSrc[1] >> 2U;
  187.          pcDest[2] = pcSrc[0] >> 2U;
  188.  
  189.          pcSrc += 3;
  190.          pcDest += 3;
  191.          }
  192.  
  193.      /* the following turns off the expected palette translation
  194.         in the save code if it thinks it has a physical VGA
  195.         running in 16 color mode.  The flag "reallyega" turns
  196.         off this translation.
  197.      */
  198.      reallyega = (cp.colors == 16) ? 1 : 0;
  199.  
  200.      _fstrcpy(achSaveName, cp.szFileName);
  201.  
  202.      save_system = 1;
  203.      save_release = win_release;
  204.      savetodisk(achSaveName);
  205.  
  206.      /* save the updated name for next time */
  207.      _fstrcpy(cp.szFileName, achSaveName);
  208.  
  209.      return (SUB_STAT_OK);
  210.      }
  211.  
  212. /*--------------------------------------------------
  213.  
  214.  Save a BMP file in OS/2 1.1/1.2/1.3 format.
  215.  
  216.  ---------------------------------------------------*/
  217. static int SaveDriverBMP(VOID)
  218.      {
  219.  
  220.      BITMAPFILEHEADER bfhIt;
  221.      HFILE hfileIt;
  222.      USHORT usIOAction;
  223.      LONG cbBitSize;
  224.      unsigned char _huge *hp;
  225.      char achSaveName[128];
  226.  
  227.      cbBitSize = (LONG) cp.pm_xbytes * (LONG) cp.cy;
  228.      _fstrcpy(achSaveName, cp.szFileName);
  229.  
  230.      /* initialize the new bitmapfileheader */
  231.      bfhIt.usType = BFT_BMAP;
  232.      bfhIt.offBits = sizeof(BITMAPFILEHEADER) + cp.colors * sizeof(RGB);
  233.      bfhIt.xHotspot = 0;
  234.      bfhIt.yHotspot = 0;
  235.      bfhIt.cbSize = bfhIt.offBits + cbBitSize;
  236.  
  237.      /* Now open the file */
  238.      if ( 0 != DosOpen(cp.szFileName, &hfileIt, &usIOAction,
  239.                            bfhIt.cbSize, FILE_NORMAL,
  240.                            FILE_TRUNCATE | FILE_CREATE,
  241.                            OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYNONE, 0L) )
  242.         {
  243.         return SUB_STAT_ABORT;
  244.         }
  245.  
  246.      /* write the file header */
  247.      if (0 != DosWrite(hfileIt, &bfhIt,
  248.                        sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER),
  249.                        &usIOAction) )
  250.         {
  251.         DosClose(hfileIt);
  252.         return SUB_STAT_ABORT;
  253.         }
  254.  
  255.      /* next, the bitmap infoheader and color table */
  256.      if (0 != DosWrite(hfileIt, cp.pbmiMemory,
  257.                        sizeof(BITMAPINFOHEADER) + cp.colors * sizeof(RGB),
  258.                        &usIOAction) )
  259.         {
  260.         DosClose(hfileIt);
  261.         return SUB_STAT_ABORT;
  262.         }
  263.  
  264.      /* now blow out the actual bits */
  265.      /* write out (up to) 32K at a time */
  266.      hp = cp.pixels;
  267.      while(cbBitSize > 0)
  268.         {
  269.         if (0 != DosWrite(hfileIt,
  270.                     (PVOID) hp,
  271.                     (cbBitSize > 0x8000L) ? 0x8000 : (USHORT) cbBitSize,
  272.                     &usIOAction) )
  273.            {
  274.            DosClose(hfileIt);
  275.            return SUB_STAT_ABORT;
  276.            }
  277.            hp += 0x8000L;
  278.            cbBitSize -= 0x8000L;
  279.         }
  280.  
  281.      DosClose(hfileIt);
  282.  
  283.      /* save the updated name for next time */
  284.      updatesavename(achSaveName);
  285.      _fstrcpy(cp.szFileName, achSaveName);
  286.  
  287.      /* and go home */
  288.      return (SUB_STAT_OK);
  289.      }
  290.  
  291. static int SaveDriverMET(VOID)
  292.      {
  293.  
  294.      /* and go home */
  295.      return (SUB_STAT_FATAL);
  296.      }
  297.  
  298.   /* ------------------------------------------------------------------ */
  299.  
  300.   /* The following structures map the Windows 3.0 bitmap file format. */
  301.  
  302. typedef struct tagRGBQUAD {
  303.         CHAR    rgbBlue;
  304.         CHAR    rgbGreen;
  305.         CHAR    rgbRed;
  306.         CHAR    rgbReserved;
  307. } RGBQUAD;
  308.  
  309. typedef struct tagBITMAPINFOHEADER{
  310.         ULONG      biSize;
  311.         ULONG      biWidth;
  312.         ULONG      biHeight;
  313.         USHORT     biPlanes;
  314.         USHORT     biBitCount;
  315.  
  316.         ULONG      biCompression;
  317.         ULONG      biSizeImage;
  318.         ULONG      biXPelsPerMeter;
  319.         ULONG      biYPelsPerMeter;
  320.         ULONG      biClrUsed;
  321.         ULONG      biClrImportant;
  322. } W3BITMAPINFOHEADER;
  323.  
  324. /*--------------------------------------------------
  325.  
  326.  Save a BMP file in Windows 3.0 format (maybe also
  327.  the OS/2 2.0 format?)
  328.  
  329.  ---------------------------------------------------*/
  330. static int SaveDriverWin3BMP(VOID)
  331.      {
  332.  
  333.      BITMAPFILEHEADER bfhIt;
  334.      W3BITMAPINFOHEADER bmpIt3;
  335.      HFILE hfileIt;
  336.      USHORT usIOAction;
  337.      LONG cbBitSize;
  338.      RGB _far *prgb1;
  339.      unsigned char _huge *hp;
  340.      char achSaveName[128];
  341.      int i;
  342.      char Zero = '\0';
  343.  
  344.      cbBitSize = (LONG) cp.pm_xbytes * (LONG) cp.cy;
  345.      _fstrcpy(achSaveName, cp.szFileName);
  346.  
  347.      /* initialize the new bitmapfileheader */
  348.      bfhIt.usType = BFT_BMAP;
  349.      bfhIt.offBits = sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER)
  350.                     + sizeof(W3BITMAPINFOHEADER)
  351.                     + cp.colors * sizeof(RGBQUAD);
  352.      bfhIt.xHotspot = 0;
  353.      bfhIt.yHotspot = 0;
  354.      bfhIt.cbSize = bfhIt.offBits + cbBitSize;
  355.  
  356.      /* initialize the Windows 3.0 bitmapinfoheader */
  357.      bmpIt3.biSize = sizeof(W3BITMAPINFOHEADER);
  358.      bmpIt3.biWidth = cp.cx;
  359.      bmpIt3.biHeight = cp.cy;
  360.      bmpIt3.biPlanes = cp.pbmiMemory->cPlanes;
  361.      bmpIt3.biBitCount = cp.pbmiMemory->cBitCount;
  362.      bmpIt3.biCompression = 0;  /* default the other trash */
  363.      bmpIt3.biSizeImage = 0;
  364.      bmpIt3.biXPelsPerMeter = 0;
  365.      bmpIt3.biYPelsPerMeter = 0;
  366.      bmpIt3.biClrUsed = 0;
  367.      bmpIt3.biClrImportant = 0;
  368.  
  369.      /* Now open the file */
  370.      if ( 0 != DosOpen(cp.szFileName, &hfileIt, &usIOAction,
  371.                            bfhIt.cbSize, FILE_NORMAL,
  372.                            FILE_TRUNCATE | FILE_CREATE,
  373.                            OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYNONE, 0L) )
  374.         {
  375.         return SUB_STAT_ABORT;
  376.         }
  377.  
  378.      /* write the file header */
  379.      if (0 != DosWrite(hfileIt, &bfhIt,
  380.                        sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER),
  381.                        &usIOAction) )
  382.         {
  383.         DosClose(hfileIt);
  384.         return SUB_STAT_ABORT;
  385.         }
  386.  
  387.      /* next, the bitmap infoheader */
  388.      if (0 != DosWrite(hfileIt, &bmpIt3,
  389.                        sizeof(W3BITMAPINFOHEADER),
  390.                        &usIOAction) )
  391.         {
  392.         DosClose(hfileIt);
  393.         return SUB_STAT_ABORT;
  394.         }
  395.  
  396.      /* now the color table.
  397.         need to go from 3 bytes/entry to 4 bytes/entry */
  398.  
  399.      prgb1 = &cp.pbmiMemory->argbColor[0];
  400.  
  401.      for (i = 0; i < cp.colors; i++)
  402.          {
  403.                     /* write R G B */
  404.          if (0 != DosWrite(hfileIt, &prgb1[i], sizeof(RGB), &usIOAction) )
  405.             {
  406.             DosClose(hfileIt);
  407.             return SUB_STAT_ABORT;
  408.             }
  409.          /* then insert a zero byte */
  410.          if (0 != DosWrite(hfileIt, &Zero, 1, &usIOAction) )
  411.             {
  412.             DosClose(hfileIt);
  413.             return SUB_STAT_ABORT;
  414.             }
  415.          }
  416.  
  417.      /* now blow out the actual bits */
  418.      /* write out (up to) 32K at a time */
  419.      hp = cp.pixels;
  420.      while(cbBitSize > 0)
  421.         {
  422.         if (0 != DosWrite(hfileIt,
  423.                     (PVOID) hp,
  424.                     (cbBitSize > 0x8000L) ? 0x8000 : (USHORT) cbBitSize,
  425.                     &usIOAction) )
  426.            {
  427.            DosClose(hfileIt);
  428.            return SUB_STAT_ABORT;
  429.            }
  430.            hp += 0x8000L;
  431.            cbBitSize -= 0x8000L;
  432.         }
  433.  
  434.      DosClose(hfileIt);
  435.  
  436.      /* save the updated name for next time */
  437.      updatesavename(achSaveName);
  438.      _fstrcpy(cp.szFileName, achSaveName);
  439.  
  440.      /* and go home */
  441.      return (SUB_STAT_OK);
  442.      }
  443.  
  444. static int SaveDriverPCX(VOID)
  445.      {
  446.  
  447.      /* and go home */
  448.      return (SUB_STAT_FATAL);
  449.      }
  450.  
  451. /* --------------------------------------------------------------------- */
  452.  
  453. /* --------------------------------------------------------
  454.    This routine puts a bitmap on the PM Clipboard from
  455.    our internal bitmap.
  456.    -------------------------------------------------------- */
  457.  
  458. VOID PMfrWriteClipbrdBmp(HAB hab)
  459.    {
  460.  
  461.    HDC hdcClip;         /* memory DC and PS to extract from the clipboard */
  462.    HPS hpsClip;
  463.    HBITMAP hbmClip;
  464.    SIZEL sizl;
  465.    BITMAPINFOHEADER bmp;
  466.    ULONG _far *alRGBColors;
  467.    LONG errorcode;
  468.    char _far *fp1;
  469.    char _far *fp2;
  470.    int i;
  471.  
  472.    if (WinOpenClipbrd(hab))
  473.       {
  474.       /* get the memory DC and PS to copy the bitmap */
  475.       hdcClip = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  476.  
  477.       sizl.cx = cp.cx; sizl.cy = cp.cy;
  478.  
  479.       hpsClip = GpiCreatePS (hab, hdcClip, &sizl,
  480.                    PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC);
  481.  
  482.       bmp.cbFix   = sizeof bmp;
  483.       bmp.cx      = cp.cx;
  484.       bmp.cy      = cp.cy;
  485.       bmp.cPlanes = cp.cPlanes;
  486.       bmp.cBitCount = cp.cBitCount;
  487.       hbmClip = GpiCreateBitmap (hpsClip, &bmp, 0L, NULL, NULL);
  488.  
  489.       GpiSetBitmap(hpsClip, hbmClip);
  490.  
  491.       /* initialize and black out the bitmap */
  492.       alRGBColors = (ULONG _far *) _fmalloc(sizeof(ULONG) * cp.colors);
  493.       /* beginning of source array */
  494.       fp2 = (char _far *) &cp.pbmiMemory->argbColor[0];
  495.       /* beginning of dest array */
  496.       fp1 = (char _far *) &alRGBColors[0];
  497.       for (i = 0; i < cp.colors; i++)
  498.           {   /* copy base bytes for number of screen colors */
  499.           alRGBColors[i] = 0;
  500.           _fmemcpy(fp1, fp2, sizeof(RGB) );
  501.           fp1 += sizeof(ULONG);
  502.           fp2 += sizeof(RGB);
  503.           }
  504.  
  505.       GpiSetMix ( hpsClip, FM_OVERPAINT) ;
  506.       GpiSetBackMix (hpsClip, BM_LEAVEALONE) ;
  507.       GpiCreateLogColorTable(hpsClip, LCOL_RESET | LCOL_REALIZABLE,
  508.               LCOLF_CONSECRGB, 0L, cp.colors, alRGBColors);
  509.  
  510.       /* now copy the bits */
  511.       cp.pbmiMemory->cx = cp.cx;
  512.       cp.pbmiMemory->cy = cp.cy;
  513.       cp.pbmiMemory->cPlanes = cp.cPlanes;
  514.       cp.pbmiMemory->cBitCount = cp.cBitCount;
  515.       errorcode = GpiSetBitmapBits(hpsClip, 0L, (LONG) cp.cy,
  516.                                 cp.pixels, cp.pbmiMemory);
  517.  
  518.       /* unlink the new bitmap */
  519.       GpiSetBitmap(hpsClip, (HBITMAP) NULL);
  520.  
  521.       /* write to the clipboard */
  522.       WinEmptyClipbrd (hab);
  523.       WinSetClipbrdData (hab, (ULONG) hbmClip, CF_BITMAP, CFI_HANDLE);
  524.  
  525.       /* now clean up */
  526.  
  527.       _ffree(alRGBColors);
  528.       GpiDestroyPS(hpsClip);
  529.       DevCloseDC(hdcClip);
  530.  
  531.       WinCloseClipbrd(hab);
  532.       }
  533.  
  534.    }
  535.