This is xanim_iff.c in view mode; [Download] [Up]
/* * xanim_iff.c * * Copyright (C) 1990,1991,1992,1993,1994 by Mark Podlipec. * All rights reserved. * * This software may be freely copied, modified and redistributed without * fee for non-commerical purposes provided that this copyright notice is * preserved intact on all copies and modified copies. * * There is no warranty or other guarantee of fitness of this software. * It is provided solely "as is". The author(s) disclaim(s) all * responsibility and liability with respect to this software's usage * or its effect upon hardware or computer systems. * */ #include "xanim.h" #include "xanim_iff.h" ULONG IFF_Read_File(); void IFF_Adjust_For_EHB(); void IFF_Read_BODY(); LONG IFF_Read_Garb(); void IFF_Print_ID(); ULONG IFF_Delta_Body(); ULONG IFF_Delta_l(); ULONG IFF_Delta_3(); ULONG IFF_Delta_5(); ULONG IFF_Delta_7(); ULONG IFF_Delta_J(); void IFF_Long_Mod(); LONG Is_IFF_File(); void IFF_Buffer_Action(); void IFF_Buffer_HAM6(); void IFF_Buffer_HAM8(); void IFF_Setup_HMAP(); void IFF_Setup_CMAP(); IFF_ACT_LST *IFF_Add_Frame(); void IFF_Image_To_Bufferable(); void IFF_Read_BMHD(); void IFF_Read_ANHD(); void IFF_Read_ANSQ(); void IFF_Register_CRNGs(); void IFF_Read_CRNG(); void IFF_Read_CMAP_0(); void IFF_Read_CMAP_1(); void IFF_Init_DLTA_HDR(); void IFF_Update_DLTA_HDR(); void IFF_Free_Stuff(); void IFF_Shift_CMAP(); void IFF_HAM6_As_True(); void IFF_HAM8_As_True(); void IFF_Hash_CleanUp(); void IFF_Hash_Init(); void IFF_Hash_Add(); XA_ACTION *IFF_Hash_Get(); ULONG IFF_Check_Same(); ULONG UTIL_Get_MSB_Long(); LONG UTIL_Get_MSB_Short(); ULONG UTIL_Get_MSB_UShort(); ULONG CMAP_Get_Or_Mask(); XA_CHDR *CMAP_Create_332(); XA_CHDR *CMAP_Create_Gray(); XA_CHDR *CMAP_Create_CHDR_From_True(); void ACT_Add_CHDR_To_Action(); void ACT_Del_CHDR_From_Action(); void UTIL_Mapped_To_Bitmap(); void UTIL_Mapped_To_Mapped(); UBYTE *UTIL_RGB_To_Map(); UBYTE *UTIL_RGB_To_FS_Map(); void ACT_Free_Act(); ULONG UTIL_Get_Buffer_Scale(); void UTIL_Scale_Pos_Size(); extern LONG xa_anim_cycling; XA_ACTION *ACT_Get_Action(); void ACT_Setup_Mapped(); void UTIL_Sub_Image(); XA_CHDR *ACT_Get_CMAP(); #define IFF_SPEED_DEFAULT 3 #define ACT_IFF_HMAP6 0x2000 #define ACT_IFF_HMAP8 0x2001 typedef struct { ULONG flag; XA_ACTION *dlta; XA_ACTION *src; XA_ACTION *dst; XA_ACTION *nxtdlta; } IFF_HASH; IFF_HASH *iff_hash_tbl; ULONG iff_hash_cur = 0; static IFF_ANSQ *iff_ansq; static ULONG iff_ansq_cnt; static IFF_DLTA_TABLE *iff_dlta_acts; static LONG iff_allow_cycling; static ULONG iff_time; static ULONG iff_anim_flags; static ULONG iff_cmap_bits; static ColorReg iff_hmap[XA_HMAP_SIZE]; static ColorReg *iff_cur_hmap; static ColorReg iff_cmap[256]; static XA_CHDR *iff_chdr; static LONG mask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; static IFF_ACT_LST *iff_act_start,*iff_act_cur; static ULONG iff_act_cnt; static ULONG iff_dlta_cnt; static ULONG iff_dlta_compression,iff_dlta_bits; static ULONG iff_imagex,iff_imagey,iff_imagec,iff_imaged; static ULONG iff_max_imagex,iff_max_imagey,iff_max_imagec,iff_max_imaged; static ULONG iff_or_mask; static ULONG iff_max_fsize; extern ULONG xa_ham_map_size; extern ULONG *xa_ham_map; extern XA_CHDR *xa_ham_chdr; extern ULONG xa_ham_init; /* * NOTES: the iff_cmap is read in as 8 bits. It's shifted down to 4 bits * before ACT_GET_CMAP is called(unless there are 8 bit planes) * How does one know whether is 4 bits or 8 bits per color component? */ void IFF_TheEnd() { IFF_Free_Stuff(); TheEnd(); } void IFF_TheEnd1(p) char *p; { IFF_Free_Stuff(); TheEnd1(p); } IFF_ACT_LST *IFF_Add_Frame(type,act) ULONG type; XA_ACTION *act; { IFF_ACT_LST *iframe; iframe = (IFF_ACT_LST *) malloc(sizeof(IFF_ACT_LST)); if (iframe == 0) IFF_TheEnd1("IFF_Add_Frame: malloc err"); if (type == 1) iff_dlta_cnt++; iframe->type = type; iframe->act = act; iframe->next = 0; if (iff_act_start == 0) iff_act_start = iframe; else iff_act_cur->next = iframe; iff_act_cur = iframe; iff_act_cnt++; return(iframe); } void IFF_Free_Stuff() { IFF_ACT_LST *itmp; if (iff_ansq) FREE(iff_ansq,0x1000); if (iff_dlta_acts) FREE(iff_dlta_acts,0x1001); iff_ansq = 0; iff_dlta_acts = 0; while(iff_act_start != 0) { itmp = iff_act_start; iff_act_start = iff_act_start->next; FREE(itmp,0x1003); } iff_ansq = 0; iff_dlta_acts = 0; iff_act_start = 0; } /* * */ ULONG IFF_Read_File(fname,anim_hdr) BYTE *fname; XA_ANIM_HDR *anim_hdr; { FILE *fin; LONG camg_flag,cmap_flag,chdr_flag,ret; LONG crng_flag,formtype; LONG ansq_flag; LONG face_flag,bmhd_flag,file_size,file_read; Bit_Map_Header bmhd; Chunk_Header chunk; LONG prop_flag; LONG exit_flag; iff_allow_cycling = (anim_hdr->anim_flags & ANIM_CYCLE)?(TRUE):(FALSE); iff_act_start = 0; iff_act_cur = 0; iff_act_cnt = 0; iff_dlta_compression = 0xffff; iff_dlta_bits = 0; iff_anim_flags = anim_hdr->anim_flags & ~(ANIM_LACE | ANIM_HAM | ANIM_CYCLE); file_size = 0; file_read = 0; iff_imagex = iff_max_imagex = 0; iff_imagey = iff_max_imagey = 0; iff_imagec = iff_max_imagec = 0; iff_imaged = iff_max_imaged = 0; iff_or_mask = 0; iff_max_fsize = 0; prop_flag = 0; bmhd_flag = 0; face_flag = 0; crng_flag = 0; camg_flag = 0; cmap_flag = FALSE; chdr_flag = FALSE; ansq_flag = 0; iff_ansq = 0; iff_ansq_cnt = 0; iff_dlta_acts = 0; iff_dlta_cnt = 0; iff_chdr = 0; iff_cmap_bits = 4; iff_cur_hmap = 0; if ( (fin=fopen(fname,XA_OPEN_MODE)) == 0) { fprintf(stderr,"can't open %s\n",fname); return(FALSE); } exit_flag = 0; while( !feof(fin) && !exit_flag) { /* read Chunk_Header */ chunk.id = UTIL_Get_MSB_Long(fin); chunk.size = UTIL_Get_MSB_Long(fin); if ( feof(fin) ) break; if (chunk.size == -1) ret = -1; else ret = 0; DEBUG_LEVEL1 { fprintf(stderr,"Chunk.ID = "); IFF_Print_ID(stderr,chunk.id); fprintf(stderr," chunksize=%lx\n",chunk.size); } if (chunk.size & 1) chunk.size+=1; /* halfword pad it */ if (ret==0) { switch(chunk.id) { case PROP: prop_flag=1; case LIST: case FORM: formtype = UTIL_Get_MSB_Long(fin); file_size = chunk.size; file_read = -1; DEBUG_LEVEL2 { fprintf(stderr," IFF "); IFF_Print_ID(stderr,chunk.id); fprintf(stderr," = "); IFF_Print_ID(stderr,formtype); fprintf(stderr,"\n"); } break; case BMHD: IFF_Read_BMHD(fin,&bmhd); if (xa_verbose) { fprintf(stderr," Size %ldx%ldx%ld comp=%ld masking=%ld\n", bmhd.width,bmhd.height,bmhd.depth, bmhd.compression,bmhd.masking); } iff_imagex = bmhd.width; iff_imagey = bmhd.height; iff_imaged = bmhd.depth; if (iff_imaged == 8) iff_cmap_bits = 8; else iff_cmap_bits = 4; if (iff_imagex > iff_max_imagex) iff_max_imagex = iff_imagex; if (iff_imagey > iff_max_imagey) iff_max_imagey = iff_imagey; if (iff_imaged > iff_max_imaged) iff_max_imaged = iff_imaged; /* or_mask is used to move pixels to upper reaches of cmap */ iff_or_mask = CMAP_Get_Or_Mask(1 << iff_imaged); bmhd_flag = 1; break; case FACE: /* used in MovieSetter anims */ { ULONG garb; bmhd.pageWidth = bmhd.width = UTIL_Get_MSB_Short(fin); bmhd.pageHeight = bmhd.height = UTIL_Get_MSB_Short(fin); garb = UTIL_Get_MSB_Long(fin); /* read x, y */ garb = UTIL_Get_MSB_Long(fin); /* read xoff, yoff */ bmhd.depth = 5; bmhd.compression = BMHD_COMP_BYTERUN; bmhd.x = bmhd.y = bmhd.masking = 0; bmhd.transparentColor = 0; bmhd.xAspect = bmhd.yAspect = 0; face_flag = bmhd_flag = 1; iff_imagex = bmhd.width; iff_imagey = bmhd.height; iff_imaged = bmhd.depth; if (iff_imagex > iff_max_imagex) iff_max_imagex = iff_imagex; if (iff_imagey > iff_max_imagey) iff_max_imagey = iff_imagey; if (iff_imaged > iff_max_imaged) iff_max_imaged = iff_imaged; iff_or_mask = CMAP_Get_Or_Mask(1 << iff_imaged); if (xa_verbose) { fprintf(stderr," Size %ldx%ldx%ld comp=%ld masking=%ld\n", bmhd.width,bmhd.height,bmhd.depth, bmhd.compression,bmhd.masking); } } break; case CAMG: { DEBUG_LEVEL2 fprintf(stderr,"IFF CAMG\n"); if (chunk.size != 4) { ret = IFF_Read_Garb(fin,chunk.size); break; } camg_flag = UTIL_Get_MSB_Long(fin) | IFF_CAMG_NOP; if ((camg_flag & IFF_CAMG_EHB) && (cmap_flag == TRUE)) { IFF_Adjust_For_EHB(iff_cmap,iff_cmap_bits); iff_chdr = ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask, iff_imagec,iff_or_mask, iff_cmap_bits,iff_cmap_bits,iff_cmap_bits); chdr_flag = TRUE; break; } if (camg_flag & IFF_CAMG_LACE) iff_anim_flags |= ANIM_LACE; if ((camg_flag & IFF_CAMG_HAM) && (cmap_flag == TRUE)) { XA_ACTION *act; /* CREATE ACT_IFF_HMAP chunk */ if (iff_cmap_bits == 8) { act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP8); iff_anim_flags |= ANIM_HAM8; } else { act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP6); iff_anim_flags |= ANIM_HAM6; } IFF_Setup_HMAP(act,iff_hmap,iff_cmap,iff_cmap_bits); iff_cur_hmap = (ColorReg *)act->data; if (cmap_true_to_332 == TRUE) { iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec); iff_or_mask = 0; } else /* if (cmap_true_to_gray == TRUE) */ { iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec); iff_or_mask = 0; } chdr_flag = TRUE; } } break; case CMAP: { ULONG tmp; DEBUG_LEVEL2 fprintf(stderr,"IFF CMAP\n"); if (chunk.size == 0x40) { iff_imagec = chunk.size / 2; /* xR+GB */ IFF_Read_CMAP_1(iff_cmap,iff_imagec,fin); } else { iff_imagec = chunk.size / 3; /* Rx+Gx+Bx 1 byte each */ IFF_Read_CMAP_0(iff_cmap,iff_imagec,fin); } /* Typically iff_imaged matches iff_imagec but not always * HAM and EHB are frequent examples */ if (bmhd_flag) { tmp = 0x01 << iff_imaged; if (tmp < iff_imagec) iff_imagec = tmp; } if (camg_flag & IFF_CAMG_HAM) { XA_ACTION *act; if (iff_cmap_bits == 8) { act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP8); iff_anim_flags |= ANIM_HAM8; } else { act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP6); iff_anim_flags |= ANIM_HAM6; } IFF_Setup_HMAP(act,iff_hmap,iff_cmap,iff_cmap_bits); iff_cur_hmap = (ColorReg *)act->data; if (cmap_true_to_332 == TRUE) { iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec); iff_or_mask = 0; } else /* if (cmap_true_to_gray == TRUE) */ { iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec); iff_or_mask = 0; } chdr_flag = TRUE; } else if (camg_flag & IFF_CAMG_EHB) { IFF_Adjust_For_EHB(iff_cmap,iff_cmap_bits); iff_chdr = ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask, iff_imagec,iff_or_mask, iff_cmap_bits,iff_cmap_bits,iff_cmap_bits); chdr_flag = TRUE; } else if (camg_flag) /* NOT HAM6,HAM8 or EHB */ { if (iff_cmap_bits == 4) IFF_Shift_CMAP(iff_cmap,iff_imagec); iff_chdr = ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask, iff_imagec,iff_or_mask, iff_cmap_bits,iff_cmap_bits,iff_cmap_bits); chdr_flag = TRUE; } cmap_flag = TRUE; } break; case BODY: { XA_ACTION *act; ACT_DLTA_HDR *dlta_hdr; DEBUG_LEVEL2 fprintf(stderr,"IFF BODY\n"); if (chdr_flag == FALSE) { if (cmap_flag==TRUE) { if (iff_cmap_bits == 4) IFF_Shift_CMAP(iff_cmap,iff_imagec); iff_chdr = ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask, iff_imagec,iff_or_mask,iff_cmap_bits, iff_cmap_bits,iff_cmap_bits); chdr_flag = TRUE; IFF_Register_CRNGs(anim_hdr,iff_chdr); camg_flag = IFF_CAMG_NOP; /* so future CMAPs okay */ } else IFF_TheEnd1("IFF_Read_BODY: no cmap\n"); } act = ACT_Get_Action(anim_hdr,ACT_DELTA); ACT_Add_CHDR_To_Action(act,iff_chdr); act->h_cmap = iff_cur_hmap; IFF_Add_Frame(1,act); /* POD TEMP FINISH THIS eventually. For now body's are read in if (xa_file_flag == TRUE) { dlta_hdr =(ACT_DLTA_HDR *)malloc(sizeof(ACT_DLTA_HDR)); if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_BODY: malloc err"); act->data = (UBYTE *)dlta_hdr; dlta_hdr->flags = ACT_DBL_BUF; dlta_hdr->fpos = ftell(fin); dlta_hdr->fsize = chunk.size; fseek(fin,chunk.size,1); if (chunk.size > iff_max_fsize) iff_max_fsize = chunk.size; } else */ { dlta_hdr = (ACT_DLTA_HDR *) malloc( sizeof(ACT_DLTA_HDR) + (iff_imagex * iff_imagey) ); if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_BODY: malloc err"); act->data = (UBYTE *)dlta_hdr; dlta_hdr->flags = ACT_DBL_BUF | DLTA_DATA; dlta_hdr->fpos = 0; dlta_hdr->fsize = chunk.size; IFF_Read_BODY(fin,dlta_hdr->data,chunk.size, iff_imagex, iff_imagey, iff_imaged, (int)(bmhd.compression),(int)(bmhd.masking), iff_or_mask); } dlta_hdr->delta = IFF_Delta_Body; dlta_hdr->xsize = iff_imagex; dlta_hdr->ysize = iff_imagey; dlta_hdr->xpos = dlta_hdr->ypos = 0; dlta_hdr->special = 0; dlta_hdr->extra = 0; } break; case ANHD: { Anim_Header anhd; DEBUG_LEVEL2 fprintf(stderr,"IFF ANHD\n"); if (chunk.size >= Anim_Header_SIZE) { IFF_Read_ANHD(fin,&anhd,chunk.size); iff_dlta_compression = anhd.op; iff_dlta_bits = anhd.bits; /* if (xa_verbose) fprintf(stderr,"ANHD time = %ld\n",anhd.reltime); */ } else { IFF_Read_Garb(fin,chunk.size); iff_dlta_compression = 0xffffffff; iff_dlta_bits = 0x0; fprintf(stderr,"ANHD chunksize mismatch %ld\n",chunk.size); } } break; case DLTA: { ACT_DLTA_HDR *dlta_hdr; XA_ACTION *act; DEBUG_LEVEL2 fprintf(stderr,"IFF DLTA: "); act = ACT_Get_Action(anim_hdr,ACT_DELTA); ACT_Add_CHDR_To_Action(act,iff_chdr); act->h_cmap = iff_cur_hmap; IFF_Add_Frame(1,act); if (xa_file_flag == TRUE) { dlta_hdr =(ACT_DLTA_HDR *)malloc(sizeof(ACT_DLTA_HDR)); if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_DLTA: malloc err"); act->data = (UBYTE *)dlta_hdr; dlta_hdr->flags = ACT_DBL_BUF; dlta_hdr->fpos = ftell(fin); dlta_hdr->fsize = chunk.size; fseek(fin,chunk.size,1); if (chunk.size > iff_max_fsize) iff_max_fsize = chunk.size; } else { dlta_hdr =(ACT_DLTA_HDR *)malloc(sizeof(ACT_DLTA_HDR)+chunk.size); if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_DLTA: malloc err"); act->data = (UBYTE *)dlta_hdr; dlta_hdr->flags = ACT_DBL_BUF | DLTA_DATA; dlta_hdr->fpos = 0; dlta_hdr->fsize = chunk.size; ret=fread(dlta_hdr->data,chunk.size,1,fin); } dlta_hdr->xsize = iff_imagex; dlta_hdr->ysize = iff_imagey; dlta_hdr->xpos = dlta_hdr->ypos = 0; dlta_hdr->special = 0; dlta_hdr->extra = 0; switch(iff_dlta_compression) { case 3: DEBUG_LEVEL2 fprintf(stderr,"type 3\n"); dlta_hdr->delta = IFF_Delta_3; break; case 5: DEBUG_LEVEL2 fprintf(stderr,"type 5\n"); dlta_hdr->delta = IFF_Delta_5; break; case 7: dlta_hdr->delta = IFF_Delta_7; if (iff_dlta_bits & IFF_ANHD_LDATA) { DEBUG_LEVEL2 fprintf(stderr,"type 7L\n"); dlta_hdr->extra = 0; } else { DEBUG_LEVEL2 fprintf(stderr,"type 7S\n"); dlta_hdr->extra = 1; } break; case 74: DEBUG_LEVEL2 fprintf(stderr,"type J\n"); dlta_hdr->delta = IFF_Delta_J; break; case 108: dlta_hdr->delta = IFF_Delta_l; dlta_hdr->extra = 1; DEBUG_LEVEL2 fprintf(stderr,"type l\n"); break; default: act->type = ACT_NOP; fprintf(stderr,"Unsupported Delta %ld\n",iff_dlta_compression); break; } } break; case ANSQ: { DEBUG_LEVEL2 fprintf(stderr,"IFF ANSQ\n"); ansq_flag = 1; /* we found an ansq chunk */ IFF_Read_ANSQ(fin,chunk.size); } break; case CRNG: DEBUG_LEVEL2 fprintf(stderr,"IFF CRNG\n"); IFF_Read_CRNG(anim_hdr,fin,chunk.size,&crng_flag); break; case TINY : /* ignore */ case DPI : /* ignore */ case IMRT: /* ignore */ case GRAB: /* ignore */ case DPPS: /* ignore */ case DPPV: /* ignore */ case DPAN: /* ignore */ case DRNG: /* ignore */ case VHDR: /* sound ignore should kill next body until bmhd*/ case ANNO: /* sound ignore */ case CHAN: /* sound ignore */ case ANFI: /* sound ignore */ if (chunk.size & 0x01) chunk.size++; ret = IFF_Read_Garb(fin,chunk.size); break; default: if ( feof(fin) ) exit_flag = 1; /* end of file */ else { fprintf(stderr,"Unknown IFF type="); IFF_Print_ID(stderr,chunk.id); if ( (file_read < file_size) /* there should be more */ && (chunk.size < (file_size - file_read) ) /* size n 2 big */ ) { fprintf(stderr," Will Continue Reading File.\n"); ret = IFF_Read_Garb(fin,chunk.size); } else { fprintf(stderr," Will Stop Reading File.\n"); exit_flag = 1; } } break; } /* end chunk switch */ /* * keep track of number of bytes read. This allows us to distinguish * valid unknown chunks from garbage tacked to the end of a file. */ if (!exit_flag) { if (file_read == -1) file_read = 4; /* assuming FORM chunk or similar */ else file_read += chunk.size + 8; /* add ID and SIZE of other chunks */ } } /* end if ret==0 */ } /* end of while not eof or exit_flag */ DEBUG_LEVEL2 fprintf(stderr,"Bytes Read = %lx\n",file_read); fclose(fin); /* * Set up a map of delta's to their action numbers. */ { ULONG i; ULONG inter_dlta_i,dlta_i,act_i; iff_dlta_acts = (IFF_DLTA_TABLE *)malloc( (iff_dlta_cnt + 1) * sizeof(IFF_DLTA_TABLE)); if (iff_dlta_acts == 0) IFF_TheEnd1("IFF_Read_File: dlta_cnts malloc err"); for(i=0; i < iff_dlta_cnt; i++) { iff_dlta_acts[i].cnt = 0; iff_dlta_acts[i].frame = 0; iff_dlta_acts[i].start = 0; iff_dlta_acts[i].end = 0; } dlta_i = 0; act_i = 0; inter_dlta_i = 0; iff_act_cur = iff_act_start; iff_dlta_acts[dlta_i].start = iff_act_cur; iff_dlta_acts[dlta_i].frame = act_i; while(iff_act_cur != 0) { inter_dlta_i++; act_i++; switch(iff_act_cur->act->type) { case ACT_DELTA: iff_dlta_acts[dlta_i].cnt = inter_dlta_i; iff_dlta_acts[dlta_i].end = iff_act_cur; inter_dlta_i = 0; iff_act_cur = iff_act_cur->next; dlta_i++; if (dlta_i > iff_dlta_cnt) { fprintf(stderr,"IFF_Read: dlta setup err <%ld > %ld> \n", dlta_i,iff_dlta_cnt); IFF_TheEnd(); } if (dlta_i < iff_dlta_cnt) { iff_dlta_acts[dlta_i].start = iff_act_cur; iff_dlta_acts[dlta_i].frame = act_i; } break; default: iff_act_cur = iff_act_cur->next; break; } } /* end of while */ DEBUG_LEVEL1 fprintf(stderr,"%ld dltas found\n",dlta_i); iff_time = XA_GET_TIME(IFF_SPEED_DEFAULT * MS_PER_60HZ); if (ansq_flag) { LONG i; ULONG iff_frame_cnt,frame_i; iff_frame_cnt = iff_dlta_acts[0].cnt; /* start with body cnt */ for(i=0; i < iff_ansq_cnt; i++) /* count frames */ { if (iff_ansq[i].time != 0xffff) /* if not loop frame */ iff_frame_cnt += iff_dlta_acts[ iff_ansq[i].dnum + 1 ].cnt; } anim_hdr->frame_lst = (XA_FRAME *)malloc(sizeof(XA_FRAME) * (iff_frame_cnt + 1)); if (anim_hdr->frame_lst == NULL) IFF_TheEnd1("IFF ANSQ: frame_lst malloc err"); /* For movies default loop frame is 0 */ anim_hdr->loop_frame = 0; /* take care of frame up to BODY */ frame_i = 0; iff_act_cur = iff_dlta_acts[0].start; while(iff_act_cur != 0) { anim_hdr->frame_lst[frame_i].act = iff_act_cur->act; if (iff_act_cur == iff_dlta_acts[0].end) { anim_hdr->frame_lst[frame_i].time = iff_time; frame_i++; break; } else anim_hdr->frame_lst[frame_i].time = 1; frame_i++; iff_act_cur = iff_act_cur->next; if ( (frame_i > iff_frame_cnt) && (iff_act_cur != 0) ) { fprintf(stderr,"IFF_ansq: frame err %ld %ld\n",frame_i,iff_frame_cnt); IFF_TheEnd(); } } for(i=0; i < iff_ansq_cnt; i++) { if (iff_ansq[i].time == 0xffff) /* loop frame */ { anim_hdr->loop_frame = iff_ansq[ iff_ansq[i].dnum ].frame; } else { ULONG dlta_j; iff_ansq[i].frame = frame_i; /* for looping info */ dlta_j = iff_ansq[i].dnum + 1; iff_time = XA_GET_TIME(iff_ansq[i].time * MS_PER_60HZ); iff_act_cur = iff_dlta_acts[dlta_j].start; while(iff_act_cur != 0) { anim_hdr->frame_lst[frame_i].act = iff_act_cur->act; if (iff_act_cur == iff_dlta_acts[dlta_j].end) { anim_hdr->frame_lst[frame_i].time = iff_time; frame_i++; break; } else anim_hdr->frame_lst[frame_i].time = 1; frame_i++; iff_act_cur = iff_act_cur->next; if ( (frame_i > iff_frame_cnt) && (iff_act_cur != 0) ) { fprintf(stderr,"IFF_ansq: frame err %ld %ld\n", frame_i,iff_frame_cnt); IFF_TheEnd(); } } } } /* end of for */ anim_hdr->frame_lst[frame_i].time = 0; anim_hdr->frame_lst[frame_i].act = 0; anim_hdr->last_frame = frame_i - 1; } else /* no ansq chunk */ { LONG frame_i; /* extra for end and JMP2END */ anim_hdr->frame_lst = (XA_FRAME *)malloc(sizeof(XA_FRAME) * (iff_act_cnt + 2)); if (anim_hdr->frame_lst == NULL) IFF_TheEnd1("IFF_Read: frame malloc err"); iff_act_cur = iff_act_start; frame_i = 0; while(iff_act_cur != 0) { anim_hdr->frame_lst[frame_i].act = iff_act_cur->act; if (iff_act_cur->type == 1) { if ( (iff_dlta_cnt == 1) && (crng_flag) && (xa_jiffy_flag == 0) ) /* && (iff_act_cur->act->type == ACT_IFF_BODY) ) */ { anim_hdr->frame_lst[frame_i].time = DEFAULT_CYCLING_TIME; } else anim_hdr->frame_lst[frame_i].time = iff_time; } else anim_hdr->frame_lst[frame_i].time = 1; iff_act_cur = iff_act_cur->next; frame_i++; if (frame_i > iff_act_cnt) { fprintf(stderr,"IFF_Read: frame inconsistency %ld %ld\n", frame_i,iff_act_cnt); IFF_TheEnd(); } } /* Add JMP2END so deltas to beginning aren't displayed unless looping */ if ( !(iff_anim_flags & ANIM_NOLOOP) && (iff_dlta_cnt > 3) && !face_flag) { ULONG kk = frame_i; anim_hdr->frame_lst[kk].time = anim_hdr->frame_lst[kk-1].time; anim_hdr->frame_lst[kk].act = anim_hdr->frame_lst[kk-1].act; anim_hdr->frame_lst[kk-1].time = anim_hdr->frame_lst[kk-2].time; anim_hdr->frame_lst[kk-1].act = anim_hdr->frame_lst[kk-2].act; anim_hdr->frame_lst[kk-2].time = 0; anim_hdr->frame_lst[kk-2].act = ACT_Get_Action(anim_hdr,ACT_JMP2END); frame_i++; anim_hdr->loop_frame = iff_dlta_acts[2].frame; } else { anim_hdr->loop_frame = 0; } if (frame_i > 0 ) anim_hdr->last_frame = frame_i - 1; else anim_hdr->last_frame = 0; anim_hdr->frame_lst[frame_i].time = 0; anim_hdr->frame_lst[frame_i].act = 0; frame_i++; if (xa_verbose) { fprintf(stderr," dlta_cnt=%ld comp=%ld ", iff_dlta_cnt,iff_dlta_compression); if (camg_flag & IFF_CAMG_EHB) fprintf(stderr," EHB\n"); else if (iff_anim_flags & ANIM_HAM8) fprintf(stderr," HAM8\n"); else if (iff_anim_flags & ANIM_HAM6) fprintf(stderr," HAM6\n"); else fprintf(stderr,"\n"); } } } anim_hdr->imagex = iff_max_imagex; anim_hdr->imagey = iff_max_imagey; anim_hdr->imagec = iff_imagec; anim_hdr->imaged = iff_max_imaged; /* Some older IFF files don't include a CAMG chunk to indicate they * are interlaced. They just assume the viewer will figure it out. * Below is an arbitrary ruleset that'll hopefully work for most cases. */ if ((iff_max_imagex >= 400) && (iff_max_imagey > iff_max_imagex)) iff_anim_flags |= ANIM_LACE; /* NOTE: A lot of IFF animations have active color cycle chunks, yet * they were never intended to cycle. AAARRRRGH!!! */ if (iff_dlta_cnt == 1) /* single image IFF files */ { if ( (crng_flag) && (iff_allow_cycling == TRUE) ) iff_anim_flags |= ANIM_CYCLE; else iff_anim_flags &= ~ANIM_CYCLE; } else /* animation IFF files */ { if ( (crng_flag) && (iff_allow_cycling == TRUE) && (xa_anim_cycling == TRUE) ) iff_anim_flags |= ANIM_CYCLE; else iff_anim_flags &= ~ANIM_CYCLE; } anim_hdr->anim_flags = iff_anim_flags; IFF_Free_Stuff(); iff_chdr = 0; if (xa_buffer_flag) IFF_Buffer_Action(anim_hdr); else { anim_hdr->anim_flags |= ANIM_SNG_BUF; if (iff_dlta_cnt > 1) anim_hdr->anim_flags |= ANIM_DBL_BUF; if (iff_anim_flags | ANIM_HAM) anim_hdr->anim_flags |= ANIM_3RD_BUF; } if (xa_file_flag==TRUE) anim_hdr->anim_flags |= ANIM_USE_FILE; anim_hdr->fname = anim_hdr->name; anim_hdr->max_fsize = iff_max_fsize; return(TRUE); } /* * */ void IFF_Adjust_For_EHB(colormap,cmap_bits) ColorReg colormap[]; ULONG cmap_bits; { LONG i,cmap_num; DEBUG_LEVEL1 fprintf(stderr,"Adjusting CMAP for Amiga Extra Half-Brite Mode\n"); if (cmap_bits == 8) cmap_num = 128; else { /* 4 bits per rgb, shift down from 8 bits to 4 bits */ cmap_num = 32; IFF_Shift_CMAP(colormap,cmap_num); } /* make upper half a darkened version of the lower half */ for(i=0;i<cmap_num;i++) { colormap[i + cmap_num].red = colormap[i].red >> 2; colormap[i + cmap_num].green = colormap[i].green >> 2; colormap[i + cmap_num].blue = colormap[i].blue >> 2; } iff_imagec = 2 * cmap_num; iff_or_mask = CMAP_Get_Or_Mask(iff_imagec); } /* * */ void IFF_Read_BODY(fin,image_out,bodysize,xsize,ysize,depth, compression,masking,or_mask) FILE *fin; UBYTE *image_out; ULONG xsize,ysize,depth; LONG bodysize,compression,masking; ULONG or_mask; { LONG i,ret,x,y,d,dmask,tmp,rowsize; LONG imagex_pad; BYTE *inbuff,*rowbuff,*sptr; BYTE *sbuff,*dbuff; if ( (compression != BMHD_COMP_NONE) && (compression != BMHD_COMP_BYTERUN) ) IFF_TheEnd1("IFF_Read_Body: unsupported compression"); if ( (masking != BMHD_MSK_NONE) && (masking != BMHD_MSK_HAS) && (masking != BMHD_MSK_TRANS) ) IFF_TheEnd1("IFF_Read_Body: unsupported masking"); inbuff = (BYTE *)malloc(bodysize); if (inbuff == 0) IFF_TheEnd1("IFF_Read_Body: malloc failed"); ret=fread(inbuff,bodysize,1,fin); if (ret!=1) IFF_TheEnd1("IFF_Read_Body: read of BODY chunk failed"); sbuff = inbuff; /* width is rounded to multiples of 16 in the BODY form */ /* extra bits are ignored upon reading */ imagex_pad = xsize / 16; if (xsize % 16) imagex_pad++; imagex_pad *= 16; rowbuff = (BYTE *)malloc( imagex_pad ); if (rowbuff == 0) IFF_TheEnd1("IFF_Read_Body: malloc failed"); memset(image_out,or_mask,(xsize * ysize) ); if (compression==BMHD_COMP_NONE) sptr = inbuff; for(y=0; y<ysize; y++) { tmp = y * xsize; dmask=1; for(d=0; d<depth; d++) { if (compression == BMHD_COMP_BYTERUN) { rowsize = imagex_pad / 8; dbuff = rowbuff; ret=UnPackRow(&sbuff,&dbuff,&bodysize,&rowsize); if (ret) { fprintf(stderr,"error %ld in unpack\n",ret); IFF_TheEnd();} sptr = rowbuff; } i = 0; for(x=0; x<xsize; x++) { if (mask[i] & (*sptr)) image_out[tmp+x] |= dmask; i++; if (i >= 8) { i = 0; sptr++; } } if (imagex_pad >= (xsize+8)) sptr++; dmask <<= 1; } /* end of depth loop */ if (masking == BMHD_MSK_HAS) { /* read the mask row and then throw out for now */ if (compression == BMHD_COMP_BYTERUN) { rowsize = imagex_pad / 8; dbuff = rowbuff; ret=UnPackRow(&sbuff,&dbuff,&bodysize,&rowsize); if (ret) { fprintf(stderr,"error %ld in unpack\n",ret); IFF_TheEnd();} } else sptr += xsize/8; } } /* end of y loop */ FREE(inbuff,0x1004); inbuff=0; FREE(rowbuff,0x1005); rowbuff=0; } /* * */ LONG IFF_Read_Garb(fp,size) FILE *fp; LONG size; { BYTE *garb; garb = (BYTE *)malloc(size); if (garb==0) { fprintf(stderr,"readgarb malloc err size=%ld",size); return(-1);} fread(garb,size,1,fp); FREE(garb,0x1006); garb=0; return(0); } void IFF_Print_ID(fout,id) FILE *fout; LONG id; { fprintf(fout,"%c", ((id >> 24) & 0xff) ); fprintf(fout,"%c", ((id >> 16) & 0xff) ); fprintf(fout,"%c", ((id >> 8) & 0xff) ); fprintf(fout,"%c(%lx)", (id & 0xff),id); } /* * */ ULONG IFF_Delta_5(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,extra) UBYTE *image; /* Image Buffer. */ UBYTE *delta; /* delta data. */ ULONG dsize; /* delta size */ XA_CHDR *chdr; /* color map info */ ULONG *map; /* used if it's going to be remapped. */ ULONG map_flag; /* whether or not to use remap_map info. */ ULONG imagex,imagey; /* Size of image buffer. */ ULONG imaged; /* Depth of Image. (IFF specific) */ ULONG *xs,*ys; /* pos of changed area. */ ULONG *xe,*ye; /* size of changed area. */ ULONG special; /* Special Info. */ ULONG extra; /* Extra Info. */ { register LONG col,depth,dmask; register LONG rowsize,width; ULONG poff; register UBYTE *i_ptr; register UBYTE *dptr,opcnt,op,cnt; LONG miny,minx,maxy,maxx; /* set to opposites for min/max testing */ *xe = *ye = 0; *ys = imagey; *xs = imagex; width = imagex; rowsize = width >> 3; dmask = 1; for(depth=0; depth<imaged; depth++) { minx = -1; maxx = -1; i_ptr = image; /* offset into delt chunk */ { register USHORT ddepth = depth << 2; poff = (ULONG)(delta[ ddepth++ ]) << 24; poff |= (ULONG)(delta[ ddepth++ ]) << 16; poff |= (ULONG)(delta[ ddepth++ ]) << 8; poff |= (ULONG)(delta[ ddepth ]); } if (poff) { dptr = (UBYTE *)(delta + poff); for(col=0;col<rowsize;col++) { /* start at top of column */ i_ptr = (UBYTE *)(image + (col << 3)); opcnt = *dptr++; /* get number of ops for this column */ miny = -1; maxy = -1; while(opcnt) /* execute ops */ { /* keep track of min and max columns */ if (minx == -1) minx = col << 3; maxx = (col << 3) + 7; op = *dptr++; /* get op */ if (op & 0x80) /* if type uniqe */ { if (miny == -1) miny=(ULONG)( i_ptr - image ) / width; cnt = op & 0x7f; /* get cnt */ while(cnt--) /* loop through data */ { register UBYTE data = *dptr++; IFF_Byte_Mod(i_ptr,data,dmask,0); i_ptr += width; } } /* end unique */ else { if (op == 0) /* type same */ { register UBYTE data; if (miny == -1) miny=(ULONG)( i_ptr - image ) / width; cnt = *dptr++; data = *dptr++; while(cnt--) /* loop through data */ { IFF_Byte_Mod(i_ptr,data,dmask,0); i_ptr += width; } } /* end same */ else { i_ptr += (width * op); /* type skip */ } } /* end of hi bit clear */ opcnt--; } /* end of while opcnt */ maxy = (ULONG)( i_ptr - image ) / width; if ( (miny>=0) && (miny < *ys)) *ys = miny; if ( (maxy>=0) && (maxy > *ye)) *ye = maxy; } /* end of column loop */ } /* end of valid pointer for this plane */ dmask <<= 1; if ( (minx>=0) && (minx < *xs)) *xs = minx; if ( (maxx>=0) && (maxx > *xe)) *xe = maxx; } /* end of for depth */ if (xa_optimize_flag == TRUE) { if (*xs >= imagex) *xs = 0; if (*ys >= imagey) *ys = 0; if (*xe <= 0) *xe = imagex; if (*ye <= 0) *ye = imagey; } else { *xs = 0; *ys = 0; *xe = imagex; *ye = imagey; } return(ACT_DLTA_NORM); } /* end of routine */ /* * */ ULONG IFF_Delta_3(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,extra) UBYTE *image; /* Image Buffer. */ UBYTE *delta; /* delta data. */ ULONG dsize; /* delta size */ XA_CHDR *chdr; /* color map info */ ULONG *map; /* used if it's going to be remapped. */ ULONG map_flag; /* whether or not to use remap_map info. */ ULONG imagex,imagey; /* Size of image buffer. */ ULONG imaged; /* Depth of Image. (IFF specific) */ ULONG *xs,*ys; /* pos of changed area. */ ULONG *xe,*ye; /* size of changed area. */ ULONG special; /* Special Info. */ ULONG extra; /* Extra Info. */ { register LONG i,depth,dmask; ULONG poff; register SHORT offset; register USHORT s,data; register UBYTE *i_ptr,*dptr; *xs = *ys = 0; *xe = imagex; *ye = imagey; dmask = 1; for(depth=0;depth<imaged;depth++) { i_ptr = image; /*poff = planeoff[depth];*/ /* offset into delt chunk */ poff = (ULONG)(delta[ 4 * depth ]) << 24; poff |= (ULONG)(delta[ 4 * depth + 1]) << 16; poff |= (ULONG)(delta[ 4 * depth + 2]) << 8; poff |= (ULONG)(delta[ 4 * depth + 3]); if (poff) { dptr = (UBYTE *)(delta + poff); while( (dptr[0] != 0xff) || (dptr[1] != 0xff) ) { offset = (*dptr++)<<8; offset |= (*dptr++); if (offset >= 0) { data = (*dptr++)<<8; data |= (*dptr++); i_ptr += 16 * (ULONG)(offset); IFF_Short_Mod(i_ptr,data,dmask,0); } /* end of pos */ else { i_ptr += 16 * (ULONG)(-(offset+2)); s = (*dptr++)<<8; s |= (*dptr++); /* size of next */ for(i=0; i < (ULONG)s; i++) { data = (*dptr++)<<8; data |= (*dptr++); i_ptr += 16; IFF_Short_Mod(i_ptr,data,dmask,0); } } /* end of neg */ } /* end of delta for this plane */ } /* plane has changed data */ dmask <<= 1; } /* end of d */ return(ACT_DLTA_NORM); } /* * */ LONG Is_IFF_File(filename) BYTE *filename; { FILE *fp; ULONG firstword; if ( (fp=fopen(filename,XA_OPEN_MODE)) == 0) return(XA_NOFILE); /* by reading bytes we can ignore big/little endian problems */ firstword = (fgetc(fp) & 0xff) << 24; firstword |= (fgetc(fp) & 0xff) << 16; firstword |= (fgetc(fp) & 0xff) << 8; firstword |= (fgetc(fp) & 0xff); fclose(fp); if (firstword == FORM) return(TRUE); if (firstword == LIST) return(TRUE); if (firstword == PROP) return(TRUE); return(FALSE); } void IFF_Hash_Init(num) ULONG num; { register ULONG i; iff_hash_cur=0; iff_hash_tbl = (IFF_HASH *)malloc(num * sizeof(IFF_HASH)); if (iff_hash_tbl == 0) TheEnd1("IFF_Hash_Init: malloc err"); for(i=0;i<num;i++) iff_hash_tbl[i].flag = ACT_DLTA_BAD; } void IFF_Hash_CleanUp() { if (iff_hash_tbl) { register ULONG i=0; while(i<iff_hash_cur) { register XA_ACTION *tact = iff_hash_tbl[i].dlta; if (tact) { if (tact->type == ACT_DELTA) ACT_Free_Act(tact); } i++; } FREE(iff_hash_tbl,0x100E); iff_hash_tbl=0; } } void IFF_Hash_Add(dlta,nxtdlta,src,dst,flag) XA_ACTION *dlta,*nxtdlta,*src,**dst; ULONG flag; { register IFF_HASH *hptr = &iff_hash_tbl[iff_hash_cur]; hptr->flag = flag; hptr->dlta = dlta; hptr->nxtdlta = nxtdlta; hptr->src = src; hptr->dst = *dst; iff_hash_cur++; } ULONG pod_temp_i; XA_ACTION *IFF_Hash_Get(dlta,src,nxtdlta) XA_ACTION *dlta,*src,*nxtdlta; { register ULONG i = 0; while(1) { IFF_HASH *hptr = &iff_hash_tbl[i]; pod_temp_i = i; if (hptr->flag & ACT_DLTA_BAD) return(0); /* end and nothing found */ else if (hptr->dlta == dlta) { if (hptr->flag & ACT_DLTA_NOP) return(src); else if ( (src == hptr->src) || (hptr->flag & ACT_DLTA_BODY) ) return(hptr->dst); else if ( (src == hptr->dst) && (hptr->flag & ACT_DLTA_XOR) ) return(hptr->src); else if (hptr->nxtdlta == nxtdlta) return(hptr->dst); } i++; } } /* * */ void IFF_Buffer_Action(anim_hdr) XA_ANIM_HDR *anim_hdr; { LONG image_size; UBYTE *buff0,*buff1,*tmp,*dbl_buff; XA_ACTION *act,*old_act0,*old_act1; XA_FRAME *frame_lst; ULONG frame_i,frame_num; ULONG scale_x,scale_y,need_to_scale; iff_chdr = 0; image_size = iff_imagex * iff_imagey; dbl_buff = buff1 = buff0 = (UBYTE *) malloc( 2 * image_size ); if (buff0 == 0) TheEnd1("IFF Buffer Action: malloc failed 0"); buff1 += image_size; frame_num = anim_hdr->last_frame + 1; IFF_Hash_Init(frame_num); need_to_scale = UTIL_Get_Buffer_Scale(iff_imagex,iff_imagey,&scale_x,&scale_y); frame_i = 0; old_act0 = old_act1 = 0; frame_lst = anim_hdr->frame_lst; while(frame_lst[frame_i].act != 0) { XA_ACTION *dst_act,*new_act,*nxt_act; act = frame_lst[frame_i].act; nxt_act = frame_lst[frame_i + 1].act; switch(act->type) { case ACT_DELTA: { ACT_DLTA_HDR *dlta_hdr = (ACT_DLTA_HDR *)act->data; LONG minx,miny,maxx,maxy; LONG pic_x,pic_y; UBYTE *t_pic; ULONG dlta_flag = 1; dlta_flag = dlta_hdr->delta(buff0, dlta_hdr->data, dlta_hdr->fsize, 0, 0, FALSE, iff_imagex,iff_imagey,iff_imaged, &minx, &miny, &maxx, &maxy, dlta_hdr->special,dlta_hdr->extra); if (dlta_flag & ACT_DLTA_BODY) { memcpy((char *)buff1, (char *)buff0, image_size); maxx = dlta_hdr->xsize; maxy = dlta_hdr->ysize; IFF_Init_DLTA_HDR(maxx,maxy); } IFF_Update_DLTA_HDR(&minx,&miny,&maxx,&maxy); dst_act = IFF_Hash_Get(act,old_act0,nxt_act); /* IF unbuffered action has been previously setup and IF it's * smaller than old one, use the old one. IF it's larger than * the old one, then free up the old one and replace with this one. * Same goes for deltas that don't change an images(the NOPs). */ if ( (dst_act) || (dlta_flag & ACT_DLTA_NOP) ) { XA_ACTION *tst_act; if (!dst_act) /* if here because no change */ { if (old_act0 == 0) TheEnd1("IFF Buff: No Body err"); IFF_Hash_Add(act,nxt_act,old_act0,&old_act0,dlta_flag); tst_act = old_act0; } else tst_act = dst_act; if ( (tst_act->type==ACT_MAPPED) || (tst_act->type==ACT_DISP) ) { ACT_MAPPED_HDR *maphdr = (ACT_MAPPED_HDR *)tst_act->data; ULONG px,py,sx,sy; ULONG opx,opy,osx,osy; px = minx; sx = maxx - minx; py = miny; sy = maxy - miny; if (need_to_scale) UTIL_Scale_Pos_Size(&px,&py,&sx,&sy, iff_imagex,iff_imagey,scale_x,scale_y); sx += px; opx = maphdr->xpos; osx = maphdr->xsize + opx; sy += py; opy = maphdr->ypos; osy = maphdr->ysize + opy; if ( ((px >= opx) && (px <= osx)) /* new is <= old */ && ((sx >= opx) && (sx <= osx)) && ((py >= opy) && (py <= osy)) && ((sy >= opy) && (sy <= osy)) ) { frame_lst[frame_i].act = tst_act; old_act0 = old_act1; old_act1 = tst_act; tmp = buff0; buff0 = buff1; buff1 = tmp; break; } } /* NOTE: this might should be an error */ ACT_Free_Act(tst_act); new_act = tst_act; /* free_act should wipe chdr info */ } else { /* get new action for unbuffered frame */ new_act = ACT_Get_Action(anim_hdr,0); ACT_Add_CHDR_To_Action(new_act,act->chdr); } pic_x = maxx - minx; pic_y = maxy - miny; /* now get into shape */ if (iff_anim_flags & ANIM_HAM) { ULONG disp_flag; if (x11_display_type == XA_MONOCHROME) {minx=miny=0; pic_x=iff_imagex; pic_y=iff_imagey; } t_pic = (UBYTE *) malloc( XA_PIC_SIZE(pic_x * pic_y) ); if (x11_display_type & XA_X11_TRUE) disp_flag = TRUE; else disp_flag = FALSE; if (iff_anim_flags & ANIM_HAM6) { if (cmap_true_map_flag == TRUE) { XA_CHDR *tmp_chdr = 0; ACT_Del_CHDR_From_Action(new_act,new_act->chdr); IFF_HAM6_As_True (t_pic,buff0,&tmp_chdr,act->h_cmap, pic_x,pic_y,minx,miny,iff_imagex); ACT_Add_CHDR_To_Action(new_act,tmp_chdr); } else IFF_Buffer_HAM6(t_pic,buff0,new_act->chdr,act->h_cmap, pic_x,pic_y,minx,miny,iff_imagex,FALSE); } else { if (cmap_true_map_flag == TRUE) { XA_CHDR *tmp_chdr = 0; ACT_Del_CHDR_From_Action(new_act,new_act->chdr); IFF_HAM8_As_True (t_pic,buff0,&tmp_chdr,act->h_cmap, pic_x,pic_y,minx,miny,iff_imagex); ACT_Add_CHDR_To_Action(new_act,tmp_chdr); } else IFF_Buffer_HAM8(t_pic,buff0,new_act->chdr,act->h_cmap, pic_x,pic_y,minx,miny,iff_imagex,FALSE); } ACT_Setup_Mapped(new_act, t_pic, new_act->chdr, minx, miny, pic_x, pic_y, iff_imagex, iff_imagey, FALSE, 0, TRUE, FALSE, disp_flag); } else ACT_Setup_Mapped(new_act, buff0, new_act->chdr, minx, miny, pic_x, pic_y, iff_imagex, iff_imagey, FALSE,0, FALSE, TRUE, FALSE); if (dlta_flag & ACT_DLTA_BODY) old_act0 = old_act1 = new_act; IFF_Hash_Add(act,nxt_act,old_act0,&new_act,dlta_flag); old_act0 = old_act1; old_act1 = new_act; frame_lst[frame_i].act = new_act; tmp = buff0; buff0 = buff1; buff1 = tmp; } /* end of delta7,5,j */ break; } /* end of switch */ frame_i++; /* move to next action in list */ } /* end of while */ if (dbl_buff) { FREE(dbl_buff,0x100A); dbl_buff = buff0 = buff1 = 0;} IFF_Hash_CleanUp(); iff_chdr = 0; } ULONG IFF_Delta_J(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,extra) UBYTE *image; /* Image Buffer. */ UBYTE *delta; /* delta data. */ ULONG dsize; /* delta size */ XA_CHDR *chdr; /* color map info */ ULONG *map; /* used if it's going to be remapped. */ ULONG map_flag; /* whether or not to use remap_map info. */ ULONG imagex,imagey; /* Size of image buffer. */ ULONG imaged; /* Depth of Image. (IFF specific) */ ULONG *xs,*ys; /* pos of changed area. */ ULONG *xe,*ye; /* size of changed area. */ ULONG special; /* Special Info. */ ULONG extra; /* Extra Info. */ { register LONG rowsize,width; register UBYTE *i_ptr; register LONG exitflag; register ULONG type,r_flag,b_cnt,g_cnt,r_cnt; register ULONG b,g,r; register ULONG offset,dmask,depth; register UBYTE data; LONG changed,xor_flag; LONG tmp,minx,miny,maxx,maxy; LONG kludge_j; /* this kludge is because animations with width less than 320 are considered * centered in the middle of a 320 screen. Does this happen with * animations greater than lores overscan(374) and less than hi-res(640)???? */ if (imagex >= 320) kludge_j = 0; else kludge_j = (320-imagex)/2; maxx = maxy = 0; minx = imagex; miny = imagey; changed = xor_flag = 0; width = imagex; rowsize = width / 8; exitflag = 0; while(!exitflag) { /* read compression type and reversible_flag(xor data not just set) */ type = (*delta++) << 8; type |= (*delta++); if (type != 0 ) { r_flag = (*delta++) << 8; r_flag |= (*delta++); } else r_flag = 0; /* Might possibly have to read it anyways */ /* switch on compression type */ switch(type) { case 0: exitflag = 1; break; /* end of list */ case 1: /* Get byte count and group count */ xor_flag |= r_flag; b_cnt = (*delta++) << 8; b_cnt |= (*delta++); g_cnt = (*delta++) << 8; g_cnt |= (*delta++); /* Loop thru groups */ for(g=0; g<g_cnt; g++) { ULONG odd_flag; offset = (*delta++) << 8; offset |= (*delta++); offset <<= 3; /* counts bytes */ if (kludge_j) offset = ((offset/320) * imagex) + (offset%320) - kludge_j; i_ptr = (UBYTE *)(image + offset); tmp = offset%imagex; if (tmp<minx) minx=tmp; tmp += 8; if (tmp>maxx) maxx=tmp; tmp = offset/imagex; if (tmp<miny) miny=tmp; tmp += b_cnt; if (tmp>maxy) maxy=tmp; odd_flag = (b_cnt * imaged) & 0x01; /* Loop thru byte count */ for(b=0; b < b_cnt; b++) { dmask = 1; for(depth=0;depth<imaged;depth++) /* loop thru planes */ { data = *delta++; changed |= data; /* CHECKFORZERO change */ IFF_Byte_Mod(i_ptr,data,dmask,r_flag); dmask <<= 1; } /* end of depth loop */ i_ptr += width; /* direction is vertical */ } /* end of byte loop */ if (odd_flag) delta++; /* pad to short */ } /* end of group loop */ break; case 2: /* Read row count, byte count and group count */ xor_flag |= r_flag; r_cnt = (*delta++) << 8; r_cnt |= (*delta++); b_cnt = (*delta++) << 8; b_cnt |= (*delta++); g_cnt = (*delta++) << 8; g_cnt |= (*delta++); /* Loop thru groups */ for(g=0; g < g_cnt; g++) { ULONG odd_flag; offset = (*delta++) << 8; offset |= (*delta++); offset <<= 3; /* counts bytes */ if (kludge_j) offset = ((offset/320) * imagex) + (offset%320) - kludge_j; tmp = offset%imagex; if (tmp<minx) minx=tmp; tmp += b_cnt * 8; if (tmp>maxx) maxx=tmp; tmp = offset/imagex; if (tmp<miny) miny=tmp; tmp += r_cnt; if (tmp>maxy) maxy=tmp; odd_flag = (r_cnt * b_cnt * imaged) & 0x01; /* Loop thru rows of group */ for(r=0; r < r_cnt; r++) { dmask = 1; for(depth=0;depth<imaged;depth++) /* loop thru planes */ { i_ptr = (UBYTE *)(image + offset + (r * width)); for(b=0; b < b_cnt; b++) /* loop thru byte count */ { data = *delta++; changed |= data; /* CHECKFORZERO */ IFF_Byte_Mod(i_ptr,data,dmask,r_flag); i_ptr += 8; /* data is horizontal */ } /* end of byte loop */ dmask <<= 1; } /* end of depth loop */ } /* end of row loop */ if (odd_flag) delta++; /* pad to short */ } /* end of group loop */ break; default: /* don't know this one yet */ fprintf(stderr,"Unknown J-type %x\n",type); type = 0; /* force an exit */ exitflag = 1; break; } /* end of type switch */ } /* end of while loop */ /* if changed is zero then this Delta didn't change the image at all */ if (changed==0) { *xs = *ys = *xe = *ye = 0; return(ACT_DLTA_NOP); } if (xa_optimize_flag == TRUE) { *xs = minx; *ys = miny; *xe = maxx; *ye = maxy; if (*xs >= imagex) *xs = 0; if (*ys >= imagey) *ys = 0; if (*xe <= 0) *xe = imagex; if (*ye <= 0) *ye = imagey; DEBUG_LEVEL2 fprintf(stderr,"xypos=<%ld,%ld> xysize=<%ld %ld>\n", *xs,*ys,*xe,*ye ); } else { *xs = 0; *ys = 0; *xe = imagex; *ye = imagey; } if (xor_flag) return(ACT_DLTA_XOR); return(ACT_DLTA_NORM); } /* end of IFF_DeltaJ routine */ /* * Decode IFF type l anims */ ULONG IFF_Delta_l(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,vertflag) UBYTE *image; /* Image Buffer. */ UBYTE *delta; /* delta data. */ ULONG dsize; /* delta size */ XA_CHDR *chdr; /* color map info */ ULONG *map; /* used if it's going to be remapped. */ ULONG map_flag; /* whether or not to use remap_map info. */ ULONG imagex,imagey; /* Size of image buffer. */ ULONG imaged; /* Depth of Image. (IFF specific) */ ULONG *xs,*ys; /* pos of changed area. */ ULONG *xe,*ye; /* size of changed area. */ ULONG special; /* Special Info. */ ULONG vertflag; /* Extra Info. 1 = vertical encoding*/ { register LONG i,depth,dmask,width; ULONG poff0,poff1; register UBYTE *i_ptr; register UBYTE *optr,*dptr; register SHORT cnt; register USHORT offset,data; *xs = *ys = 0; *xe = imagex; *ye = imagey; i_ptr = image; if (vertflag) width = imagex; else width = 16; dmask = 1; for(depth = 0; depth<imaged; depth++) { i_ptr = image; /*poff = planeoff[depth];*/ /* offset into delt chunk */ poff0 = (ULONG)(delta[ 4 * depth ]) << 24; poff0 |= (ULONG)(delta[ 4 * depth + 1]) << 16; poff0 |= (ULONG)(delta[ 4 * depth + 2]) << 8; poff0 |= (ULONG)(delta[ 4 * depth + 3]); if (poff0) { poff1 = (ULONG)(delta[ 4 * (depth+8) ]) << 24; poff1 |= (ULONG)(delta[ 4 * (depth+8) + 1]) << 16; poff1 |= (ULONG)(delta[ 4 * (depth+8) + 2]) << 8; poff1 |= (ULONG)(delta[ 4 * (depth+8) + 3]); dptr = (UBYTE *)(delta + 2 * poff0); optr = (UBYTE *)(delta + 2 * poff1); /* while short *optr != -1 */ while( (optr[0] != 0xff) || (optr[1] != 0xff) ) { offset = (*optr++) << 8; offset |= (*optr++); cnt = (*optr++) << 8; cnt |= (*optr++); if (cnt < 0) /* cnt negative */ { i_ptr = image + 16 * (ULONG)(offset); cnt = -cnt; data = (*dptr++) << 8; data |= (*dptr++); for(i=0; i < (ULONG)cnt; i++) { IFF_Short_Mod(i_ptr,data,dmask,0); i_ptr += width; } } /* end of neg */ else/* cnt pos then */ { i_ptr = image + 16 * (ULONG)(offset); for(i=0; i < (ULONG)cnt; i++) { data = (*dptr++) << 8; data |= (*dptr++); IFF_Short_Mod(i_ptr,data,dmask,0); i_ptr += width; } } /* end of pos */ } /* end of delta for this plane */ } /* plane has changed data */ dmask <<= 1; } /* end of d */ return(ACT_DLTA_NORM); } void IFF_Setup_HMAP(act,hmap,cmap,bits) XA_ACTION *act; ColorReg *hmap,*cmap; ULONG bits; { ColorReg *hptr; ULONG i,size,shift; if (bits == 8) {size = XA_HMAP8_SIZE; shift = 2;} else {size = XA_HMAP6_SIZE; shift = 4;} act->data = (UBYTE *) malloc(size * sizeof(ColorReg) ); if (act->data == 0) IFF_TheEnd1("IFF_Setup_HMAP: malloc failed\n"); hptr = (ColorReg *) act->data; for(i=0; i < size; i++) { hptr[i].red = hmap[i].red = cmap[i].red >> shift; hptr[i].green = hmap[i].green = cmap[i].green >> shift; hptr[i].blue = hmap[i].blue = cmap[i].blue >> shift; } } IFF_DLTA_HDR iff_dlta[2]; void IFF_Init_DLTA_HDR(max_x,max_y) ULONG max_x,max_y; { iff_dlta[0].minx = iff_dlta[1].minx = 0; iff_dlta[0].miny = iff_dlta[1].miny = 0; iff_dlta[0].maxx = iff_dlta[1].maxx = max_x; iff_dlta[0].maxy = iff_dlta[1].maxy = max_y; } void IFF_Update_DLTA_HDR(min_x,min_y,max_x,max_y) LONG *min_x,*min_y,*max_x,*max_y; { register LONG tmin_x,tmin_y,tmax_x,tmax_y; /* This mess keeps track of the largest rectangle needed to * display all changes. Since things are double buffered, the * min/maxes of the corners of the current and previous two * images are taken. If the animation is in single step mode * it's best to display the entire image. */ /* Special condition if max_x is 0, then return previous largest values*/ if (max_x) { tmin_x = *min_x; tmin_y = *min_y; tmax_x = *max_x; tmax_y = *max_y; iff_dlta[0].minx = XA_MIN(iff_dlta[0].minx, tmin_x); iff_dlta[0].miny = XA_MIN(iff_dlta[0].miny, tmin_y); iff_dlta[0].maxx = XA_MAX(iff_dlta[0].maxx, tmax_x); iff_dlta[0].maxy = XA_MAX(iff_dlta[0].maxy, tmax_y); *min_x = XA_MIN(iff_dlta[1].minx, iff_dlta[0].minx); *min_y = XA_MIN(iff_dlta[1].miny, iff_dlta[0].miny); *max_x = XA_MAX(iff_dlta[1].maxx, iff_dlta[0].maxx); *max_y = XA_MAX(iff_dlta[1].maxy, iff_dlta[0].maxy); /* Throw out oldest rectangle and store current. */ iff_dlta[1].minx = iff_dlta[0].minx; iff_dlta[1].miny = iff_dlta[0].miny; iff_dlta[1].maxx = iff_dlta[0].maxx; iff_dlta[1].maxy = iff_dlta[0].maxy; iff_dlta[0].minx = tmin_x; iff_dlta[0].miny = tmin_y; iff_dlta[0].maxx = tmax_x; iff_dlta[0].maxy = tmax_y; } else { *min_x = XA_MIN(iff_dlta[1].minx, iff_dlta[0].minx); *min_y = XA_MIN(iff_dlta[1].miny, iff_dlta[0].miny); *max_x = XA_MAX(iff_dlta[1].maxx, iff_dlta[0].maxx); *max_y = XA_MAX(iff_dlta[1].maxy, iff_dlta[0].maxy); } } void IFF_Read_BMHD(fin,bmhd) FILE *fin; Bit_Map_Header *bmhd; { /* read Bit_Map_Header into bmhd */ /* read so as to avoid endian problems */ bmhd->width = UTIL_Get_MSB_Short(fin); bmhd->height = UTIL_Get_MSB_Short(fin); bmhd->x = UTIL_Get_MSB_Short(fin); bmhd->y = UTIL_Get_MSB_Short(fin); bmhd->depth = fgetc(fin); bmhd->masking = fgetc(fin); bmhd->compression = fgetc(fin); bmhd->pad1 = fgetc(fin); bmhd->transparentColor = UTIL_Get_MSB_Short(fin); bmhd->xAspect = fgetc(fin); bmhd->yAspect = fgetc(fin); bmhd->pageWidth = UTIL_Get_MSB_Short(fin); bmhd->pageHeight = UTIL_Get_MSB_Short(fin); } void IFF_Read_ANHD(fin,anhd,chunk_size) FILE *fin; Anim_Header *anhd; ULONG chunk_size; { ULONG i; anhd->op = fgetc(fin); anhd->mask = fgetc(fin); anhd->w = UTIL_Get_MSB_Short(fin); anhd->h = UTIL_Get_MSB_Short(fin); anhd->x = UTIL_Get_MSB_Short(fin); anhd->y = UTIL_Get_MSB_Short(fin); anhd->abstime = UTIL_Get_MSB_Long(fin); anhd->reltime = UTIL_Get_MSB_Long(fin); anhd->interleave = fgetc(fin); anhd->pad0 = fgetc(fin); anhd->bits = UTIL_Get_MSB_Long(fin); fread((BYTE *)(anhd->pad),1,16,fin); /* read pad */ i = Anim_Header_SIZE; while(i < chunk_size) {fgetc(fin); i++;} } void IFF_Read_ANSQ(fin,chunk_size) FILE *fin; ULONG chunk_size; { ULONG i; UBYTE *p; /* data is actually big endian USHORT */ BYTE *garb; iff_ansq_cnt = chunk_size / 4; iff_ansq_cnt++; /* adding dlta 0 up front */ DEBUG_LEVEL2 fprintf(stderr," ansq_cnt=%ld dlta_cnt=%ld\n", iff_ansq_cnt,iff_dlta_cnt); /* allocate space for ansq variables */ iff_ansq = (IFF_ANSQ *)malloc( iff_ansq_cnt * sizeof(IFF_ANSQ)); if (iff_ansq == NULL) IFF_TheEnd1("IFF_Read_ANSQ: malloc err"); if (xa_verbose) fprintf(stderr," frames=%ld dlts=%d comp=%ld\n", iff_ansq_cnt,iff_dlta_cnt,iff_dlta_compression); garb = (BYTE *)malloc(chunk_size); if (garb==0) { fprintf(stderr,"ansq malloc not enough\n"); IFF_TheEnd(); } fread(garb,chunk_size,1,fin); p = (UBYTE *)(garb); /* first delta is only used once and doesn't appear in * the ANSQ */ iff_ansq[0].dnum = 0; iff_ansq[0].time = 1; for(i=1; i<iff_ansq_cnt; i++) { /* this is delta to apply */ iff_ansq[i].dnum = (ULONG)(*p++)<<8; iff_ansq[i].dnum |= (ULONG)(*p++); /* this is jiffy count or if 0xffff then a goto */ iff_ansq[i].time = (ULONG)(*p++)<<8; iff_ansq[i].time |= (ULONG)(*p++); iff_ansq[i].frame = 0; DEBUG_LEVEL2 fprintf(stderr,"<%ld %ld> ",iff_ansq[i].dnum, iff_ansq[i].time); } FREE(garb,0x100C); garb=0; } /* * Function to register any CRNGs that occur before CMAP in IFF file */ void IFF_Register_CRNGs(anim_hdr,chdr) XA_ANIM_HDR *anim_hdr; XA_CHDR *chdr; { XA_ACTION *act; act = (XA_ACTION *)anim_hdr->acts; while(act) { if ( (act->type == ACT_CYCLE) && (act->chdr == 0) ) ACT_Add_CHDR_To_Action(act,chdr); act = act->next; } } void IFF_Read_CRNG(anim_hdr,fin,chunk_size,crng_flag) XA_ANIM_HDR *anim_hdr; FILE *fin; ULONG chunk_size; ULONG *crng_flag; { /* CRNG_HDR * word pad1,rate,active; * byte low,high; */ /* is the chunk the correct size ? */ if (chunk_size == IFF_CRNG_HDR_SIZE) { XA_ACTION *act; ULONG rate,active,low,high,csize; ACT_CYCLE_HDR *act_cycle; /* read CRNG chunk */ rate = UTIL_Get_MSB_UShort(fin); /* throw away pad1 */ rate = UTIL_Get_MSB_UShort(fin); active = UTIL_Get_MSB_UShort(fin); low = fgetc(fin); high = fgetc(fin); /* make it an action only if its valid */ if ( (active & IFF_CRNG_ACTIVE) && (low < high) && (rate > IFF_CRNG_DPII_KLUDGE) && (iff_allow_cycling == TRUE) ) { ULONG i,*i_ptr; csize = high - low + 1; act_cycle = (ACT_CYCLE_HDR *) malloc( sizeof(ACT_CYCLE_HDR) + (csize * sizeof(ULONG)) ); if (act_cycle == 0) IFF_TheEnd1("IFF_Read_CRNG: malloc failed"); act_cycle->size = csize; act_cycle->curpos = 0; act_cycle->rate = (ULONG)(IFF_CRNG_INTERVAL/rate); act_cycle->flags = ACT_CYCLE_ACTIVE; if (active & IFF_CRNG_REVERSE) act_cycle->flags |= ACT_CYCLE_REVERSE; i_ptr = (ULONG *)act_cycle->data; for(i=0; i<csize; i++) { i_ptr[i] = low + i + iff_or_mask; } *crng_flag = *crng_flag + 1; act = ACT_Get_Action(anim_hdr,ACT_CYCLE); IFF_Add_Frame(0,act); act->data = (UBYTE *) act_cycle; /* register it now if iff_chdr valid, else wait to later */ if (iff_chdr) ACT_Add_CHDR_To_Action(act,iff_chdr); } else DEBUG_LEVEL2 fprintf(stderr,"IFF_CRNG not used\n"); } else { IFF_Read_Garb(fin,chunk_size); fprintf(stderr,"IFF_CRNG chunksize mismatch %ld\n",chunk_size); } } void IFF_Read_CMAP_0(cmap,size,fin) ColorReg *cmap; ULONG size; FILE *fin; { ULONG i; for(i=0; i < size; i++) { cmap[i].red = fgetc(fin); cmap[i].green = fgetc(fin); cmap[i].blue = fgetc(fin); } } void IFF_Read_CMAP_1(cmap,size,fin) ColorReg *cmap; ULONG size; FILE *fin; { ULONG i; for(i=0; i < size; i++) { ULONG d; d = fgetc(fin); cmap[i].red = (d & 0x0f) << 4; d = fgetc(fin); cmap[i].green = (d & 0xf0); cmap[i].blue = (d & 0x0f) << 4; } } void IFF_Buffer_HAM6(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize,d_flag) UBYTE *out; /* output image (size of section) */ UBYTE *in; /* input image */ XA_CHDR *chdr; /* color header to map to */ ColorReg *h_cmap; /* ham color map */ ULONG xosize,yosize; /* size of section in input buffer */ ULONG xip,yip; /* pos of section in input buffer */ ULONG xisize; /* x size of input buffer */ ULONG d_flag; /* map_flag */ { XA_CHDR *the_chdr; ULONG new_cmap_flag,*the_map,psize; register ULONG y,xend,the_moff,coff; USHORT g_adj[16]; if (x11_display_type & XA_X11_TRUE) for(y=0;y<16;y++) g_adj[y] = xa_gamma_adj[ (17 * y) ]; the_map = chdr->map; coff = chdr->coff; if (chdr->new_chdr == 0) { the_chdr = chdr; new_cmap_flag = 0; } else { the_chdr = chdr->new_chdr; new_cmap_flag = 1; } the_moff = the_chdr->moff; if (x11_display_type & XA_X11_TRUE) d_flag = TRUE; if (d_flag==TRUE) psize = x11_bytes_pixel; else psize = 1; DEBUG_LEVEL1 fprintf(stderr,"ham_cmap: = %lx\n",(ULONG)h_cmap); if (xa_ham_map == 0) { xa_ham_map_size = XA_HAM6_CACHE_SIZE; xa_ham_map = (ULONG *)malloc( xa_ham_map_size * sizeof(ULONG) ); if (xa_ham_map == 0) IFF_TheEnd1("IFF_Buffer_HAM6: h_map malloc err"); } if ((the_chdr != xa_ham_chdr) || (xa_ham_init != 6)) { register ULONG i; DEBUG_LEVEL1 fprintf(stderr,"xa_ham_map: old = %lx new = %lx\n", (ULONG)xa_ham_chdr,(ULONG)the_chdr); for(i=0; i<XA_HAM6_CACHE_SIZE; i++) xa_ham_map[i] = XA_HAM_MAP_INVALID; xa_ham_chdr = the_chdr; xa_ham_init = 6; } xend = xip + xosize; if (xend > xisize) xend = xisize; for (y=yip; y < (yip + yosize); y++) { register ULONG x; register UBYTE *i_ptr = (UBYTE *)( in + y * xisize ); register UBYTE *o_ptr = (UBYTE *)( out + (y-yip)*xosize * psize ); register ULONG pred,pgrn,pblu,data; pred = pgrn = pblu = 0; for (x=0; x<xend; x++) { data = (USHORT )(*i_ptr++); switch(data & 0x30) { case 0x00: /* use color register given by low */ { register USHORT low = data & 0x0f; pred = h_cmap[low].red; pgrn = h_cmap[low].green; pblu = h_cmap[low].blue; } break; case 0x10: pblu = data & 0x0f; break; /* change blue */ case 0x20: pred = data & 0x0f; break; /* change red */ case 0x30: pgrn = data & 0x0f; break; /* change green */ } if ( (x >= xip) && (x < xend) ) { register ULONG t_color; register USHORT indx = (pred << 8) | (pgrn << 4) | pblu; if ( (t_color = xa_ham_map[indx]) == XA_HAM_MAP_INVALID) { if (x11_display_type & XA_X11_TRUE) t_color = X11_Get_True_Color( g_adj[pred],g_adj[pgrn],g_adj[pblu],16); else /* don't gamma because chdr already adjusted */ { if (cmap_true_to_332 == TRUE) t_color = CMAP_GET_332(pred,pgrn,pblu,CMAP_SCALE4); else t_color = CMAP_GET_GRAY(pred,pgrn,pblu,CMAP_SCALE9); if (new_cmap_flag) t_color = the_map[t_color - coff] + the_moff; } xa_ham_map[indx] = t_color; } if (d_flag) { if (x11_bytes_pixel == 4) { ULONG *ulp = (ULONG *)o_ptr; *ulp = t_color; o_ptr += 4; } else if (x11_bytes_pixel == 2) { USHORT *usp = (USHORT *)o_ptr; *usp = (USHORT)(t_color); o_ptr += 2; } else *o_ptr++ = (UBYTE)t_color; } else *o_ptr++ = (UBYTE)t_color; } /* end of output */ } /* end of x */ } /* end of y */ } void IFF_Buffer_HAM8(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize,d_flag) UBYTE *out; /* output image (size of section) */ UBYTE *in; /* input image */ XA_CHDR *chdr; /* color header to map to */ ColorReg *h_cmap; /* ham color map */ ULONG xosize,yosize; /* size of section in input buffer */ ULONG xip,yip; /* pos of section in input buffer */ ULONG xisize; /* x size of input buffer */ ULONG d_flag; /* map_flag */ { XA_CHDR *the_chdr; ULONG new_cmap_flag,*the_map,psize; register ULONG y,xend,the_moff,coff; USHORT g_adj[64]; if (x11_display_type & XA_X11_TRUE) for(y=0;y<64;y++) g_adj[y] = xa_gamma_adj[ ((65 * y) >> 4) ]; the_map = chdr->map; coff = chdr->coff; if (chdr->new_chdr == 0) { the_chdr = chdr; new_cmap_flag = 0; } else { the_chdr = chdr->new_chdr; new_cmap_flag = 1; } the_moff = chdr->moff; if (x11_display_type & XA_X11_TRUE) d_flag = TRUE; if (d_flag==TRUE) psize = x11_bytes_pixel; else psize = 1; if (xa_ham_map_size != XA_HAM8_CACHE_SIZE) { if (xa_ham_map == 0) { xa_ham_map_size = XA_HAM8_CACHE_SIZE; xa_ham_map = (ULONG *)malloc( xa_ham_map_size * sizeof(ULONG) ); if (xa_ham_map == 0) IFF_TheEnd1("IFF_Buffer_HAM8: h_map malloc err"); } else { ULONG *tmp; xa_ham_map_size = XA_HAM8_CACHE_SIZE; tmp = (ULONG *) realloc(xa_ham_map,xa_ham_map_size * sizeof(ULONG)); if (tmp == 0) IFF_TheEnd1("IFF_Buffer_HAM8: h_map malloc err"); xa_ham_map = tmp; } xa_ham_chdr = 0; } if ( (the_chdr != xa_ham_chdr) || (xa_ham_init != 8)) { register ULONG i; DEBUG_LEVEL1 fprintf(stderr,"xa_ham8_map: old = %lx new = %lx\n", (ULONG)xa_ham_chdr,(ULONG)the_chdr); for(i=0; i<XA_HAM8_CACHE_SIZE; i++) xa_ham_map[i] = XA_HAM_MAP_INVALID; xa_ham_chdr = the_chdr; xa_ham_init = 8; } xend = xip + xosize; if (xend > xisize) xend = xisize; for (y=yip; y < (yip + yosize); y++) { register ULONG x; register UBYTE *i_ptr = (UBYTE *)( in + y * xisize ); register UBYTE *o_ptr = (UBYTE *)( out + (y-yip) *xosize * psize); register ULONG pred,pgrn,pblu,data; pred = pgrn = pblu = 0; for (x=0; x<xend; x++) { data = (ULONG )(*i_ptr++); switch(data & 0xc0) { case 0x00: /* use color register given by low */ { register ULONG low = data & 0x3f; pred = h_cmap[low].red; pgrn = h_cmap[low].green; pblu = h_cmap[low].blue; } break; case 0x40: pblu = data & 0x3f; break; /* change blue */ case 0x80: pred = data & 0x3f; break; /* change red */ case 0xc0: pgrn = data & 0x3f; break; /* change green */ } if ( (x >= xip) && (x < xend) ) { register ULONG t_color; register ULONG indx = (pred << 12) | (pgrn << 6) | pblu; if ( (t_color = xa_ham_map[indx]) == XA_HAM_MAP_INVALID) { if (x11_display_type & XA_X11_TRUE) t_color = X11_Get_True_Color( g_adj[pred],g_adj[pgrn],g_adj[pblu],16); else /* no gamma here because it's already in cmap */ { if (cmap_true_to_332 == TRUE) t_color = CMAP_GET_332(pred,pgrn,pblu,CMAP_SCALE6); else t_color = CMAP_GET_GRAY(pred,pgrn,pblu,CMAP_SCALE11); if (new_cmap_flag) t_color = the_map[t_color - coff] + the_moff; } xa_ham_map[indx] = t_color; } if (d_flag) { if (x11_bytes_pixel == 4) { ULONG *ulp = (ULONG *)o_ptr; *ulp = t_color; o_ptr += 4; } else if (x11_bytes_pixel == 2) { USHORT *usp = (USHORT *)o_ptr; *usp = (USHORT)(t_color); o_ptr += 2; } else *o_ptr++ = (UBYTE)t_color; } else *o_ptr++ = (UBYTE)t_color; } /* end of output */ } /* end of x */ } /* end of y */ } void IFF_Shift_CMAP(cmap,csize) ColorReg *cmap; ULONG csize; { ULONG i; for(i=0;i<csize;i++) { cmap[i].red >>= 4; cmap[i].green >>= 4; cmap[i].blue >>= 4; } } ULONG IFF_Delta_7(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,extra) UBYTE *image; /* Image Buffer. */ UBYTE *delta; /* delta data. */ ULONG dsize; /* delta size */ XA_CHDR *chdr; /* color map info */ ULONG *map; /* used if it's going to be remapped. */ ULONG map_flag; /* whether or not to use remap_map info. */ ULONG imagex,imagey; /* Size of image buffer. */ ULONG imaged; /* Depth of Image. (IFF specific) */ ULONG *xs,*ys; /* pos of changed area. */ ULONG *xe,*ye; /* size of changed area. */ ULONG special; /* Special Info. */ ULONG extra; /* Extra Info. 0 = short encoding, 1 = long encoding*/ { register LONG col,depth,dmask; register LONG rowsize,width; ULONG poff,doff,col_shift; register UBYTE *i_ptr; register UBYTE *optr,opcnt,op,cnt; UBYTE *d_ptr; LONG miny,minx,maxy,maxx; /* set to opposites for min/max testing */ *xs = imagex; *ys = imagey; *xe = 0; *ye = 0; i_ptr = image; width = imagex; col_shift = (extra)?4:5; rowsize = width >> col_shift; dmask = 1; for(depth=0; depth<imaged; depth++) { minx = -1; maxx = -1; i_ptr = image; /* offset into delt chunk */ { register ULONG ddepth = depth << 2; poff = (ULONG)(delta[ ddepth++ ]) << 24; poff |= (ULONG)(delta[ ddepth++ ]) << 16; poff |= (ULONG)(delta[ ddepth++ ]) << 8; poff |= (ULONG)(delta[ ddepth ]); ddepth +=29; /* move to data */ doff = (ULONG)(delta[ ddepth++ ]) << 24; doff |= (ULONG)(delta[ ddepth++ ]) << 16; doff |= (ULONG)(delta[ ddepth++ ]) << 8; doff |= (ULONG)(delta[ ddepth ]); } if (poff) { optr = (UBYTE *)(delta + poff); d_ptr = (UBYTE *)(delta + doff); for(col=0;col<rowsize;col++) { /* start at top of column */ i_ptr = (UBYTE *)(image + (col << col_shift)); opcnt = *optr++; /* get number of ops for this column */ miny = -1; maxy = -1; while(opcnt) /* execute ops */ { /* keep track of min and max columns */ if (minx == -1) minx = col; maxx = col; op = *optr++; /* get op */ if (extra) /* SHORT Data */ { if (op & 0x80) /* if type uniqe */ { if (miny == -1) miny = (ULONG)(i_ptr - image ) / width; cnt = op & 0x7f; /* get cnt */ while(cnt--) /* loop through data */ { register ULONG data; data = (*d_ptr++) << 8; data |= *d_ptr++; IFF_Short_Mod(i_ptr,data,dmask,0); i_ptr += width; } } /* end unique */ else { if (op == 0) /* type same */ { register USHORT data; if (miny == -1) miny=(ULONG)(i_ptr - image) / width; cnt = *optr++; data = (*d_ptr++) << 8; data |= *d_ptr++; while(cnt--) /* loop through data */ { IFF_Short_Mod(i_ptr,data,dmask,0); i_ptr += width; } } /* end same */ else { i_ptr += (width * op); /* type skip */ } } /* end of hi bit clear */ } /* end of short data */ else /* LONG Data */ { if (op & 0x80) /* if type uniqe */ { if (miny == -1) miny=(ULONG)( i_ptr - image ) / width; cnt = op & 0x7f; /* get cnt */ while(cnt--) /* loop through data */ { register ULONG data; data = (*d_ptr++)<<24; data |= (*d_ptr++)<<16; data |= (*d_ptr++)<<8; data |= *d_ptr++; IFF_Long_Mod(i_ptr,data,dmask,0); i_ptr += width; } } /* end unique */ else { if (op == 0) /* type same */ { register ULONG data; if (miny == -1) miny=(ULONG)( i_ptr - image ) / width; cnt = *optr++; data = (*d_ptr++)<<24; data |= (*d_ptr++)<<16; data |= (*d_ptr++)<<8; data |= *d_ptr++; while(cnt--) {IFF_Long_Mod(i_ptr,data,dmask,0); i_ptr += width;} } /* end same */ else { i_ptr += (width * op); /* type skip */ } } /* end of hi bit clear */ } /* end of long data */ opcnt--; } /* end of while opcnt */ maxy = (ULONG)( i_ptr - image ) / width; if ( (miny>=0) && (miny < *ys)) *ys = miny; if ( (maxy>=0) && (maxy > *ye)) *ye = maxy; } /* end of column loop */ } /* end of valid pointer for this plane */ dmask <<= 1; minx <<= col_shift; maxx <<= col_shift; maxx = (extra)?(maxx+15):(maxx+31); if ( (minx>=0) && (minx < *xs)) *xs = minx; if ( (maxx>=0) && (maxx > *xe)) *xe = maxx; } /* end of for depth */ if (xa_optimize_flag == TRUE) { if (*xs >= imagex) *xs = 0; if (*ys >= imagey) *ys = 0; if (*xe <= 0) *xe = imagex; if (*ye <= 0) *ye = imagey; } else { *xs = 0; *ys = 0; *xe = imagex; *ye = imagey; } return(ACT_DLTA_NORM); } /* end of routine */ /* POD NOTE: no need to support xorflag yet */ void IFF_Long_Mod(ptr,data,dmask,xorflag) UBYTE *ptr; ULONG data,dmask,xorflag; { register UBYTE *_iptr = ptr; register UBYTE dmaskoff = ~dmask; if (xorflag) TheEnd1("IFF comp7: xorflag not supported yet. Contact Author"); if (0x80000000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x40000000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x20000000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x10000000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x08000000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x04000000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x02000000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x01000000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00800000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00400000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00200000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00100000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00080000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00040000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00020000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00010000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00008000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00004000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00002000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00001000 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000800 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000400 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000200 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000100 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000080 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000040 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000020 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000010 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000008 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000004 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000002 & data) *_iptr++ |= dmask; else *_iptr++ &= dmaskoff; if (0x00000001 & data) *_iptr |= dmask; else *_iptr &= dmaskoff; } void IFF_HAM6_As_True(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize) UBYTE *out,*in; XA_CHDR **chdr; ColorReg *h_cmap; ULONG xosize,yosize,xip,yip,xisize; { ULONG xend,y; UBYTE *tpic,*optr; USHORT g_adj[16]; for(y=0;y<16;y++) g_adj[y] = xa_gamma_adj[ (17 * y) ] >> 8; tpic = (UBYTE *)malloc( 3 * xosize * yosize); if (tpic == 0) TheEnd1("IFF_HAM6_As_True: malloc err\n"); optr = tpic; xend = xip + xosize; if (xend > xisize) xend = xisize; for (y=yip; y < (yip + yosize); y++) { register ULONG x; register UBYTE *i_ptr = (UBYTE *)( in + y * xisize ); register ULONG pred,pgrn,pblu,data; pred = pgrn = pblu = 0; for (x=0; x<xend; x++) { data = (ULONG )(*i_ptr++); switch( (data & 0x30) ) { case 0x00: /* use color register given by low */ { register ULONG low; low = data & 0x0f; pred = g_adj[ h_cmap[low].red ]; pgrn = g_adj[ h_cmap[low].green ]; pblu = g_adj[ h_cmap[low].blue ]; } break; case 0x10: pblu = g_adj[ (data & 0x0f) ]; break; case 0x20: pred = g_adj[ (data & 0x0f) ]; break; case 0x30: pgrn = g_adj[ (data & 0x0f) ]; break; } if ( (x >= xip) && (x < xend) ) { *optr++ = pred; *optr++ = pgrn; *optr++ = pblu; } } /* end of x */ } /* end of y */ if ( (cmap_true_to_all == TRUE) || ((cmap_true_to_1st == TRUE) && (iff_chdr == 0)) ) iff_chdr = CMAP_Create_CHDR_From_True(tpic,8,8,8,xosize,yosize, iff_cmap,&iff_imagec); else if ( (cmap_true_to_332 == TRUE) && (iff_chdr == 0) ) iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec); else if ( (cmap_true_to_gray == TRUE) && (iff_chdr == 0) ) iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec); if (cmap_dither_type == CMAP_DITHER_FLOYD) out = UTIL_RGB_To_FS_Map(out,tpic,iff_chdr,xosize,yosize,TRUE); else out = UTIL_RGB_To_Map(out,tpic,iff_chdr,xosize,yosize,TRUE); *chdr = iff_chdr; } void IFF_HAM8_As_True(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize) UBYTE *out,*in; XA_CHDR **chdr; ColorReg *h_cmap; ULONG xosize,yosize,xip,yip,xisize; { ULONG xend,y; UBYTE *tpic,*optr; USHORT g_adj[64]; for(y=0;y<64;y++) g_adj[y] = xa_gamma_adj[ ((65 * y) >> 4) ] >> 8; tpic = (UBYTE *)malloc( 3 * xosize * yosize); if (tpic == 0) TheEnd1("IFF_HAM8_As_True: malloc err\n"); optr = tpic; xend = xip + xosize; if (xend > xisize) xend = xisize; for (y=yip; y < (yip + yosize); y++) { register ULONG x; register UBYTE *i_ptr = (UBYTE *)( in + y * xisize ); register ULONG pred,pgrn,pblu,data; pred = pgrn = pblu = 0; for (x=0; x<xend; x++) { data = (ULONG )(*i_ptr++); switch( (data & 0xc0) ) { case 0x00: /* use color register given by low */ { register ULONG low = data & 0x3f; pred = g_adj[ h_cmap[low].red ]; pgrn = g_adj[ h_cmap[low].green ]; pblu = g_adj[ h_cmap[low].blue ]; } break; case 0x40: pblu = g_adj[ (data & 0x3f) ]; break; case 0x80: pred = g_adj[ (data & 0x3f) ]; break; case 0xc0: pgrn = g_adj[ (data & 0x3f) ]; break; } if ( (x >= xip) && (x < xend) ) { *optr++ = pred; *optr++ = pgrn; *optr++ = pblu; } } /* end of x */ } /* end of y */ if ( (cmap_true_to_all == TRUE) || ((cmap_true_to_1st == TRUE) && (iff_chdr == 0)) ) iff_chdr = CMAP_Create_CHDR_From_True(tpic,8,8,8,xosize,yosize, iff_cmap,&iff_imagec); else if ( (cmap_true_to_332 == TRUE) && (iff_chdr == 0) ) iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec); else if ( (cmap_true_to_gray == TRUE) && (iff_chdr == 0) ) iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec); if (cmap_dither_type == CMAP_DITHER_FLOYD) out = UTIL_RGB_To_FS_Map(out,tpic,iff_chdr,xosize,yosize,TRUE); else out = UTIL_RGB_To_Map(out,tpic,iff_chdr,xosize,yosize,TRUE); *chdr = iff_chdr; } ULONG IFF_Delta_Body(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged, xs,ys,xe,ye,special,extra) UBYTE *image; /* ptr to image out */ UBYTE *delta; /* ptr to delta */ ULONG dsize; /* delta size */ XA_CHDR *chdr; /* color map info */ ULONG *map; /* pixel map - use if map_flag */ ULONG map_flag; /* ignored */ ULONG imagex,imagey,imaged; /* image size and depth */ ULONG *xs,*ys; /* pos of changed area */ ULONG *xe,*ye; /* size of changed area */ ULONG special; /* reserved */ ULONG extra; /* Extra Info. */ { ULONG image_size = imagex * imagey; memcpy( (char *)image, (char *)delta, image_size); *xs = *ys = 0; *xe = imagex; *ye = imagey; return(ACT_DLTA_BODY); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.