home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- * *
- * Copyright (c) 1988, David B. Wecker *
- * All Rights Reserved *
- * *
- * This file is part of DBW_uRAY *
- * *
- * DBW_uRAY is distributed in the hope that it will be useful, but *
- * WITHOUT ANY WARRANTY. No author or distributor accepts *
- * responsibility to anyone for the consequences of using it or for *
- * whether it serves any particular purpose or works at all, unless *
- * he says so in writing. Refer to the DBW_uRAY General Public *
- * License for full details. *
- * *
- * Everyone is granted permission to copy, modify and redistribute *
- * DBW_uRAY, but only under the conditions described in the *
- * DBW_uRAY General Public License. A copy of this license is *
- * supposed to have been given to you along with DBW_uRAY so you *
- * can know your rights and responsibilities. It should be in a file *
- * named COPYING. Among other things, the copyright notice and this *
- * notice must be preserved on all copies. *
- ************************************************************************
- * *
- * Authors: *
- * DBW - David B. Wecker *
- * *
- * Versions: *
- * V1.0 881023 DBW - First released version *
- * V1.1 881110 DBW - Fixed scan coherence code *
- * V1.2 881125 DBW - Removed ALL scan coherence code (useless) *
- * added "fat" extent boxes *
- * *
- ************************************************************************/
-
- #include "uray.h"
-
-
- /************************************************************************/
- /************ module to write output files ******************************/
- /************************************************************************/
-
-
- void wfil(fil,cnt,val) /* write a number to a file (68000 order) */
- FILE *fil;
- short cnt;
- char val[];
- {
-
- #ifdef MCH_AMIGA
- fwrite(val,cnt,1,fil);
- #else
- while (cnt--) fwrite(&val[cnt],1,1,fil);
- #endif
-
- }
-
- short rfil(fil,cnt,val) /* read a number from a file (68000 order) */
- FILE *fil;
- short cnt;
- char val[];
- {
-
- #ifdef MCH_AMIGA
- if (fread(val,cnt,1,fil) != 1) return(-1);
- #else
- while (cnt--) if (fread(&val[cnt],1,1,fil) != 1) return(-1);
- #endif
-
- return(0);
- }
-
-
- /* create output files */
- void coutputs() {
- int i;
-
- /* first create the output .tmp file */
- if (bpp) {
- sprintf(str,"%s.tmp",basnam);
- fp = fopen(str,"w");
- if (!fp) leave("Bad output file");
-
- /* write out the header */
- wfil(fp,sizeof(short),&startrow);
- wfil(fp,sizeof(short),&endrow);
- wfil(fp,sizeof(short),&cols);
- wfil(fp,sizeof(short),&bpp);
- }
-
- /* second, create the output .ilbm file */
- sprintf(str,"%s.ilbm",basnam);
- fp2 = fopen(str,"w");
- if (!fp2) leave("Bad output file (ilbm)");
-
- /* write out the header */
- sprintf(str,"FORM"); fwrite(str,1,4,fp2);
- pos1 = ftell(fp2);
- lng = FORMsize; wfil(fp2,sizeof(long),&lng);
- sprintf(str,"ILBM"); fwrite(str,1,4,fp2);
-
- sprintf(str,"BMHD"); fwrite(str,1,4,fp2);
- lng = BMHDsize; wfil(fp2,4,&lng);
- wrd = cols; wfil(fp2,2,&wrd); /* width */
- wrd = rows; wfil(fp2,2,&wrd); /* height */
- wrd = startrow; wfil(fp2,2,&wrd); /* top */
- wrd = 0; wfil(fp2,2,&wrd); /* left */
- byt = DEPTH; wfil(fp2,1,&byt); /* Depth */
- byt = 0; wfil(fp2,1,&byt); /* mask */
- byt = 1; wfil(fp2,1,&byt); /* compress */
- byt = 0; wfil(fp2,1,&byt); /* pad */
- wrd = 0; wfil(fp2,2,&wrd); /* transparency */
- byt = 10; wfil(fp2,1,&byt); /* aspect x */
- byt = 11; wfil(fp2,1,&byt); /* aspect y */
- wrd = cols; wfil(fp2,2,&wrd); /* page width */
- wrd = rows; wfil(fp2,2,&wrd); /* page height */
-
- sprintf(str,"CAMG"); fwrite(str,1,4,fp2);
- lng = CAMGsize; wfil(fp2,4,&lng);
- lng = HAM | LACE; wfil(fp2,4,&lng);
-
- sprintf(str,"CMAP"); fwrite(str,1,4,fp2);
- lng = CMAPsize; wfil(fp2,4,&lng);
- pos3 = ftell(fp2);
- colors[0][0] = colors[0][1] = colors[0][2] = 0;
- lstcolor = 1;
- fwrite(colors,1,48,fp2);
- fwrite(colors,1,48,fp2);
-
- sprintf(str,"BODY"); fwrite(str,1,4,fp2);
- pos2 = ftell(fp2);
- lng = BODYsize; wfil(fp2,4,&lng);
-
- lsize = 0L;
- }
-
- /* write a scan line to the output files */
- void woutputs(sline)
- short sline;
- {
- int i,j,k,c,d,old[3],new[3],x,pxl,scr,addok,
- index,bdist,ndist,maxdist,dcol,dval;
- unsigned char buf[512],planes[6][128],b1,b2;
-
- /* print out 'dots' so the user knows we're working */
- if (sline % 50 == 0 || sline == startrow)
- printf("Row %4d: ",sline);
- printf(".");
- if (sline % 50 == 49) printf("\n");
- else fflush(stdout);
-
- /* write out a scan line to .tmp file */
- if (bpp) {
- wfil(fp,sizeof(short),&sline);
-
- /* now write out each color of the scan line */
- for (i=0; i<3; i++) {
-
- /* write out 24 bits per pixel */
- if (cols == obpsl) fwrite(outary[i],1,obpsl,fp);
-
- /* or 12 bits per pixel (need to pack it) */
- else {
- for (x=0; x<cols; x++) {
- b1 = outary[i][x];
- b2 = b1 >> 4;
- if (x & 1) buf[x>>1] |= b2 & 0x0F;
- else buf[x>>1] = b1 & 0xF0;
- }
- fwrite(buf,1,obpsl,fp);
- }
- }
- fflush(fp);
- }
-
- /* initialize the HAM encoding */
- for (i=0; i<3; i++) old[i] = 0;
- for (d=0; d<6; d++)
- for (i=0; i<MAXBYTE; i++)
- planes[d][i] = 0;
-
- /* allow 1 new color to be added to colors[] per scan line (max) */
- addok = 1;
-
- /* set the amount of error for adding new colors[] */
- if (sline < (rows>>1)) maxdist = 127;
- else maxdist = 63;
-
- for (x=0; x<cols; x++,dcol++) {
-
- /* first get the desired old values (dither as necessary) */
- for (i=0; i<3; i++) {
- dval = ((int)outary[i][x]) & 0xF;
- new[i] = ((int)outary[i][x]) & 0xF0;
- if (dval && new[i] != 0xF0 && dval > (random() & 0xF))
- new[i] += 0x10;
- }
-
- /* get the best absolute color */
- bdist = 9999;
- for (i=0; i<lstcolor; i++) {
- ndist = 0;
- for (j=0; j<3; j++)
- ndist += ABS(new[j] - (int)colors[i][j]);
- if (ndist < bdist) {
- bdist = ndist;
- index = i;
- }
- }
-
- /* now find worst color (to make relative change) */
- ndist = 0;
- j = -1;
- for (i = 0; i<3; i++) {
- if ((k=ABS(new[i] - old[i])) > j) {
- c = i;
- j = k;
- }
- ndist += k;
- }
-
- /* subtract off the gun we want to fix */
- ndist -= j;
-
- /* if relative is best, flag it (index = -1) (unless first pixel) */
- if (x > 0 && ndist < bdist) {
- bdist = ndist;
- index = -1;
- }
-
- /* decide if we need a new color in the color table */
- if (addok && lstcolor < 16 && bdist > maxdist) {
- for (i=0; i<3; i++) colors[lstcolor][i] = (unsigned char)new[i];
- addok = 0;
- bdist = 0;
- index = lstcolor++;
- # if DEBUG_ilbm
- printf("Adding color %2d: %02x%02x%02x\n",index,
- new[0],new[1],new[2]);
- # endif
- }
-
- /* now change the gun (for relative) */
- if (index == -1) {
- pxl = (old[c] = new[c]) >> 4;
- switch (c) {
- case 0: pxl |= 0x20; break;
- case 1: pxl |= 0x30; break;
- case 2: pxl |= 0x10; break;
- }
- }
- else {
- pxl = index;
- for (i=0; i<3; i++) old[i] = (int)colors[index][i];
- }
-
- # if DEBUG_ilbm
- printf("%4d,%4d: %02x (%d)\n",sline,x,pxl,bdist);
- # endif
-
- /* and store the pixel away */
- j = x >> 3;
- k = 7 - (x & 0x7);
- for (i=0; i<DEPTH; i++) {
- planes[i][j] |= (pxl & 1) << k;
- pxl >>= 1;
- }
- }
-
- /* now pack the row away (RKM run length encoding) */
- for (i=0; i < DEPTH; i++) {
- wrd = PackRow(planes[i],buf,MAXBYTE);
- lsize += (long)wrd;
- fwrite(buf,1,wrd,fp2);
- }
- }
-