home *** CD-ROM | disk | FTP | other *** search
- #include <fastgraf.h>
-
- #include <fstream.h>
- #include <values.h> // MAXINT
- #include <stdlib.h>
- #include <io.h> // access
- #include "pcx.h"
-
- const int VMODE = 22;
- const int STRLEN = 80;
-
- struct pal_entry // struct compadible with the
- { // fg_setdacs routine
- unsigned char r;
- unsigned char g;
- unsigned char b;
- };
-
- static pal_entry oldpal[256];
- static pal_entry newpal[256];
- static int bestmatch[256];
- static pcx_header pcx;
-
- void store_new_palette(char* fname);
- void calc_best_matches();
- int get_best_new_color(int oldcolor);
- int get_match_rank(int r1,int g1,int b1,int r2,int g2,int b2);
- void replace_colors(int w,int h);
-
- int main(int argc,char** argv)
- {
- int w,h;
- if (argc<3)
- {
- cout << "\nUSAGE : CVTPAL <pcxfile> <palettefile>\n";
- cout << " CVTPAL modifies 'pcxfile' so that it uses the palette\n";
- cout << " defined in 'palettefile'\n";
- return -1;
- }
- if (access(argv[1],0)!=0)
- {
- cout << "can't open file '" << argv[1] << "'\n";
- return -1;
- }
- if (access(argv[2],0)!=0)
- {
- cout << "can't open file '" << argv[2] << "'\n";
- return -1;
- }
-
- fg_pcxhead(argv[1],(char*)&pcx);
- cout << "width = " << pcx.width << '\n';
- cout << "height = " << pcx.height << '\n';
- if (argc>3)
- {
- w=atoi(argv[3])-1;
- h=atoi(argv[4])-1;
- }
- else
- {
- w=pcx.width+1-pcx.x;
- h=pcx.height+1-pcx.y;
- }
-
- int oldmode=fg_getmode();
- fg_setmode(VMODE);
- fg_setcolor(0);
- fg_rect(0,319,0,239);
-
- fg_move(0,0);
- fg_showpcx(argv[1],2);
-
- fg_getdacs(0,256,(char*)oldpal);
- store_new_palette(argv[2]);
-
- fg_setdacs(0,256,(char*)newpal);
-
- calc_best_matches();
- replace_colors(w,h);
- fg_makepcx(0,w-1,0,h-1,argv[1]);
-
- fg_setmode(oldmode);
- return 0;
- }
-
- void store_new_palette(char* fname)
- // read in a Neopaint (c) ascii palette file
- // into the global array 'newpal'
- {
- int r,g,b;
- static char str[STRLEN];
-
- ifstream pal(fname);
- if (pal.bad()) return;
-
- pal.getline(str,STRLEN); // NeoPaint ...
- pal.getline(str,STRLEN); // blah blah...
- pal.getline(str,STRLEN); // palette size
- if (atoi(str)!=256)
- {
- fg_setmode(3);
- cout << "the palettefile should contain 256 entries.\n";
- exit(1);
- };
- for (int i=0;i<256;i++)
- {
- pal >> r;
- pal >> g;
- pal >> b;
- newpal[i].r=(unsigned char)r;
- newpal[i].g=(unsigned char)g;
- newpal[i].b=(unsigned char)b;
- }
- }
-
- void calc_best_matches()
- {
- int oldcolor;
- for (oldcolor=0;oldcolor<256;oldcolor++)
- {
- bestmatch[oldcolor]=get_best_new_color(oldcolor);
- }
- }
-
- int get_best_new_color(int oldcolor)
- {
- int matchval,bestval=MAXINT;
- int bestindex;
- unsigned char r,g,b;
- r=oldpal[oldcolor].r;
- g=oldpal[oldcolor].g;
- b=oldpal[oldcolor].b;
-
- for (int i=0;i<256;i++)
- {
- matchval=get_match_rank(r,g,b,newpal[i].r,newpal[i].g,newpal[i].b);
- if (matchval<bestval)
- {
- bestval=matchval;
- bestindex=i;
- }
- }
- return bestindex;
- }
-
- int get_match_rank(int r1,int g1,int b1,int r2,int g2,int b2)
- {
- return (abs(r1-r2) + abs(g1-g2) + abs(b1-b2));
- }
-
- void replace_colors(int w,int h)
- {
- for (int wi=0;wi<w;wi++)
- {
- for (int hi=0;hi<h;hi++)
- {
- fg_setcolor(bestmatch[fg_getpixel(wi,hi)]);
- fg_point(wi,hi);
- }
- }
- }
-