home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / WINDOWS / PROGRAM / WINSRC20.ZIP / LOADFILE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-18  |  16.9 KB  |  567 lines

  1. /*
  2.     loadfile.c - load an existing fractal image, control level
  3.     This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  4. */
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "fractint.h"
  10. #include "fractype.h"
  11. #include "targa_lc.h"
  12.  
  13. /* routines in this module    */
  14.  
  15. void loadfile_overlay(void);
  16. int  read_overlay(void);
  17.  
  18. static int  find_fractal_info(char *,struct fractal_info *);
  19. static void load_ext_blk(char far *loadptr,int loadlen);
  20. static void skip_ext_blk(int *,int *);
  21. static void backwardscompat();
  22.  
  23. int filetype;
  24.  
  25. extern int    showfile;         /* has file been displayed yet? */
  26. extern char   readname[];        /* name of fractal input file */
  27. extern char   far *resume_info;     /* pointer to resume info if alloc'd */
  28. extern int    resume_len;        /* length of resume info */
  29. extern int    adapter;
  30. extern int    calc_status;
  31. extern int    initmode;         /* initial video mode        */
  32. extern long   calctime;
  33. extern int    initbatch;        /* 1 if batch run (no kbd)  */
  34. extern int    maxit;
  35. extern int    initincr;         /* maxiter incrmnt        */
  36. extern char   usr_stdcalcmode;        /* pass mode            */
  37. extern int    fractype;         /* fractal type         */
  38. extern double xxmin,xxmax;        /* corner values        */
  39. extern double yymin,yymax;        /* corner values        */
  40. extern double xx3rd,yy3rd;        /* corner values        */
  41. extern double param[4];         /* parameters            */
  42. extern int    inside;            /* inside color: 1=blue     */
  43. extern int    outside;            /* outside color, if set    */
  44. extern int    finattract;        /* finite attractor option  */
  45. extern int    forcesymmetry;
  46. extern int    LogFlag;            /* non-zero if logarithmic palettes */
  47. extern int    rflag, rseed;
  48. extern int    usr_periodicitycheck;
  49. extern char   useinitorbit;
  50. extern struct complex initorbit;
  51. extern int    potflag;            /* continuous potential flag */
  52. extern int    pot16bit;
  53. extern double potparam[3];        /* three potential parameters*/
  54. extern double inversion[];
  55. extern int    decomp[];
  56. extern int    usr_distest;        /* non-zero if distance estimator   */
  57. extern int    init3d[20];        /* '3d=nn/nn/nn/...' values */
  58. extern char   usr_floatflag;        /* floating-point fractals? */
  59. extern int    biomorph;
  60. extern char   FormName[];
  61. extern int    bailout;            /* user input bailout value */
  62. extern int    previewfactor;
  63. extern int    xtrans;
  64. extern int    ytrans;
  65. extern int    red_crop_left;
  66. extern int    red_crop_right;
  67. extern int    blue_crop_left;
  68. extern int    blue_crop_right;
  69. extern int    red_bright;
  70. extern int    blue_bright;
  71. extern int    xadjust;
  72. extern int    eyeseparation;
  73. extern int    glassestype;
  74. extern int    display3d;        /* 3D display flag: 0 = OFF */
  75. extern int    overlay3d;        /* 3D overlay flag: 0 = OFF */
  76. extern int    viewwindow;        /* 0 for full screen, 1 for window */
  77. extern float  viewreduction;        /* window auto-sizing */
  78. extern float  finalaspectratio;     /* for view shape and rotation */
  79. extern int    viewxdots,viewydots;    /* explicit view sizing */
  80. extern int    save_system,save_release;
  81.  
  82. static FILE *fp;
  83.  
  84. int fileydots, filexdots, filecolors;
  85. float fileaspectratio;
  86.  
  87. int skipxdots,skipydots;    /* for decoder, when reducing image */
  88.  
  89.  
  90. void loadfile_overlay() { }    /* for restore_active_ovly */
  91.  
  92.  
  93. int read_overlay()    /* read overlay/3D files, if reqr'd */
  94. {
  95.    struct fractal_info read_info;
  96.    char oldfloatflag;
  97.    char msg[110];
  98.  
  99.    ENTER_OVLY(OVLY_LOADFILE);
  100.  
  101.    showfile = 1;        /* for any abort exit, pretend done */
  102.    initmode = -1;        /* no viewing mode set yet */
  103.    oldfloatflag = usr_floatflag;
  104.  
  105.    if(find_fractal_info(readname,&read_info)) { /* didn't find a useable file */
  106.       sprintf(msg,"Sorry, %s isn't a file I can decode.",readname);
  107.       stopmsg(1,msg);
  108.       EXIT_OVLY;
  109.       return(-1);
  110.       }
  111.  
  112.    maxit    = read_info.iterations;
  113.    fractype    = read_info.fractal_type;
  114.    xxmin    = read_info.xmin;
  115.    xxmax    = read_info.xmax;
  116.    yymin    = read_info.ymin;
  117.    yymax    = read_info.ymax;
  118.    param[0]    = read_info.creal;
  119.    param[1]    = read_info.cimag;
  120.    save_release = 1100; /* unless we find out better later on */
  121.  
  122.    if(read_info.version > 0) {
  123.       param[2]        = read_info.parm3;
  124.       param[3]        = read_info.parm4;
  125.       potparam[0]   = read_info.potential[0];
  126.       potparam[1]   = read_info.potential[1];
  127.       potparam[2]   = read_info.potential[2];
  128.       potflag        = (potparam[0] != 0.0);
  129.       rflag        = read_info.rflag;
  130.       rseed        = read_info.rseed;
  131.       inside        = read_info.inside;
  132.       LogFlag        = read_info.logmap;
  133.       inversion[0]  = read_info.invert[0];
  134.       inversion[1]  = read_info.invert[1];
  135.       inversion[2]  = read_info.invert[2];
  136.       decomp[0]     = read_info.decomp[0];
  137.       decomp[1]     = read_info.decomp[1];
  138.       biomorph        = read_info.biomorph;
  139.       forcesymmetry = read_info.symmetry;
  140.       }
  141.  
  142.    if(read_info.version > 1) {
  143.       save_release  = 1200;
  144.       if (!display3d) {
  145.      int i;
  146.      for (i = 0; i < 16; i++)
  147.         init3d[i] = read_info.init3d[i];
  148.      previewfactor     = read_info.previewfactor;
  149.      xtrans      = read_info.xtrans;
  150.      ytrans      = read_info.ytrans;
  151.      red_crop_left     = read_info.red_crop_left;
  152.      red_crop_right  = read_info.red_crop_right;
  153.      blue_crop_left  = read_info.blue_crop_left;
  154.      blue_crop_right = read_info.blue_crop_right;
  155.      red_bright     = read_info.red_bright;
  156.      blue_bright     = read_info.blue_bright;
  157.      xadjust     = read_info.xadjust;
  158.      eyeseparation     = read_info.eyeseparation;
  159.      glassestype     = read_info.glassestype;
  160.      }
  161.       }
  162.  
  163.    if(read_info.version > 2) {
  164.       save_release = 1300;
  165.       outside       = read_info.outside;
  166.       }
  167.  
  168.    calc_status = 0;      /* defaults if version < 4 */
  169.    xx3rd = xxmin;
  170.    yy3rd = yymin;
  171.    usr_distest = 0;
  172.    calctime = 0;
  173.    if(read_info.version > 3) {
  174.       save_release = 1400;
  175.       xx3rd      = read_info.x3rd;
  176.       yy3rd      = read_info.y3rd;
  177.       calc_status = read_info.calc_status;
  178.       usr_stdcalcmode = read_info.stdcalcmode;
  179.       usr_distest     = read_info.distest;
  180.       usr_floatflag   = read_info.floatflag;
  181.       bailout      = read_info.bailout;
  182.       calctime      = read_info.calctime;
  183.       trigndx[0]  = read_info.trigndx[0];
  184.       trigndx[1]  = read_info.trigndx[1];
  185.       trigndx[2]  = read_info.trigndx[2];
  186.       trigndx[3]  = read_info.trigndx[3];
  187.       finattract  = read_info.finattract;
  188.       initorbit.x = read_info.initorbit[0];
  189.       initorbit.y = read_info.initorbit[1];
  190.       useinitorbit = read_info.useinitorbit;
  191.       usr_periodicitycheck = read_info.periodicity;
  192.       }
  193.  
  194.    pot16bit = 0;
  195.    save_system = 0;
  196.    if(read_info.version > 4) {
  197.       pot16bit       = read_info.pot16bit;
  198.       if (pot16bit)
  199.      filexdots >>= 1;
  200.       fileaspectratio = read_info.faspectratio;
  201.       if (fileaspectratio < 0.01)    /* fix files produced in early v14.1 */
  202.      fileaspectratio = SCREENASPECT;
  203.       save_system  = read_info.system;
  204.       save_release = read_info.release; /* from fmt 5 on we know real number */
  205.       if (read_info.version == 5    /* except a few early fmt 5 cases: */
  206.       && (save_release <= 0 || save_release >= 2000)) {
  207.      save_release = 1410;
  208.      save_system = 0;
  209.      }
  210.       }
  211.  
  212.    if(read_info.version < 4) { /* pre-version 14.0? */
  213.       backwardscompat(&read_info); /* translate obsolete types */
  214.       if(LogFlag)
  215.      LogFlag = 2;
  216.       usr_floatflag = (fractalspecific[fractype].isinteger) ? 0 : 1;
  217.       }
  218.  
  219.    if(read_info.version < 5) { /* pre-version 15.0? */
  220.       if(LogFlag == 2) /* logmap=old changed again in format 5! */
  221.      LogFlag = -1;
  222.       }
  223.  
  224.    fractalspecific[fractype].paramvalue[0] = param[0];
  225.    fractalspecific[fractype].paramvalue[1] = param[1];
  226.    fractalspecific[fractype].paramvalue[2] = param[2];
  227.    fractalspecific[fractype].paramvalue[3] = param[3];
  228.    set_trig_pointers(-1);
  229.  
  230.    if (display3d)            /* PB - a klooge till the meaning of */
  231.       usr_floatflag = oldfloatflag; /*    floatflag in line3d is clarified */
  232.  
  233.    if (overlay3d)
  234.       initmode = adapter;       /* use previous adapter mode for overlays */
  235.    else
  236.       if (get_video_mode(&read_info)) {
  237.      EXIT_OVLY;
  238.      initmode = -1;
  239.      return(-1);
  240.      }
  241.  
  242.    if (display3d) {
  243.       calc_status = 0;
  244.       fractype = PLASMA;
  245.       param[0] = 0;
  246.       if (!initbatch)
  247.      if (get_3d_params() < 0) {
  248.         EXIT_OVLY;
  249.         initmode = -1;
  250.         return(-1);
  251.         }
  252.       }
  253.  
  254.    showfile = 0;           /* trigger the file load */
  255.  
  256.    EXIT_OVLY;
  257.    return(0);
  258. }
  259.  
  260.  
  261. static int find_fractal_info(gif_file,info)
  262. char *gif_file;
  263. struct fractal_info *info;
  264. {
  265.    unsigned char gifstart[18];
  266.    char temp1[81];
  267.    int scan_extend, block_type, block_len, data_len;
  268.    int fractinf_len;
  269.    int hdr_offset;
  270.    int i;
  271.  
  272.    if((fp = fopen(gif_file,"rb"))==NULL)
  273.       return(-1);
  274.  
  275.    fread(gifstart,18,1,fp);
  276.    if (strncmp(gifstart,"GIF",3)!=0) { /* not GIF, maybe old .tga? */
  277.       if(fread(info,sizeof(struct fractal_info),1,fp)==1 &&
  278.          strncmp(info->info_id,"Fractal",8)==0) {
  279.      filetype = 1; /* Targa 16 */
  280.      fileydots = *(int *)&gifstart[O_VSIZE];
  281.      filexdots = *(int *)&gifstart[O_HSIZE];
  282.      filecolors = info->colors;
  283.      fileaspectratio = SCREENASPECT;
  284.      if(fileydots == info->ydots && filexdots == info->xdots) {
  285.         fclose(fp);
  286.         return(0);
  287.         }
  288.      }
  289.       fclose(fp);
  290.       return(-1);
  291.       }
  292.  
  293.    filetype = 0; /* GIF */
  294.    filexdots = gifstart[7]*256+gifstart[6];
  295.    fileydots = gifstart[9]*256+gifstart[8];
  296.    filecolors = 2 << (gifstart[10] & 7);
  297.    fileaspectratio = 0; /* unknown */
  298.    if (gifstart[12]) { /* calc reasonably close value from gif header */
  299.       fileaspectratio = (64.0 / ((double)(gifstart[12]) + 15.0))
  300.               * (double)fileydots / (double)filexdots;
  301.       if ( fileaspectratio > SCREENASPECT-0.03
  302.     && fileaspectratio < SCREENASPECT+0.03)
  303.      fileaspectratio = SCREENASPECT;
  304.       }
  305.    else
  306.       if (fileydots * 4 == filexdots * 3) /* assume the common square pixels */
  307.      fileaspectratio = SCREENASPECT;
  308.  
  309.    if (resume_info != NULL) { /* free the prior area if there is one */
  310.       farmemfree(resume_info);
  311.       resume_info = NULL;
  312.       }
  313.  
  314.    /* Format of .gif extension blocks is:
  315.       1 byte    '!', extension block identifier
  316.       1 byte    extension block number, 255
  317.       1 byte    length of id, 11
  318.      11 bytes   alpha id, "fractintnnn" with fractint, nnn is secondary id
  319.        n * {
  320.       1 byte    length of block info in bytes
  321.       x bytes   block info
  322.        }
  323.       1 byte    0, extension terminator
  324.       To scan extension blocks, we first look in file at length of fractal_info
  325.       (the main extension block) from end of file, looking for a literal known
  326.       to be at start of our block info.  Then we scan forward a bit, in case
  327.       the file is from an earlier fractint vsn with shorter fractal_info.
  328.       If fractal_info is found and is from vsn>=14, it includes the total length
  329.       of all extension blocks; we then scan them all first to last to load
  330.       any optional ones which are present.
  331.       Defined extension blocks:
  332.     fractint001    header, always present
  333.     fractint002    resume info for interrupted resumable image
  334.     fractint003    additional formula type info
  335.    */
  336.  
  337.    memset(info,0,sizeof(FRACTAL_INFO));
  338.    fractinf_len = sizeof(FRACTAL_INFO) + (sizeof(FRACTAL_INFO)+254)/255;
  339.    fseek(fp,(long)(-1-fractinf_len),SEEK_END);
  340.    fread(info,1,sizeof(FRACTAL_INFO),fp);
  341.    if (strcmp(INFO_ID,info->info_id) == 0)
  342.       hdr_offset = -1-fractinf_len;
  343.    else {
  344.       /* didn't work 1st try, maybe an older vsn, maybe junk at eof, scan: */
  345.       int offset,i;
  346.       char tmpbuf[110];
  347.       hdr_offset = 0;
  348.       offset = 80; /* don't even check last 80 bytes of file for id */
  349.       while (offset < fractinf_len+513) { /* allow 512 garbage at eof */
  350.      offset += 100; /* go back 100 bytes at a time */
  351.      fseek(fp,(long)(0-offset),SEEK_END);
  352.      fread(tmpbuf,1,110,fp); /* read 10 extra for string compare */
  353.      for (i = 0; i < 100; ++i)
  354.         if (!strcmp(INFO_ID,&tmpbuf[i])) { /* found header? */
  355.            strcpy(info->info_id,INFO_ID);
  356.            fseek(fp,(long)(hdr_offset=i-offset),SEEK_END);
  357.            fread(info,1,sizeof(FRACTAL_INFO),fp);
  358.            offset = 10000; /* force exit from outer loop */
  359.            break;
  360.            }
  361.      }
  362.       }
  363.  
  364.    if (hdr_offset) { /* we found INFO_ID */
  365.  
  366.       if (info->version >= 4) {
  367.      /* first reload main extension block, reasons:
  368.           might be over 255 chars, and thus earlier load might be bad
  369.           find exact endpoint, so scan back to start of ext blks works
  370.         */
  371.      fseek(fp,(long)(hdr_offset-15),SEEK_END);
  372.      scan_extend = 1;
  373.      while (scan_extend) {
  374.         if (fgetc(fp) != '!' /* if not what we expect just give up */
  375.           || fread(temp1,1,13,fp) != 13
  376.           || strncmp(&temp1[2],"fractint",8))
  377.            break;
  378.         temp1[13] = 0;
  379.         block_type = atoi(&temp1[10]); /* e.g. "fractint002" */
  380.         switch (block_type) {
  381.            case 1: /* "fractint001", the main extension block */
  382.           if (scan_extend == 2) { /* we've been here before, done now */
  383.              scan_extend = 0;
  384.              break;
  385.              }
  386.           load_ext_blk((char far *)info,sizeof(FRACTAL_INFO));
  387.           scan_extend = 2;
  388.           /* now we know total extension len, back up to first block */
  389.           fseek(fp,0L-info->tot_extend_len,SEEK_CUR);
  390.           break;
  391.            case 2: /* resume info */
  392.           skip_ext_blk(&block_len,&data_len); /* once to get lengths */
  393.           if ((resume_info = farmemalloc((long)data_len)) == NULL)
  394.              info->calc_status = 3; /* not resumable after all */
  395.           else {
  396.              fseek(fp,(long)(0-block_len),SEEK_CUR);
  397.              load_ext_blk(resume_info,data_len);
  398.              resume_len = data_len;
  399.              }
  400.           break;
  401.            case 3: /* formula info */
  402.           load_ext_blk(FormName,40);
  403.           /* perhaps in future add more here, check block_len for
  404.              backward compatibility */
  405.           break;
  406.            default:
  407.           skip_ext_blk(&block_len,&data_len);
  408.            }
  409.         }
  410.      }
  411.  
  412.       fclose(fp);
  413.       fileaspectratio = SCREENASPECT; /* if not >= v15, this is correct */
  414.       return(0);
  415.       }
  416.  
  417.    strcpy(info->info_id, "GIFFILE");
  418.    info->iterations = 150;
  419.    info->fractal_type = PLASMA;
  420.    info->xmin = -1;
  421.    info->xmax = 1;
  422.    info->ymin = -1;
  423.    info->ymax = 1;
  424.    info->x3rd = -1;
  425.    info->y3rd = -1;
  426.    info->creal = 0;
  427.    info->cimag = 0;
  428.    info->videomodeax=255;
  429.    info->videomodebx=255;
  430.    info->videomodecx=255;
  431.    info->videomodedx=255;
  432.    info->dotmode = 0;
  433.    info->xdots = filexdots;
  434.    info->ydots = fileydots;
  435.    info->colors = filecolors;
  436.    info->version = 0; /* this forces lots more init at calling end too */
  437.  
  438.    /* zero means we won */
  439.    fclose(fp);
  440.    return(0);
  441. }
  442.  
  443. static void load_ext_blk(char far *loadptr,int loadlen)
  444. {
  445.    int len;
  446.    while ((len = fgetc(fp)) > 0) {
  447.       while (--len >= 0) {
  448.      if (--loadlen >= 0)
  449.         *(loadptr++) = fgetc(fp);
  450.      else
  451.         fgetc(fp); /* discard excess characters */
  452.      }
  453.       }
  454. }
  455.  
  456. static void skip_ext_blk(int *block_len, int *data_len)
  457. {
  458.    int len;
  459.    *data_len = 0;
  460.    *block_len = 1;
  461.    while ((len = fgetc(fp)) > 0) {
  462.       fseek(fp,(long)len,SEEK_CUR);
  463.       *data_len += len;
  464.       *block_len += len + 1;
  465.       }
  466. }
  467.  
  468.  
  469. /* switch obsolete fractal types to new generalizations */
  470. static void backwardscompat(struct fractal_info *info)
  471. {
  472.    switch(fractype) {
  473.       case LAMBDASINE:
  474.      fractype = LAMBDATRIGFP;
  475.      trigndx[0] = SIN;
  476.      break;
  477.       case LAMBDACOS    :
  478.      fractype = LAMBDATRIGFP;
  479.      trigndx[0] = COS;
  480.      break;
  481.       case LAMBDAEXP    :
  482.      fractype = LAMBDATRIGFP;
  483.      trigndx[0] = EXP;
  484.      break;
  485.       case MANDELSINE    :
  486.      fractype = MANDELTRIGFP;
  487.      trigndx[0] = SIN;
  488.      break;
  489.       case MANDELCOS    :
  490.      fractype = MANDELTRIGFP;
  491.      trigndx[0] = COS;
  492.      break;
  493.       case MANDELEXP    :
  494.      fractype = MANDELTRIGFP;
  495.      trigndx[0] = EXP;
  496.      break;
  497.       case MANDELSINH    :
  498.      fractype = MANDELTRIGFP;
  499.      trigndx[0] = SINH;
  500.      break;
  501.       case LAMBDASINH    :
  502.      fractype = LAMBDATRIGFP;
  503.      trigndx[0] = SINH;
  504.      break;
  505.       case MANDELCOSH    :
  506.      fractype = MANDELTRIGFP;
  507.      trigndx[0] = COSH;
  508.      break;
  509.       case LAMBDACOSH    :
  510.      fractype = LAMBDATRIGFP;
  511.      trigndx[0] = COSH;
  512.      break;
  513.       case LMANDELSINE    :
  514.      fractype = MANDELTRIG;
  515.      trigndx[0] = SIN;
  516.      break;
  517.       case LLAMBDASINE    :
  518.      fractype = LAMBDATRIG;
  519.      trigndx[0] = SIN;
  520.      break;
  521.       case LMANDELCOS    :
  522.      fractype = MANDELTRIG;
  523.      trigndx[0] = COS;
  524.      break;
  525.       case LLAMBDACOS    :
  526.      fractype = LAMBDATRIG;
  527.      trigndx[0] = COS;
  528.      break;
  529.       case LMANDELSINH    :
  530.      fractype = MANDELTRIG;
  531.      trigndx[0] = SINH;
  532.      break;
  533.       case LLAMBDASINH    :
  534.      fractype = LAMBDATRIG;
  535.      trigndx[0] = SINH;
  536.      break;
  537.       case LMANDELCOSH    :
  538.      fractype = MANDELTRIG;
  539.      trigndx[0] = COSH;
  540.      break;
  541.       case LLAMBDACOSH    :
  542.      fractype = LAMBDATRIG;
  543.      trigndx[0] = COSH;
  544.      break;
  545.       case LMANDELEXP    :
  546.      fractype = MANDELTRIG;
  547.      trigndx[0] = EXP;
  548.      break;
  549.       case LLAMBDAEXP    :
  550.      fractype = LAMBDATRIG;
  551.      trigndx[0] = EXP;
  552.      break;
  553.       case DEMM     :
  554.      fractype = MANDELFP;
  555.      usr_distest = (info->ydots - 1) * 2;
  556.      break;
  557.       case DEMJ     :
  558.      fractype = JULIAFP;
  559.      usr_distest = (info->ydots - 1) * 2;
  560.      break;
  561.       case MANDELLAMBDA :
  562.      useinitorbit = 2;
  563.      break;
  564.       }
  565. }
  566.  
  567.