home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / frasrc18.zip / LOADFILE.C < prev    next >
C/C++ Source or Header  |  1993-03-28  |  23KB  |  772 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. #ifdef XFRACT
  10. #include <unistd.h>
  11. #endif
  12. #include "fractint.h"
  13. #include "fractype.h"
  14. #include "targa_lc.h"
  15. #include "prototyp.h"
  16.  
  17. /* routines in this module    */
  18.  
  19. static int  find_fractal_info(char *,struct fractal_info *);
  20. static void load_ext_blk(char far *loadptr,int loadlen);
  21. static void skip_ext_blk(int *,int *);
  22. static void backwardscompat();
  23.  
  24. int filetype;
  25. int loaded3d;
  26.  
  27. extern char   maxfn;                    /* num trig functions if formula */
  28. extern int    showfile;         /* has file been displayed yet? */
  29. extern char   readname[];        /* name of fractal input file */
  30. extern char   far *resume_info;     /* pointer to resume info if alloc'd */
  31. extern int    resume_len;        /* length of resume info */
  32. extern int    adapter;
  33. extern int    calc_status;
  34. extern int    initmode;         /* initial video mode        */
  35. extern long   calctime;
  36. extern int    initbatch;        /* 1 if batch run (no kbd)  */
  37. extern int    maxit;
  38. extern int    initincr;         /* maxiter incrmnt        */
  39. extern char   usr_stdcalcmode;        /* pass mode            */
  40. extern int    fractype;         /* fractal type         */
  41. extern double xxmin,xxmax;        /* corner values        */
  42. extern double yymin,yymax;        /* corner values        */
  43. extern double xx3rd,yy3rd;        /* corner values        */
  44. extern double param[];             /* parameters            */
  45. extern int    fillcolor;        /* fill color: -1 = normal  */
  46. extern int    inside;            /* inside color: 1=blue     */
  47. extern int    outside;            /* outside color, if set    */
  48. extern int    finattract;        /* finite attractor option  */
  49. extern int    forcesymmetry;
  50. extern int    LogFlag;            /* non-zero if logarithmic palettes */
  51. extern int    rflag, rseed;
  52. extern int    usr_periodicitycheck;
  53. extern char   useinitorbit;
  54. extern _CMPLX initorbit;
  55. extern int    potflag;            /* continuous potential flag */
  56. extern int    pot16bit;
  57. extern double potparam[3];        /* three potential parameters*/
  58. extern double inversion[];
  59. extern int    decomp[];
  60. extern int    usr_distest;        /* non-zero if distance estimator   */
  61. extern int    distestwidth;
  62. extern int    init3d[20];        /* '3d=nn/nn/nn/...' values */
  63. extern char   usr_floatflag;        /* floating-point fractals? */
  64. extern char   floatflag;
  65. extern int    usr_biomorph;
  66. extern char   FormName[];
  67. extern char   LName[];
  68. extern char   IFSName[];
  69. extern int    bailout;            /* user input bailout value */
  70. extern int    previewfactor;
  71. extern int    xtrans;
  72. extern int    ytrans;
  73. extern int    red_crop_left;
  74. extern int    red_crop_right;
  75. extern int    blue_crop_left;
  76. extern int    blue_crop_right;
  77. extern int    red_bright;
  78. extern int    blue_bright;
  79. extern int    xadjust;
  80. extern int    eyeseparation;
  81. extern int    glassestype;
  82. extern int    display3d;        /* 3D display flag: 0 = OFF */
  83. extern int    overlay3d;        /* 3D overlay flag: 0 = OFF */
  84. extern int    viewwindow;        /* 0 for full screen, 1 for window */
  85. extern float  viewreduction;        /* window auto-sizing */
  86. extern float  finalaspectratio;     /* for view shape and rotation */
  87. extern int    xdots, ydots;        /* # of dots on the logical screen */
  88. extern int    viewxdots,viewydots;    /* explicit view sizing */
  89. extern int    save_system,save_release;
  90. extern int    Ambient;
  91. extern int    RANDOMIZE;
  92. extern int    haze;
  93. extern int    transparent[2];
  94. extern int    rotate_lo,rotate_hi;
  95. extern int far *ranges;
  96. extern int    rangeslen;
  97. extern int    invert;
  98. extern int    num_fractal_types;
  99. extern float  screenaspect;
  100. extern     double mxmaxfp;
  101. extern     double mxminfp;
  102. extern     double mymaxfp;
  103. extern     double myminfp;
  104. extern     int   zdots;
  105. extern     float originfp;
  106. extern     float depthfp;
  107. extern     float heightfp;
  108. extern     float widthfp;
  109. extern     float distfp;
  110. extern     float eyesfp;
  111. extern     int   neworbittype;
  112. extern     short juli3Dmode;
  113. extern     int   major_method;  /* inverse julia method */
  114. extern     int   minor_method;
  115.  
  116. static FILE *fp;
  117.  
  118. int fileydots, filexdots, filecolors;
  119. float fileaspectratio;
  120.  
  121. int skipxdots,skipydots;    /* for decoder, when reducing image */
  122.  
  123.  
  124. void loadfile_overlay() { }    /* for restore_active_ovly */
  125.  
  126. #ifdef XFRACT
  127. extern int decode_fractal_info();
  128. #endif
  129.  
  130. int read_overlay()    /* read overlay/3D files, if reqr'd */
  131. {
  132.    struct fractal_info read_info;
  133.    char oldfloatflag;
  134.    char msg[110];
  135.  
  136.    ENTER_OVLY(OVLY_LOADFILE);
  137.  
  138.    showfile = 1;        /* for any abort exit, pretend done */
  139.    initmode = -1;        /* no viewing mode set yet */
  140.    oldfloatflag = usr_floatflag;
  141.    loaded3d = 0;
  142.  
  143.    if(strchr(readname,'.') == NULL)
  144.       strcat(readname,".gif");
  145.  
  146.    if(find_fractal_info(readname,&read_info)) { /* didn't find a useable file */
  147.       sprintf(msg,"Sorry, %s isn't a file I can decode.",readname);
  148.       stopmsg(0,msg);
  149.       EXIT_OVLY;
  150.       return(-1);
  151.       }
  152.  
  153.    maxit    = read_info.iterations;
  154.    fractype    = read_info.fractal_type;
  155.    if (fractype < 0 || fractype >= num_fractal_types) {
  156.       sprintf(msg,"Warning: %s has a bad fractal type; using 0",readname);
  157.       fractype = 0;
  158.    }
  159.    curfractalspecific = &fractalspecific[fractype];
  160.    xxmin    = read_info.xmin;
  161.    xxmax    = read_info.xmax;
  162.    yymin    = read_info.ymin;
  163.    yymax    = read_info.ymax;
  164.    param[0]    = read_info.creal;
  165.    param[1]    = read_info.cimag;
  166.    save_release = 1100; /* unless we find out better later on */
  167.  
  168.    invert = 0;
  169.    if(read_info.version > 0) {
  170.       param[2]        = read_info.parm3;
  171.       roundfloatd(¶m[2]);
  172.       param[3]        = read_info.parm4;
  173.       roundfloatd(¶m[3]);
  174.       potparam[0]   = read_info.potential[0];
  175.       potparam[1]   = read_info.potential[1];
  176.       potparam[2]   = read_info.potential[2];
  177.       potflag        = (potparam[0] != 0.0);
  178.       rflag        = read_info.rflag;
  179.       rseed        = read_info.rseed;
  180.       inside        = read_info.inside;
  181.       LogFlag        = read_info.logmap;
  182.       inversion[0]  = read_info.invert[0];
  183.       inversion[1]  = read_info.invert[1];
  184.       inversion[2]  = read_info.invert[2];
  185.       if (inversion[0] != 0.0)
  186.      invert = 3;
  187.       decomp[0]     = read_info.decomp[0];
  188.       decomp[1]     = read_info.decomp[1];
  189.       usr_biomorph  = read_info.biomorph;
  190.       forcesymmetry = read_info.symmetry;
  191.       }
  192.  
  193.    if(read_info.version > 1) {
  194.       save_release  = 1200;
  195.       if (!display3d
  196.     && (read_info.version <= 4 || read_info.flag3d > 0
  197.         || (curfractalspecific->flags&PARMS3D) )) {
  198.      int i;
  199.      for (i = 0; i < 16; i++)
  200.         init3d[i] = read_info.init3d[i];
  201.      previewfactor     = read_info.previewfactor;
  202.      xtrans      = read_info.xtrans;
  203.      ytrans      = read_info.ytrans;
  204.      red_crop_left     = read_info.red_crop_left;
  205.      red_crop_right  = read_info.red_crop_right;
  206.      blue_crop_left  = read_info.blue_crop_left;
  207.      blue_crop_right = read_info.blue_crop_right;
  208.      red_bright     = read_info.red_bright;
  209.      blue_bright     = read_info.blue_bright;
  210.      xadjust     = read_info.xadjust;
  211.      eyeseparation     = read_info.eyeseparation;
  212.      glassestype     = read_info.glassestype;
  213.      }
  214.       }
  215.  
  216.    if(read_info.version > 2) {
  217.       save_release = 1300;
  218.       outside       = read_info.outside;
  219.       }
  220.  
  221.    calc_status = 0;      /* defaults if version < 4 */
  222.    xx3rd = xxmin;
  223.    yy3rd = yymin;
  224.    usr_distest = 0;
  225.    calctime = 0;
  226.    if(read_info.version > 3) {
  227.       save_release = 1400;
  228.       xx3rd      = read_info.x3rd;
  229.       yy3rd      = read_info.y3rd;
  230.       calc_status = read_info.calc_status;
  231.       usr_stdcalcmode = read_info.stdcalcmode;
  232.       usr_distest     = read_info.distest;
  233.       usr_floatflag   = read_info.floatflag;
  234.       bailout      = read_info.bailout;
  235.       calctime      = read_info.calctime;
  236.       trigndx[0]  = read_info.trigndx[0];
  237.       trigndx[1]  = read_info.trigndx[1];
  238.       trigndx[2]  = read_info.trigndx[2];
  239.       trigndx[3]  = read_info.trigndx[3];
  240.       finattract  = read_info.finattract;
  241.       initorbit.x = read_info.initorbit[0];
  242.       initorbit.y = read_info.initorbit[1];
  243.       useinitorbit = read_info.useinitorbit;
  244.       usr_periodicitycheck = read_info.periodicity;
  245.       }
  246.  
  247.    pot16bit = 0;
  248.    save_system = 0;
  249.    if(read_info.version > 4) {
  250.       pot16bit       = read_info.pot16bit;
  251.       if (pot16bit)
  252.      filexdots >>= 1;
  253.       fileaspectratio = read_info.faspectratio;
  254.       if (fileaspectratio < 0.01)    /* fix files produced in early v14.1 */
  255.      fileaspectratio = screenaspect;
  256.       save_system  = read_info.system;
  257.       save_release = read_info.release; /* from fmt 5 on we know real number */
  258.       if (read_info.version == 5    /* except a few early fmt 5 cases: */
  259.       && (save_release <= 0 || save_release >= 2000)) {
  260.      save_release = 1410;
  261.      save_system = 0;
  262.      }
  263.       if (!display3d && read_info.flag3d > 0) {
  264.      loaded3d    = 1;
  265.      Ambient    = read_info.ambient;
  266.      RANDOMIZE    = read_info.randomize;
  267.      haze        = read_info.haze;
  268.      transparent[0] = read_info.transparent[0];
  269.      transparent[1] = read_info.transparent[1];
  270.      }
  271.       }
  272.  
  273.    rotate_lo = 1; rotate_hi = 255;
  274.    distestwidth = 71;
  275.    if(read_info.version > 5) {
  276.       rotate_lo     = read_info.rotate_lo;
  277.       rotate_hi     = read_info.rotate_hi;
  278.       distestwidth    = read_info.distestwidth;
  279.       }
  280.  
  281.    if(read_info.version > 6) {
  282.       param[2]        = read_info.dparm3;
  283.       param[3]        = read_info.dparm4;
  284.       }
  285.  
  286.    if(read_info.version > 7) {
  287.       fillcolor        = read_info.fillcolor;
  288.       }
  289.  
  290.    if(read_info.version > 8) {
  291.    mxmaxfp   =  read_info.mxmaxfp        ;
  292.    mxminfp   =  read_info.mxminfp        ;
  293.    mymaxfp   =  read_info.mymaxfp        ;
  294.    myminfp   =  read_info.myminfp        ;
  295.    zdots     =  read_info.zdots          ;        
  296.    originfp  =  read_info.originfp       ;
  297.    depthfp   =  read_info.depthfp        ;    
  298.    heightfp  =  read_info.heightfp       ;
  299.    widthfp   =  read_info.widthfp        ;    
  300.    distfp    =  read_info.distfp         ;    
  301.    eyesfp    =  read_info.eyesfp         ;    
  302.    neworbittype = read_info.orbittype    ;
  303.    juli3Dmode   = read_info.juli3Dmode   ;
  304.    maxfn    =   read_info.maxfn          ;
  305.    major_method = read_info.inversejulia >> 8;
  306.    minor_method = read_info.inversejulia & 255;
  307.    param[4] = read_info.dparm5;
  308.    param[5] = read_info.dparm6;
  309.    param[6] = read_info.dparm7;
  310.    param[7] = read_info.dparm8;
  311.    param[8] = read_info.dparm9;
  312.    param[9] = read_info.dparm10;
  313.       }
  314.  
  315.    if(read_info.version < 4) { /* pre-version 14.0? */
  316.       backwardscompat(&read_info); /* translate obsolete types */
  317.       if(LogFlag)
  318.      LogFlag = 2;
  319.       usr_floatflag = (curfractalspecific->isinteger) ? 0 : 1;
  320.       }
  321.  
  322.    if (read_info.version < 5) { /* pre-version 15.0? */
  323.       if (LogFlag == 2) /* logmap=old changed again in format 5! */
  324.      LogFlag = -1;
  325.       if (decomp[0] > 0 && decomp[1] > 0)
  326.      bailout = decomp[1];
  327.       }
  328.    if(potflag) /* in version 15.x and 16.x logmap didn't work with pot */
  329.       if(read_info.version == 6 || read_info.version == 7)
  330.          LogFlag = 0;
  331.    set_trig_pointers(-1);
  332.  
  333.    if(read_info.version < 9) { /* pre-version 18.0? */
  334.       /* forcesymmetry==1000 means we want to force symmetry but don't
  335.          know which symmetry yet, will find out in setsymmetry() */
  336.       if(outside==REAL || outside==IMAG || outside==MULT || outside==SUM)
  337.          if(forcesymmetry == 999)
  338.             forcesymmetry = 1000;
  339.       }
  340.    if(save_release < 1725) { /* pre-version 17.25 */
  341.       set_if_old_bif(); /* translate bifurcation types */
  342.    }
  343.  
  344.    if (display3d)            /* PB - a klooge till the meaning of */
  345.       usr_floatflag = oldfloatflag; /*    floatflag in line3d is clarified */
  346.  
  347.    if (overlay3d) {
  348.       initmode = adapter;       /* use previous adapter mode for overlays */
  349.       if (filexdots > xdots || fileydots > ydots) {
  350.      static char far msg[]={"Can't overlay with a larger image"};
  351.      stopmsg(0,msg);
  352.      EXIT_OVLY;
  353.      initmode = -1;
  354.      return(-1);
  355.      }
  356.       }
  357.    else {
  358.       int olddisplay3d,oldfloatflag,i;
  359.       olddisplay3d = display3d;
  360.       oldfloatflag = floatflag;
  361.       display3d = loaded3d;      /* for <tab> display during next */
  362.       floatflag = usr_floatflag; /* ditto */
  363.       i = get_video_mode(&read_info);
  364.       display3d = olddisplay3d;
  365.       floatflag = oldfloatflag;
  366.       if (i) {
  367.      EXIT_OVLY;
  368.      initmode = -1;
  369.      return(-1);
  370.      }
  371.       }
  372.  
  373.    if (display3d) {
  374.       calc_status = 0;
  375.       fractype = PLASMA;
  376.       curfractalspecific = &fractalspecific[PLASMA];
  377.       param[0] = 0;
  378.       if (!initbatch)
  379.      if (get_3d_params() < 0) {
  380.         EXIT_OVLY;
  381.         initmode = -1;
  382.         return(-1);
  383.         }
  384.       }
  385.  
  386.    showfile = 0;           /* trigger the file load */
  387.  
  388.    EXIT_OVLY;
  389.    return(0);
  390. }
  391.  
  392.  
  393. static int find_fractal_info(gif_file,info)
  394. char *gif_file;
  395. struct fractal_info *info;
  396. {
  397.    BYTE gifstart[18];
  398.    char temp1[81];
  399.    int scan_extend, block_type, block_len, data_len;
  400.    int fractinf_len;
  401.    int hdr_offset;
  402.  
  403.    if((fp = fopen(gif_file,"rb"))==NULL)
  404.       return(-1);
  405.  
  406.    fread(gifstart,18,1,fp);
  407. #ifndef XFRACT
  408.    if (strncmp(gifstart,"GIF",3)!=0) { /* not GIF, maybe old .tga? */
  409. #else
  410.    if (strncmp((char *)gifstart,"GIF",3)!=0) { /* not GIF, maybe old .tga? */
  411. #endif
  412.       if(fread(info,FRACTAL_INFO_SIZE,1,fp)==1 &&
  413.          strncmp(info->info_id,"Fractal",8)==0) {
  414.      filetype = 1; /* Targa 16 */
  415.      GET16(gifstart[O_VSIZE],fileydots);
  416.      GET16(gifstart[O_HSIZE],filexdots);
  417.      filecolors = info->colors;
  418.      fileaspectratio = screenaspect;
  419.      if(fileydots == info->ydots && filexdots == info->xdots) {
  420.         fclose(fp);
  421.         return(0);
  422.         }
  423.      }
  424.       fclose(fp);
  425.       return(-1);
  426.       }
  427.  
  428.    filetype = 0; /* GIF */
  429.    GET16(gifstart[6],filexdots);
  430.    GET16(gifstart[8],fileydots);
  431.    filecolors = 2 << (gifstart[10] & 7);
  432.    fileaspectratio = 0; /* unknown */
  433.    if (gifstart[12]) { /* calc reasonably close value from gif header */
  434.       fileaspectratio = (64.0 / ((double)(gifstart[12]) + 15.0))
  435.               * (double)fileydots / (double)filexdots;
  436.       if ( fileaspectratio > screenaspect-0.03
  437.     && fileaspectratio < screenaspect+0.03)
  438.      fileaspectratio = screenaspect;
  439.       }
  440.    else
  441.       if (fileydots * 4 == filexdots * 3) /* assume the common square pixels */
  442.      fileaspectratio = screenaspect;
  443.  
  444.    if (resume_info != NULL) { /* free the prior area if there is one */
  445.       farmemfree(resume_info);
  446.       resume_info = NULL;
  447.       }
  448.    if (rangeslen) { /* free prior ranges */
  449.       farmemfree((char far *)ranges);
  450.       rangeslen = 0;
  451.       }
  452.  
  453.    /* Format of .gif extension blocks is:
  454.       1 byte    '!', extension block identifier
  455.       1 byte    extension block number, 255
  456.       1 byte    length of id, 11
  457.      11 bytes   alpha id, "fractintnnn" with fractint, nnn is secondary id
  458.        n * {
  459.       1 byte    length of block info in bytes
  460.       x bytes   block info
  461.        }
  462.       1 byte    0, extension terminator
  463.       To scan extension blocks, we first look in file at length of fractal_info
  464.       (the main extension block) from end of file, looking for a literal known
  465.       to be at start of our block info.  Then we scan forward a bit, in case
  466.       the file is from an earlier fractint vsn with shorter fractal_info.
  467.       If fractal_info is found and is from vsn>=14, it includes the total length
  468.       of all extension blocks; we then scan them all first to last to load
  469.       any optional ones which are present.
  470.       Defined extension blocks:
  471.     fractint001    header, always present
  472.     fractint002    resume info for interrupted resumable image
  473.     fractint003    additional formula type info
  474.     fractint004    ranges info
  475.    */
  476.  
  477.    memset(info,0,FRACTAL_INFO_SIZE);
  478.    fractinf_len = FRACTAL_INFO_SIZE + (FRACTAL_INFO_SIZE+254)/255;
  479.    fseek(fp,(long)(-1-fractinf_len),SEEK_END);
  480.    fread(info,1,FRACTAL_INFO_SIZE,fp);
  481.    if (strcmp(INFO_ID,info->info_id) == 0) {
  482. #ifdef XFRACT
  483.        decode_fractal_info(info,1);
  484. #endif
  485.       hdr_offset = -1-fractinf_len;
  486.    } else {
  487.       /* didn't work 1st try, maybe an older vsn, maybe junk at eof, scan: */
  488.       int offset,i;
  489.       char tmpbuf[110];
  490.       hdr_offset = 0;
  491.       offset = 80; /* don't even check last 80 bytes of file for id */
  492.       while (offset < fractinf_len+513) { /* allow 512 garbage at eof */
  493.      offset += 100; /* go back 100 bytes at a time */
  494.      fseek(fp,(long)(0-offset),SEEK_END);
  495.      fread(tmpbuf,1,110,fp); /* read 10 extra for string compare */
  496.      for (i = 0; i < 100; ++i)
  497.         if (!strcmp(INFO_ID,&tmpbuf[i])) { /* found header? */
  498.            strcpy(info->info_id,INFO_ID);
  499.            fseek(fp,(long)(hdr_offset=i-offset),SEEK_END);
  500.            fread(info,1,FRACTAL_INFO_SIZE,fp);
  501. #ifdef XFRACT
  502.            decode_fractal_info(info,1);
  503. #endif
  504.            offset = 10000; /* force exit from outer loop */
  505.            break;
  506.            }
  507.      }
  508.       }
  509.  
  510.    if (hdr_offset) { /* we found INFO_ID */
  511.  
  512.       if (info->version >= 4) {
  513.      /* first reload main extension block, reasons:
  514.           might be over 255 chars, and thus earlier load might be bad
  515.           find exact endpoint, so scan back to start of ext blks works
  516.         */
  517.      fseek(fp,(long)(hdr_offset-15),SEEK_END);
  518.      scan_extend = 1;
  519.      while (scan_extend) {
  520.         if (fgetc(fp) != '!' /* if not what we expect just give up */
  521.           || fread(temp1,1,13,fp) != 13
  522.           || strncmp(&temp1[2],"fractint",8))
  523.            break;
  524.         temp1[13] = 0;
  525.         block_type = atoi(&temp1[10]); /* e.g. "fractint002" */
  526.         switch (block_type) {
  527.            case 1: /* "fractint001", the main extension block */
  528.           if (scan_extend == 2) { /* we've been here before, done now */
  529.              scan_extend = 0;
  530.              break;
  531.              }
  532.           load_ext_blk((char far *)info,FRACTAL_INFO_SIZE);
  533. #ifdef XFRACT
  534.           decode_fractal_info(info,1);
  535. #endif
  536.           scan_extend = 2;
  537.           /* now we know total extension len, back up to first block */
  538.           fseek(fp,0L-info->tot_extend_len,SEEK_CUR);
  539.           break;
  540.            case 2: /* resume info */
  541.           skip_ext_blk(&block_len,&data_len); /* once to get lengths */
  542.           if ((resume_info = farmemalloc((long)data_len)) == NULL)
  543.              info->calc_status = 3; /* not resumable after all */
  544.           else {
  545.              fseek(fp,(long)(0-block_len),SEEK_CUR);
  546.              load_ext_blk(resume_info,data_len);
  547.              resume_len = data_len;
  548.              }
  549.           break;
  550.            case 3: /* formula info */
  551.           {
  552.           char *nameptr;
  553.           char tmpname[40];
  554.           load_ext_blk(tmpname,40);
  555.           switch (info->fractal_type) {
  556.              case LSYSTEM:
  557.             nameptr = LName;
  558.             break;
  559.              case IFS:
  560.              case IFS3D:
  561.             nameptr = IFSName;
  562.             break;
  563.              default:
  564.             nameptr = FormName;
  565.             break;
  566.              }
  567.           tmpname[ITEMNAMELEN] = 0;
  568.           strcpy(nameptr,tmpname);
  569.           /* perhaps in future add more here, check block_len for
  570.              backward compatibility */
  571.           }
  572.           break;
  573.            case 4: /* ranges info */
  574.           skip_ext_blk(&block_len,&data_len); /* once to get lengths */
  575.           if ((ranges = (int far *)farmemalloc((long)data_len))) {
  576.              fseek(fp,(long)(0-block_len),SEEK_CUR);
  577.              load_ext_blk((char far *)ranges,data_len);
  578.              rangeslen = data_len/2;
  579. #ifdef XFRACTINT
  580.              fix_ranges(ranges,rangeslen,1);
  581. #endif
  582.              }
  583.           break;
  584.            default:
  585.           skip_ext_blk(&block_len,&data_len);
  586.            }
  587.         }
  588.      }
  589.  
  590.       fclose(fp);
  591.       fileaspectratio = screenaspect; /* if not >= v15, this is correct */
  592.       return(0);
  593.       }
  594.  
  595.    strcpy(info->info_id, "GIFFILE");
  596.    info->iterations = 150;
  597.    info->fractal_type = PLASMA;
  598.    info->xmin = -1;
  599.    info->xmax = 1;
  600.    info->ymin = -1;
  601.    info->ymax = 1;
  602.    info->x3rd = -1;
  603.    info->y3rd = -1;
  604.    info->creal = 0;
  605.    info->cimag = 0;
  606.    info->videomodeax=255;
  607.    info->videomodebx=255;
  608.    info->videomodecx=255;
  609.    info->videomodedx=255;
  610.    info->dotmode = 0;
  611.    info->xdots = filexdots;
  612.    info->ydots = fileydots;
  613.    info->colors = filecolors;
  614.    info->version = 0; /* this forces lots more init at calling end too */
  615.  
  616.    /* zero means we won */
  617.    fclose(fp);
  618.    return(0);
  619. }
  620.  
  621. static void load_ext_blk(char far *loadptr,int loadlen)
  622. {
  623.    int len;
  624.    while ((len = fgetc(fp)) > 0) {
  625.       while (--len >= 0) {
  626.      if (--loadlen >= 0)
  627.         *(loadptr++) = fgetc(fp);
  628.      else
  629.         fgetc(fp); /* discard excess characters */
  630.      }
  631.       }
  632. }
  633.  
  634. static void skip_ext_blk(int *block_len, int *data_len)
  635. {
  636.    int len;
  637.    *data_len = 0;
  638.    *block_len = 1;
  639.    while ((len = fgetc(fp)) > 0) {
  640.       fseek(fp,(long)len,SEEK_CUR);
  641.       *data_len += len;
  642.       *block_len += len + 1;
  643.       }
  644. }
  645.  
  646.  
  647. /* switch obsolete fractal types to new generalizations */
  648. static void backwardscompat(struct fractal_info *info)
  649. {
  650.    switch(fractype) {
  651.       case LAMBDASINE:
  652.      fractype = LAMBDATRIGFP;
  653.      trigndx[0] = SIN;
  654.      break;
  655.       case LAMBDACOS    :
  656.      fractype = LAMBDATRIGFP;
  657.      trigndx[0] = COS;
  658.      break;
  659.       case LAMBDAEXP    :
  660.      fractype = LAMBDATRIGFP;
  661.      trigndx[0] = EXP;
  662.      break;
  663.       case MANDELSINE    :
  664.      fractype = MANDELTRIGFP;
  665.      trigndx[0] = SIN;
  666.      break;
  667.       case MANDELCOS    :
  668.      fractype = MANDELTRIGFP;
  669.      trigndx[0] = COS;
  670.      break;
  671.       case MANDELEXP    :
  672.      fractype = MANDELTRIGFP;
  673.      trigndx[0] = EXP;
  674.      break;
  675.       case MANDELSINH    :
  676.      fractype = MANDELTRIGFP;
  677.      trigndx[0] = SINH;
  678.      break;
  679.       case LAMBDASINH    :
  680.      fractype = LAMBDATRIGFP;
  681.      trigndx[0] = SINH;
  682.      break;
  683.       case MANDELCOSH    :
  684.      fractype = MANDELTRIGFP;
  685.      trigndx[0] = COSH;
  686.      break;
  687.       case LAMBDACOSH    :
  688.      fractype = LAMBDATRIGFP;
  689.      trigndx[0] = COSH;
  690.      break;
  691.       case LMANDELSINE    :
  692.      fractype = MANDELTRIG;
  693.      trigndx[0] = SIN;
  694.      break;
  695.       case LLAMBDASINE    :
  696.      fractype = LAMBDATRIG;
  697.      trigndx[0] = SIN;
  698.      break;
  699.       case LMANDELCOS    :
  700.      fractype = MANDELTRIG;
  701.      trigndx[0] = COS;
  702.      break;
  703.       case LLAMBDACOS    :
  704.      fractype = LAMBDATRIG;
  705.      trigndx[0] = COS;
  706.      break;
  707.       case LMANDELSINH    :
  708.      fractype = MANDELTRIG;
  709.      trigndx[0] = SINH;
  710.      break;
  711.       case LLAMBDASINH    :
  712.      fractype = LAMBDATRIG;
  713.      trigndx[0] = SINH;
  714.      break;
  715.       case LMANDELCOSH    :
  716.      fractype = MANDELTRIG;
  717.      trigndx[0] = COSH;
  718.      break;
  719.       case LLAMBDACOSH    :
  720.      fractype = LAMBDATRIG;
  721.      trigndx[0] = COSH;
  722.      break;
  723.       case LMANDELEXP    :
  724.      fractype = MANDELTRIG;
  725.      trigndx[0] = EXP;
  726.      break;
  727.       case LLAMBDAEXP    :
  728.      fractype = LAMBDATRIG;
  729.      trigndx[0] = EXP;
  730.      break;
  731.       case DEMM     :
  732.      fractype = MANDELFP;
  733.      usr_distest = (info->ydots - 1) * 2;
  734.      break;
  735.       case DEMJ     :
  736.      fractype = JULIAFP;
  737.      usr_distest = (info->ydots - 1) * 2;
  738.      break;
  739.       case MANDELLAMBDA :
  740.      useinitorbit = 2;
  741.      break;
  742.       }
  743.    curfractalspecific = &fractalspecific[fractype];
  744. }
  745.  
  746. /* switch old bifurcation fractal types to new generalizations */
  747. void set_if_old_bif(void)
  748. {
  749. /* set functions if not set already, may need to check 'functionpreloaded'
  750.    before calling this routine.  JCO 7/5/92 */
  751.  
  752.    ENTER_OVLY(OVLY_LOADFILE);
  753.    switch(fractype) {
  754.       case BIFURCATION:
  755.       case LBIFURCATION:
  756.       case BIFSTEWART:
  757.       case LBIFSTEWART:
  758.       case BIFLAMBDA:
  759.       case LBIFLAMBDA:
  760.         set_trig_array(0,"ident");
  761.         break;
  762.  
  763.       case BIFEQSINPI:
  764.       case LBIFEQSINPI:
  765.       case BIFADSINPI:
  766.       case LBIFADSINPI:
  767.         set_trig_array(0,"sin");
  768.         break;
  769.    }
  770.    EXIT_OVLY;
  771. }
  772.