home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-18 | 31.2 KB | 1,087 lines |
- /************************************************************************
- * *
- * spr_fsi.c *
- * ========= *
- * *
- * RISCOS sprite manipulation utility *
- * Supports scaling, depth (colour) expansion/reduction *
- * with image processing features. *
- * Uses Floyd-Steinburg Integer (FSI) error distrubution dithering *
- * *
- * Version 0.01 (18-Jan-1993) *
- * 0.02 (24-Feb-1993) *
- * 0.03 (15-Mar-1993) *
- * 0.04 (28-Apr-1993) *
- * 0.05 (10-May-1993) Split to form process.c *
- * 0.06 (16-Jun-1993) *
- * 0.07 (13-Aug-1993) *
- * 0.08 (31-Aug-1993) *
- * 0.09 (13-Sep-1993) *
- * 0.10 (13-Oct-1993) *
- * 1.00 (13-Jan-1994) *
- * 1.10 (20-Apr-1994) filters added *
- * *
- * (C) 1993-4 DEEJ Technology PLC *
- * *
- ************************************************************************/
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "io.h"
- #include "sprite.h"
- #include "process.h"
- #include "palette.h"
-
- /******************************** Constants ********************************/
-
- typedef enum
- {
- PAL_INPUT = 0,
- PAL_DESK = 1,
- PAL_WIN3 = 2,
- PAL_RGB = 3,
- PAL_GREY = 4,
- PAL_FIX = 5,
- PAL_OPT = 6,
- PAL_NONE = -1
- } palette_type;
-
- const char *palette_names[] =
- {
- "input",
- "desktop",
- "win3",
- "rgb",
- "grey",
- "fix",
- "opt",
- ""
- };
-
- typedef enum
- {
- FILTER_user = 0,
- FILTER_sharpen1 = 1,
- FILTER_sharpen2 = 2,
- FILTER_sharpen3 = 3,
- FILTER_smooth1 = 4,
- FILTER_smooth2 = 5,
- FILTER_smooth3 = 6,
- FILTER_average = 7,
- FILTER_noise1 = 8,
- FILTER_noise2 = 9,
- FILTER_noise3 = 10,
- FILTER_edge = 11,
- FILTER_edgeV = 12,
- FILTER_edgeH = 13,
- FILTER_edgeNW = 14,
- FILTER_edgeNE = 15,
- FILTER_edgeSW = 16,
- FILTER_edgeSE = 17,
- FILTER_emboss1 = 18,
- FILTER_emboss2 = 19,
- FILTER_none = -1
- } filter_type;
-
- const char *filter_names[] =
- {
- "user",
- "sharpen1",
- "sharpen2",
- "sharpen3",
- "smooth1",
- "smooth2",
- "smooth3",
- "average",
- "noise1",
- "noise2",
- "noise3",
- "edge",
- "edgeV",
- "edgeH",
- "edgeNW",
- "edgeNE",
- "edgeSW",
- "edgeSE",
- "emboss1",
- "emboss2",
- ""
- };
-
- /******************************** structures ********************************/
-
- typedef struct
- {
- int Xmul;
- int Xdiv;
- int Ymul;
- int Ydiv;
- } scale_str;
-
- typedef struct
- {
- process_str pro;
- scale_str scale;
- palette_type palette;
- filter_type filter;
- BOOL aspect;
- BOOL quiet;
- } options_str;
-
- /*************************** Function prototypes ****************************/
-
- void error(char*);
- void syntax(char*);
- void info(void);
- void palette_setup(char*);
- void filter_setup(char*);
- void scale_setup(char*);
- void calc_output_info(spr_info_str*, spr_info_str*);
-
- /*********************************** Data ***********************************/
-
- /* Program parameter globals */
-
- options_str opts;
-
- /* main program data globals */
-
- FILE *inf, *outf, *errf;
- spr_info_str in,out;
-
- /* general globals */
-
- char progname[256];
-
- /* externals */
-
- #ifdef CACHE_STAT
- extern int cache_calls;
- extern int cache_hits;
- extern int cache_misses;
- extern int cache_used;
- #endif
-
- /****************************************************************************/
-
- /*
- * report non continuable error condition
- */
-
- void error(char *err)
- {
- fprintf(errf,"Error: %s - %s unable to continue\n",err,progname);
- exit(1);
- }
-
- /*
- * explain command syntax
- */
-
- void syntax(char *info)
- {
- fprintf(errf,"%s\n",info);
- fprintf(errf,"Syntax:\n");
- fprintf(errf, "%s [-scale {<Xsize>,<Ysize>} |\n",progname);
- fprintf(errf," {<XYmul>:<XYdiv>} |\n");
- fprintf(errf," {<Xmul>:<Xdiv>,<Ymul>:<Ydiv>}]\n");
- fprintf(errf," [-bpp <1|2|4|8|15|24>]\n");
- fprintf(errf," [-palette <rgb|grey|desktop|win3|fix|opt>]\n");
- fprintf(errf," [-filter {<name>}|{<matrix>[,<mul>][,<div>],[<add>],[<min>,<max>]]\n");
- fprintf(errf," [-invert] [-expand] [-gamma <gamma>] [-aspect]\n");
- fprintf(errf," [-nodither] [-nointerp] [-quiet] [-help]\n");
- fprintf(errf," [-in <in_file>] [-out <out_file>] [-err <err_file>]\n");
- fprintf(errf,"\n");
-
-
- /* #### add palette and filter names here */
-
- fprintf(errf,"Input defaults to stdin, output to stdout and\n");
- fprintf(errf,"errors/progress indication to stderr\n");
- }
-
- void info(void)
- {
- int xres, yres, type;
-
- type = (unsigned)out.mode >> 27;
- xres = (out.mode >> 1) & 0xFFF;
- yres = (out.mode >> 14) & 0xFFF;
-
- fprintf(errf,"Scale : %d:%d,%d:%d\n",opts.scale.Xmul,
- opts.scale.Xdiv,
- opts.scale.Ymul,
- opts.scale.Ydiv);
- fprintf(errf,"Pixel aspect: %s\n",opts.aspect ? "TRUE":"FALSE");
- fprintf(errf,"No dither : %s\n",opts.pro.nodither ? "TRUE":"FALSE");
- fprintf(errf,"No interpol.: %s\n",opts.pro.nointerp ? "TRUE":"FALSE");
-
- if(opts.pro.gamma)
- fprintf(errf,"Gamma : %f\n",opts.pro.data.gamma);
- else
- fprintf(errf,"Gamma : None\n");
-
- fprintf(errf,"Palette : %s\n",palette_names[opts.palette]);
-
- if(opts.pro.filter)
- {
- fprintf(errf,"Filter : %s\n",filter_names[opts.filter]);
- fprintf(errf," %2d,%2d,%2d *%d /%d\n",
- opts.pro.data.filter.matrix[0][0],
- opts.pro.data.filter.matrix[0][1],
- opts.pro.data.filter.matrix[0][2],
- opts.pro.data.filter.mul,
- opts.pro.data.filter.div);
- fprintf(errf," %2d,%2d,%2d +%d\n",
- opts.pro.data.filter.matrix[1][0],
- opts.pro.data.filter.matrix[1][1],
- opts.pro.data.filter.matrix[1][2],
- opts.pro.data.filter.add);
- fprintf(errf," %2d,%2d,%2d >%d\n",
- opts.pro.data.filter.matrix[2][0],
- opts.pro.data.filter.matrix[2][1],
- opts.pro.data.filter.matrix[2][2],
- opts.pro.data.filter.diff);
-
- }
- fprintf(errf,"Size : %d,%d\n",out.X,out.Y);
- fprintf(errf,"BPP (cols) : %d/%d (%d)\n",out.bpp,out.pix,out.cols);
-
- if(type == 0)
- fprintf(errf,"Mode : %d (0x%X)\n",out.mode,out.mode);
- else
- fprintf(errf,"Mode (deep) : 0x%X (%d:%dx%d)\n", out.mode,
- type,xres,yres);
- }
-
- /*
- * find palette type for argument
- */
-
- void palette_setup(char *arg)
- {
- int i = 0;
-
- while(strcmp(palette_names[i],"")!=0 && strcmp(palette_names[i],arg)!=0)
- i++;
-
- if(i==0 || strcmp(palette_names[i],"")==0)
- {
- syntax("Error: unrecognised palette type");
- exit(1);
- }
-
- opts.palette = i;
- }
-
- /*
- * find palette type for argument
- */
-
- void filter_setup(char *arg)
- {
- int i = 0;
-
- while(strcmp(filter_names[i],"")!=0 && strcmp(filter_names[i],arg)!=0)
- i++;
-
- if(i==0 || strcmp(filter_names[i],"")==0)
- {
- if(!((arg[0]>='0' && arg[0]<='9') ||
- (arg[0]=='-' && arg[1]>='0' && arg[1]<='9')))
- {
- syntax("Error: unrecognised filter type/format");
- exit(1);
- }
-
- memset(&opts.pro.data.filter, 0, sizeof(filter_str));
- sscanf(arg, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
- &opts.pro.data.filter.matrix[0][0],
- &opts.pro.data.filter.matrix[0][1],
- &opts.pro.data.filter.matrix[0][2],
- &opts.pro.data.filter.matrix[1][0],
- &opts.pro.data.filter.matrix[1][1],
- &opts.pro.data.filter.matrix[1][2],
- &opts.pro.data.filter.matrix[2][0],
- &opts.pro.data.filter.matrix[2][1],
- &opts.pro.data.filter.matrix[2][2],
- &opts.pro.data.filter.mul,
- &opts.pro.data.filter.div,
- &opts.pro.data.filter.add,
- &opts.pro.data.filter.diff);
-
- if(opts.pro.data.filter.mul==0 || opts.pro.data.filter.div==0)
- {
- int j,k;
-
- opts.pro.data.filter.mul = 1;
- opts.pro.data.filter.div = 0;
-
- for(j=0; j<3; j++)
- for(k=0; k<3; k++)
- opts.pro.data.filter.div +=
- opts.pro.data.filter.matrix[j][k];
-
- if(opts.pro.data.filter.div == 0)
- opts.pro.data.filter.div = 1;
- if(opts.pro.data.filter.div < 0)
- opts.pro.data.filter.div =
- -opts.pro.data.filter.div;
- }
-
- opts.pro.filter = TRUE;
- opts.filter = FILTER_user;
- }
- else
- {
- opts.pro.filter = TRUE;
- opts.filter = i;
-
- switch(opts.filter)
- {
- case FILTER_sharpen1:
- {
- filter_str f = { -1, -2, -1,
- -2, 19, -2,
- -1, -2, -1,
- 1,7, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_sharpen2:
- {
- filter_str f = { -1, -2, -1,
- -2, 13, -2,
- -1, -2, -1,
- 1,1, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_sharpen3:
- {
- filter_str f = { 0, -1, 0,
- -1, 5, -1,
- 0, -1, 0,
- 1,1, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_smooth1:
- {
- filter_str f = { 1, 1, 1,
- 1, 24, 1,
- 1, 1, 1,
- 1,32, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_smooth2:
- {
- filter_str f = { 1, 2, 1,
- 2, 4, 2,
- 1, 2, 1,
- 1,16, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_smooth3:
- {
- filter_str f = { 1, 1, 1,
- 1, 2, 1,
- 1, 1, 1,
- 1,10, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_average:
- {
- filter_str f = { 1, 1, 1,
- 1, 1, 1,
- 1, 1, 1,
- 1,9, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_noise1:
- {
- filter_str f = { 1, 1, 1,
- 1, 0, 1,
- 1, 1, 1,
- 1,8, 0, 150 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_noise2:
- {
- filter_str f = { 1, 1, 1,
- 1, 0, 1,
- 1, 1, 1,
- 1,8, 0, 100 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_noise3:
- {
- filter_str f = { 1, 1, 1,
- 1, 0, 1,
- 1, 1, 1,
- 1,8, 0, 50 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_edge:
- {
- filter_str f = { 0, -2, 0,
- -2, 8, -2,
- 0, -2, 0,
- 1,1, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_edgeV:
- {
- filter_str f = { 1, 0, -1,
- 2, 0, -2,
- 1, 0, -1,
- 1,1, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_edgeH:
- {
- filter_str f = { 1, 2, 1,
- 0, 0, 0,
- -1, -2, -1,
- 1,1, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_edgeNW:
- {
- filter_str f = { 2, 1, 0,
- 1, 0, -1,
- 0, -1, -2,
- 1,1, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_edgeNE:
- {
- filter_str f = { 0, 1, 2,
- -1, 0, 1,
- -2, -1, 0,
- 1,1, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_edgeSW:
- {
- filter_str f = { 0, -1, -2,
- 1, 0, -1,
- 2, 1, 0,
- 1,1, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_edgeSE:
- {
- filter_str f = { -2, -1, 0,
- -1, 0, 1,
- 0, 1, 2,
- 1,1, 0, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_emboss1:
- {
- filter_str f = { -1, 0, 0,
- 0, 1, 0,
- 0, 0, 0,
- 1,1, 128, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- case FILTER_emboss2:
- {
- filter_str f = { 0, 0, 0,
- 0, 1, 0,
- 0, 0, -1,
- 1,1, 128, 0 };
- opts.pro.data.filter = f;
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- /*
- * decode -scale argument
- */
-
- void scale_setup(char *arg)
- {
- int a,b,c,d = -1;
- char *comma = strchr(arg, ',');
- char *colon1 = strchr(arg, ':');
- char *colon2 = strrchr(arg,':');
-
- /* Xmul:Xdiv,Ymul:Ydiv */
-
- if(colon1!=0 && colon2!=0 && colon1!=colon2 && comma!=0)
- {
- sscanf(arg,"%d:%d,%d:%d",&a,&b,&c,&d);
- if(a>0 && b>0 && c>0 && d>0)
- {
- opts.scale.Xmul = a;
- opts.scale.Xdiv = b;
- opts.scale.Ymul = c;
- opts.scale.Ydiv = d;
- return;
- }
- else
- {
- syntax("Error: Bad scale factors");
- exit(1);
- }
- }
-
- /* XYmul:XYdiv */
-
- if(colon1!=0 && colon2!=0 && colon1==colon2 && comma==0)
- {
- sscanf(arg,"%d:%d",&a,&b);
- if(a>0 && b>0)
- {
- opts.scale.Xmul = opts.scale.Ymul = a;
- opts.scale.Xdiv = opts.scale.Ydiv = b;
- return;
- }
- else
- {
- syntax("Error: Bad scale factors");
- exit(1);
- }
- }
-
- /* Xsize,Ysize */
-
- if(colon1==0 && colon2==0 && comma!=0)
- {
- sscanf(arg,"%d,%d",&a,&b);
- if(a>0 && b>0)
- {
- if(a > in.X)
- {
- opts.scale.Xmul = a;
- opts.scale.Xdiv = in.X;
- }
- else
- {
- opts.scale.Xmul = in.X;
- opts.scale.Xdiv = a;
- }
- if(b > in.Y)
- {
- opts.scale.Ymul = b;
- opts.scale.Ydiv = in.Y;
- }
- else
- {
- opts.scale.Ymul = in.Y;
- opts.scale.Ydiv = b;
- }
- return;
- }
- else
- {
- syntax("Error: Bad scale factors");
- exit(1);
- }
- }
-
- syntax("Error: Bad scale expression");
- exit(1);
- }
-
- /*
- * calculate spr_info structure for output sprite
- * allocate 24 bit partial buffer for FSI routine
- */
-
- void calc_output_info(spr_info_str *in, spr_info_str *out)
- {
- int i,j,r,g,b;
-
- /* check for preservation of pixel aspect ratio (using global) */
-
- if(opts.aspect)
- {
- out->Xasp = in->Xasp;
- out->Yasp = in->Yasp;
- }
- else
- {
- out->Xasp = 1;
- out->Yasp = 1;
- }
-
- if(opts.scale.Xmul==-1 || opts.scale.Xdiv==-1)
- {
- /* fix up mul or div depending on source image size */
-
- if(opts.scale.Xmul == -1) opts.scale.Xmul = in->X;
- if(opts.scale.Xdiv == -1) opts.scale.Xdiv = in->X;
- }
- else
- {
- /* account for differing pixel aspect ratios in scale factors */
-
- if(in->Xasp > out->Xasp)
- {
- opts.scale.Xmul *= in->Xasp;
- opts.scale.Xdiv *= out->Xasp;
- }
- else
- {
- opts.scale.Xmul *= out->Xasp;
- opts.scale.Xdiv *= in->Xasp;
- }
- }
- if(opts.scale.Ymul==-1 || opts.scale.Ydiv==-1)
- {
- /* fix up mul or div depending on source image size */
-
- if(opts.scale.Ymul == -1) opts.scale.Ymul = in->Y;
- if(opts.scale.Ydiv == -1) opts.scale.Ydiv = in->Y;
- }
- else
- {
- /* account for differing pixel aspect ratios in scale factors */
-
- if(in->Yasp > out->Yasp)
- {
- opts.scale.Ymul *= in->Yasp;
- opts.scale.Ydiv *= out->Yasp;
- }
- else
- {
- opts.scale.Ymul *= out->Yasp;
- opts.scale.Ydiv *= in->Yasp;
- }
- }
-
- /* check for scale factors * or / greater than 128 */
-
- if((opts.scale.Xmul/opts.scale.Xdiv)>=128 ||
- (opts.scale.Xdiv/opts.scale.Xmul)>=128)
- error("X scale factors too large");
- if((opts.scale.Ymul/opts.scale.Ydiv)>=128 ||
- (opts.scale.Ydiv/opts.scale.Ymul)>=128)
- error("Y scale factors too large");
-
- /* calculate output sprites sizes */
-
- out->X = (in->X * opts.scale.Xmul) / opts.scale.Xdiv;
- out->Y = (in->Y * opts.scale.Ymul) / opts.scale.Ydiv;
-
- if(out->X<4 || out->Y<4)
- error("Ridiculously small output sprite with this scale");
-
- if(out->X>32767 || out->Y>32767)
- error("Output sprite is too large for fixed point maths");
-
- if(out->X==in->X && out->Y==in->Y)
- opts.pro.nointerp = TRUE;
-
- if(out->bpp == 24)
- opts.pro.nodither = TRUE;
-
- /* fill out palette and pix spacing */
-
- out->cols = (1<<out->bpp);
-
- switch(opts.palette)
- {
- case PAL_INPUT:
- /* copy palettes if same bpp, else make defaults */
- if((in->cols==out->cols) && in->cols<=256)
- {
- memcpy((void*)out->palette,
- (void*)in->palette,
- out->cols*sizeof(uint));
- }
- else
- {
- default_palette(out);
- }
- break;
-
- case PAL_DESK: /* RISCOS desktop palette */
- if(out->bpp == 4)
- {
- out->palette[0] = 0xFFFFFF00;
- out->palette[1] = 0xDDDDDD00;
- out->palette[2] = 0xBBBBBB00;
- out->palette[3] = 0x99999900;
- out->palette[4] = 0x77777700;
- out->palette[5] = 0x55555500;
- out->palette[6] = 0x33333300;
- out->palette[7] = 0x00000000;
- out->palette[8] = 0x99440000;
- out->palette[9] = 0x00EEEE00;
- out->palette[10] = 0x00CC0000;
- out->palette[11] = 0x0000DD00;
- out->palette[12] = 0xBBEEEE00;
- out->palette[13] = 0x00885500;
- out->palette[14] = 0x00BBFF00;
- out->palette[15] = 0xFFBB0000;
- }
- else
- {
- if(out->bpp == 8)
- default_palette(out);
- else
- error("Desktop palette only available with 4 BPP");
- }
- break;
-
- case PAL_WIN3: /* Microsoft Windows 3 palette */
- switch(out->bpp)
- {
- case 2:
- out->palette[0] = 0x00000000;
- out->palette[1] = 0x80808000;
- out->palette[2] = 0xC0C0C000;
- out->palette[3] = 0xFFFFFF00;
- break;
-
- case 4:
- out->palette[0] = 0x00000000;
- out->palette[1] = 0x00008000;
- out->palette[2] = 0x00800000;
- out->palette[3] = 0x00808000;
- out->palette[4] = 0x80000000;
- out->palette[5] = 0x80008000;
- out->palette[6] = 0x80800000;
- out->palette[7] = 0x80808000;
- out->palette[8] = 0xC0C0C000;
- out->palette[9] = 0x0000FF00;
- out->palette[10] = 0x00FF0000;
- out->palette[11] = 0x00FFFF00;
- out->palette[12] = 0xFF000000;
- out->palette[13] = 0xFF00FF00;
- out->palette[14] = 0xFFFF0000;
- out->palette[15] = 0xFFFFFF00;
- break;
-
- /* not a windows 3 palette, */
- /*but I wanted to use it somewhere */
- case 8: /* 176 greys, 62 2 bpp cube, 18 RGYBMC shades */
-
- for(i=0; i<176; i++)
- {
- j = (i * 255) / 175;
- out->palette[i] = (j<<24) | (j<<16) | (j<<8);
- }
- for(i=1; i<63; i++)
- {
- r = (i & 3) * 0x55;
- g = ((i & 12) >> 2) * 0x55;
- b = ((i & 48) >> 4) * 0x55;
-
- out->palette[i+175] = (b<<24)|(g<<16)|(r<<8);
- }
- for(i=0; i<18; i++)
- {
- switch(i%6)
- {
- case 0: j=0x0000FF00; break;
- case 1: j=0x00FF0000; break;
- case 2: j=0x00FFFF00; break;
- case 3: j=0xFF000000; break;
- case 4: j=0xFF00FF00; break;
- case 5: j=0xFFFF0000; break;
- }
- switch(i/6)
- {
- case 0: j = 0x33333300 & j; break;
- case 1: j = 0x88888800 & j; break;
- case 2: j = 0xDDDDDD00 & j; break;
- }
- out->palette[i+238] = j;
- }
- break;
-
- default:
- error("Windows 3 palette only available with 4 BPP");
- break;
- }
- break;
-
- case PAL_RGB:
- switch(out->bpp)
- {
- case 1:
- case 2:
- error("RGB palette only available with >= 4 BPP");
- break;
-
- case 4: /* 9 greys + 6 full satuarated colours */
- out->palette[0] = 0xFFFFFF00;
- out->palette[1] = 0xDDDDDD00;
- out->palette[2] = 0xBBBBBB00;
- out->palette[3] = 0x99999900;
- out->palette[4] = 0x77777700;
- out->palette[5] = 0x55555500;
- out->palette[6] = 0x33333300;
- out->palette[7] = 0x00000000;
- out->palette[8] = 0xFF000000;
- out->palette[9] = 0x00FFFF00;
- out->palette[10] = 0x00FF0000;
- out->palette[11] = 0x0000FF00;
- out->palette[12] = 0xEEEEEE00;
- out->palette[13] = 0x007FFF00;
- out->palette[14] = 0xFF00FF00;
- out->palette[15] = 0xFFFF0000;
- break;
-
- case 8: /* 6x6x6 r,g,b (minus greys) + 46 greys */
- for(i=0; i<46; i++)
- {
- j = (i * 255) / 45;
- out->palette[i] = (j<<24) | (j<<16) | (j<<8);
- }
- for(r=0; r<6; r++)
- for(g=0; g<6; g++)
- for(b=0; b<6; b++)
- {
- if( !((r==g) && (r==b) && (g==b)) )
- out->palette[i++] = ((r*255/5)<<24) |
- ((g*255/5)<<16) |
- ((b*255/5)<<8);
- }
- break;
-
- case 24: /* RGB_PAL used to select 24 bpp or 24/32 bpp */
- out->pix = 24;
-
- default:
- break;
- }
- break;
-
- case PAL_GREY: /* maximum span grey level palettes */
- if(out->bpp <= 8)
- {
- for(i=0; i<out->cols; i++)
- {
- j = (i * 255) / (out->cols-1);
- out->palette[i] = (j<<24) | (j<<16) | (j<<8);
- }
- }
- else
- error("Grey palette only available with <= 8 BPP");
- break;
-
- case PAL_FIX:
- /*
- * fix input palette by copying
- * upper to lower nibbles
- * if lower nibble is zero
- */
- for(i=0; i<in->cols; i++)
- {
- if((in->palette[i] & 0x0F) == 0)
- in->palette[i] |= (in->palette[i]>>4);
- }
-
- /* copy palettes if same bpp, else make defaults */
-
- if((in->cols==out->cols) && in->cols<=256)
- {
- for(i=0; i<out->cols; i++)
- {
- out->palette[i] = in->palette[i];
- }
- }
- else
- {
- default_palette(out);
- }
- break;
-
- case PAL_OPT:
- if(out->bpp<4 || out->bpp>8)
- error("Optomized palette only available with 4 & 8 BPP");
-
- out->has_palette = out->cols;
-
- /*
- * leave calculating optimised palette until after palette or
- * image altering operations such as invert/expand/gamma
- */
- opts.pro.palette_opt = TRUE;
- break;
-
- default:
- break; /* should be checked by arg processor */
- }
-
- /* select mode from output bpp */
- /* also selects best pixel r/w functions */
-
- fill_info(out);
-
- /* allocate memory for one line of the output image */
-
- alloc_spr_line(out);
- }
-
- int main(int argc, char **argv)
- {
- opts.scale.Xmul = 1;
- opts.scale.Xdiv = 1;
- opts.scale.Ymul = 1;
- opts.scale.Ydiv = 1;
- opts.palette = PAL_INPUT;
- opts.pro.invert = FALSE;
- opts.pro.expand = FALSE;
- opts.pro.gamma = FALSE;
- opts.pro.filter = FALSE;
- opts.pro.nodither = FALSE;
- opts.pro.nointerp = FALSE;
- opts.aspect = FALSE;
- opts.quiet = FALSE;
- in.X = in.Y = -1;
- out.X = out.Y = -1;
- out.bpp = 24;
-
- strcpy(progname,argv[0]);
-
- file_args(argc, argv, &inf, &outf, &errf);
-
- argc--; argv++;
-
- while(argc>0 && (**argv==0 || **argv=='-'))
- {
- if(**argv=='-')
- {
- (*argv)++;
-
- switch(**argv)
- {
- case 's':
- argc--; argv++;
- scale_setup(*argv);
- break;
-
- case 'i':
- opts.pro.invert = TRUE;
- break;
-
- case 'b':
- argc--; argv++;
- out.bpp = atoi(*argv);
- if(out.bpp!=1 && out.bpp!=2 &&
- out.bpp!=4 && out.bpp!=8 &&
- out.bpp!=15 && out.bpp!=24)
- {
- syntax("Error: Bad bits per pixel");
- exit(1);
- }
- /* 24/24 bpp mode by specifing PAL_RGB */
- break;
-
- case 'p':
- argc--; argv++;
- palette_setup(*argv);
- break;
-
- case 'f':
- argc--; argv++;
- filter_setup(*argv);
- break;
-
- case 'e':
- opts.pro.expand = TRUE;
- break;
-
- case 'g':
- argc--; argv++;
- opts.pro.gamma = TRUE;
- opts.pro.data.gamma = (float)atof(*argv);
- break;
-
- case 'a':
- opts.aspect = TRUE; /* preserve pixel aspect ratio */
- break;
-
- case 'n':
- if(strncmp(*argv, "nod", 3)==0)
- opts.pro.nodither = TRUE;
- else if(strncmp(*argv, "noi", 3)==0)
- opts.pro.nointerp = TRUE;
- else
- syntax("Unrecognided -n...");
- break;
-
- case 'q':
- opts.quiet = TRUE;
- break;
-
- case 'h':
- syntax("Sprite processing with FSI dithering");
- exit(0);
- break;
-
- default:
- syntax("Error: Unrecognised parameter");
- exit(1);
- break;
- }
- }
- argc--; argv++;
- }
-
- read_sprite(&in, inf);
- calc_output_info(&in, &out);
-
- if(!opts.quiet) info();
-
- /* main scaling, preprocessing and FSI routine */
-
- opts.pro.in = ∈
- opts.pro.out = &out;
- opts.pro.outf = outf;
- process(&opts.pro);
-
- #ifdef CACHE_STAT
- fprintf(errf,"Cache calls : %d\n", cache_calls);
- fprintf(errf,"Cache hits : %d\n", cache_hits);
- fprintf(errf,"Cache miss : %d\n", cache_misses);
- fprintf(errf,"Cache used : %d\n", cache_used);
- #endif
- }
-