📄 loadfile.c
字号:
EXIT_OVLY;
return(0);
}
static int find_fractal_info(gif_file,info)
char *gif_file;
struct fractal_info *info;
{
BYTE gifstart[18];
char temp1[81];
int scan_extend, block_type, block_len, data_len;
int fractinf_len;
int hdr_offset;
if((fp = fopen(gif_file,"rb"))==NULL)
return(-1);
fread(gifstart,18,1,fp);
#ifndef XFRACT
if (strncmp(gifstart,"GIF",3)!=0) { /* not GIF, maybe old .tga? */
#else
if (strncmp((char *)gifstart,"GIF",3)!=0) { /* not GIF, maybe old .tga? */
#endif
if(fread(info,FRACTAL_INFO_SIZE,1,fp)==1 &&
strncmp(info->info_id,"Fractal",8)==0) {
filetype = 1; /* Targa 16 */
GET16(gifstart[O_VSIZE],fileydots);
GET16(gifstart[O_HSIZE],filexdots);
filecolors = info->colors;
fileaspectratio = screenaspect;
if(fileydots == info->ydots && filexdots == info->xdots) {
fclose(fp);
return(0);
}
}
fclose(fp);
return(-1);
}
filetype = 0; /* GIF */
GET16(gifstart[6],filexdots);
GET16(gifstart[8],fileydots);
filecolors = 2 << (gifstart[10] & 7);
fileaspectratio = 0; /* unknown */
if (gifstart[12]) { /* calc reasonably close value from gif header */
fileaspectratio = (64.0 / ((double)(gifstart[12]) + 15.0))
* (double)fileydots / (double)filexdots;
if ( fileaspectratio > screenaspect-0.03
&& fileaspectratio < screenaspect+0.03)
fileaspectratio = screenaspect;
}
else
if (fileydots * 4 == filexdots * 3) /* assume the common square pixels */
fileaspectratio = screenaspect;
if (resume_info != NULL) { /* free the prior area if there is one */
farmemfree(resume_info);
resume_info = NULL;
}
if (rangeslen) { /* free prior ranges */
farmemfree((char far *)ranges);
rangeslen = 0;
}
/* Format of .gif extension blocks is:
1 byte '!', extension block identifier
1 byte extension block number, 255
1 byte length of id, 11
11 bytes alpha id, "fractintnnn" with fractint, nnn is secondary id
n * {
1 byte length of block info in bytes
x bytes block info
}
1 byte 0, extension terminator
To scan extension blocks, we first look in file at length of fractal_info
(the main extension block) from end of file, looking for a literal known
to be at start of our block info. Then we scan forward a bit, in case
the file is from an earlier fractint vsn with shorter fractal_info.
If fractal_info is found and is from vsn>=14, it includes the total length
of all extension blocks; we then scan them all first to last to load
any optional ones which are present.
Defined extension blocks:
fractint001 header, always present
fractint002 resume info for interrupted resumable image
fractint003 additional formula type info
fractint004 ranges info
*/
memset(info,0,FRACTAL_INFO_SIZE);
fractinf_len = FRACTAL_INFO_SIZE + (FRACTAL_INFO_SIZE+254)/255;
fseek(fp,(long)(-1-fractinf_len),SEEK_END);
fread(info,1,FRACTAL_INFO_SIZE,fp);
if (strcmp(INFO_ID,info->info_id) == 0) {
#ifdef XFRACT
decode_fractal_info(info,1);
#endif
hdr_offset = -1-fractinf_len;
} else {
/* didn't work 1st try, maybe an older vsn, maybe junk at eof, scan: */
int offset,i;
char tmpbuf[110];
hdr_offset = 0;
offset = 80; /* don't even check last 80 bytes of file for id */
while (offset < fractinf_len+513) { /* allow 512 garbage at eof */
offset += 100; /* go back 100 bytes at a time */
fseek(fp,(long)(0-offset),SEEK_END);
fread(tmpbuf,1,110,fp); /* read 10 extra for string compare */
for (i = 0; i < 100; ++i)
if (!strcmp(INFO_ID,&tmpbuf[i])) { /* found header? */
strcpy(info->info_id,INFO_ID);
fseek(fp,(long)(hdr_offset=i-offset),SEEK_END);
fread(info,1,FRACTAL_INFO_SIZE,fp);
#ifdef XFRACT
decode_fractal_info(info,1);
#endif
offset = 10000; /* force exit from outer loop */
break;
}
}
}
if (hdr_offset) { /* we found INFO_ID */
if (info->version >= 4) {
/* first reload main extension block, reasons:
might be over 255 chars, and thus earlier load might be bad
find exact endpoint, so scan back to start of ext blks works
*/
fseek(fp,(long)(hdr_offset-15),SEEK_END);
scan_extend = 1;
while (scan_extend) {
if (fgetc(fp) != '!' /* if not what we expect just give up */
|| fread(temp1,1,13,fp) != 13
|| strncmp(&temp1[2],"fractint",8))
break;
temp1[13] = 0;
block_type = atoi(&temp1[10]); /* e.g. "fractint002" */
switch (block_type) {
case 1: /* "fractint001", the main extension block */
if (scan_extend == 2) { /* we've been here before, done now */
scan_extend = 0;
break;
}
load_ext_blk((char far *)info,FRACTAL_INFO_SIZE);
#ifdef XFRACT
decode_fractal_info(info,1);
#endif
scan_extend = 2;
/* now we know total extension len, back up to first block */
fseek(fp,0L-info->tot_extend_len,SEEK_CUR);
break;
case 2: /* resume info */
skip_ext_blk(&block_len,&data_len); /* once to get lengths */
if ((resume_info = farmemalloc((long)data_len)) == NULL)
info->calc_status = 3; /* not resumable after all */
else {
fseek(fp,(long)(0-block_len),SEEK_CUR);
load_ext_blk(resume_info,data_len);
resume_len = data_len;
}
break;
case 3: /* formula info */
{
char *nameptr;
char tmpname[40];
load_ext_blk(tmpname,40);
switch (info->fractal_type) {
case LSYSTEM:
nameptr = LName;
break;
case IFS:
case IFS3D:
nameptr = IFSName;
break;
default:
nameptr = FormName;
break;
}
tmpname[ITEMNAMELEN] = 0;
strcpy(nameptr,tmpname);
/* perhaps in future add more here, check block_len for
backward compatibility */
}
break;
case 4: /* ranges info */
skip_ext_blk(&block_len,&data_len); /* once to get lengths */
if ((ranges = (int far *)farmemalloc((long)data_len))) {
fseek(fp,(long)(0-block_len),SEEK_CUR);
load_ext_blk((char far *)ranges,data_len);
rangeslen = data_len/2;
#ifdef XFRACTINT
fix_ranges(ranges,rangeslen,1);
#endif
}
break;
default:
skip_ext_blk(&block_len,&data_len);
}
}
}
fclose(fp);
fileaspectratio = screenaspect; /* if not >= v15, this is correct */
return(0);
}
strcpy(info->info_id, "GIFFILE");
info->iterations = 150;
info->fractal_type = PLASMA;
info->xmin = -1;
info->xmax = 1;
info->ymin = -1;
info->ymax = 1;
info->x3rd = -1;
info->y3rd = -1;
info->creal = 0;
info->cimag = 0;
info->videomodeax=255;
info->videomodebx=255;
info->videomodecx=255;
info->videomodedx=255;
info->dotmode = 0;
info->xdots = filexdots;
info->ydots = fileydots;
info->colors = filecolors;
info->version = 0; /* this forces lots more init at calling end too */
/* zero means we won */
fclose(fp);
return(0);
}
static void load_ext_blk(char far *loadptr,int loadlen)
{
int len;
while ((len = fgetc(fp)) > 0) {
while (--len >= 0) {
if (--loadlen >= 0)
*(loadptr++) = fgetc(fp);
else
fgetc(fp); /* discard excess characters */
}
}
}
static void skip_ext_blk(int *block_len, int *data_len)
{
int len;
*data_len = 0;
*block_len = 1;
while ((len = fgetc(fp)) > 0) {
fseek(fp,(long)len,SEEK_CUR);
*data_len += len;
*block_len += len + 1;
}
}
/* switch obsolete fractal types to new generalizations */
static void backwardscompat(struct fractal_info *info)
{
switch(fractype) {
case LAMBDASINE:
fractype = LAMBDATRIGFP;
trigndx[0] = SIN;
break;
case LAMBDACOS :
fractype = LAMBDATRIGFP;
trigndx[0] = COS;
break;
case LAMBDAEXP :
fractype = LAMBDATRIGFP;
trigndx[0] = EXP;
break;
case MANDELSINE :
fractype = MANDELTRIGFP;
trigndx[0] = SIN;
break;
case MANDELCOS :
fractype = MANDELTRIGFP;
trigndx[0] = COS;
break;
case MANDELEXP :
fractype = MANDELTRIGFP;
trigndx[0] = EXP;
break;
case MANDELSINH :
fractype = MANDELTRIGFP;
trigndx[0] = SINH;
break;
case LAMBDASINH :
fractype = LAMBDATRIGFP;
trigndx[0] = SINH;
break;
case MANDELCOSH :
fractype = MANDELTRIGFP;
trigndx[0] = COSH;
break;
case LAMBDACOSH :
fractype = LAMBDATRIGFP;
trigndx[0] = COSH;
break;
case LMANDELSINE :
fractype = MANDELTRIG;
trigndx[0] = SIN;
break;
case LLAMBDASINE :
fractype = LAMBDATRIG;
trigndx[0] = SIN;
break;
case LMANDELCOS :
fractype = MANDELTRIG;
trigndx[0] = COS;
break;
case LLAMBDACOS :
fractype = LAMBDATRIG;
trigndx[0] = COS;
break;
case LMANDELSINH :
fractype = MANDELTRIG;
trigndx[0] = SINH;
break;
case LLAMBDASINH :
fractype = LAMBDATRIG;
trigndx[0] = SINH;
break;
case LMANDELCOSH :
fractype = MANDELTRIG;
trigndx[0] = COSH;
break;
case LLAMBDACOSH :
fractype = LAMBDATRIG;
trigndx[0] = COSH;
break;
case LMANDELEXP :
fractype = MANDELTRIG;
trigndx[0] = EXP;
break;
case LLAMBDAEXP :
fractype = LAMBDATRIG;
trigndx[0] = EXP;
break;
case DEMM :
fractype = MANDELFP;
usr_distest = (info->ydots - 1) * 2;
break;
case DEMJ :
fractype = JULIAFP;
usr_distest = (info->ydots - 1) * 2;
break;
case MANDELLAMBDA :
useinitorbit = 2;
break;
}
curfractalspecific = &fractalspecific[fractype];
}
/* switch old bifurcation fractal types to new generalizations */
void set_if_old_bif(void)
{
/* set functions if not set already, may need to check 'functionpreloaded'
before calling this routine. JCO 7/5/92 */
ENTER_OVLY(OVLY_LOADFILE);
switch(fractype) {
case BIFURCATION:
case LBIFURCATION:
case BIFSTEWART:
case LBIFSTEWART:
case BIFLAMBDA:
case LBIFLAMBDA:
set_trig_array(0,"ident");
break;
case BIFEQSINPI:
case LBIFEQSINPI:
case BIFADSINPI:
case LBIFADSINPI:
set_trig_array(0,"sin");
break;
}
EXIT_OVLY;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -