home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C++ Games Programming
/
CPPGAMES.ISO
/
thx
/
source
/
utils
/
cvtpal.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-12
|
3KB
|
162 lines
#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);
}
}
}