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

  1. #include <fastgraf.h>
  2.  
  3. #include <fstream.h>
  4. #include <values.h>   // MAXINT
  5. #include <stdlib.h>
  6. #include <io.h>       // access
  7. #include "pcx.h"
  8.  
  9. const int VMODE = 22;
  10. const int STRLEN = 80;
  11.  
  12. struct pal_entry       // struct compadible with the
  13.   {                    // fg_setdacs routine
  14.   unsigned char r;
  15.   unsigned char g;
  16.   unsigned char b;
  17.   };
  18.  
  19. static pal_entry oldpal[256];
  20. static pal_entry newpal[256];
  21. static int bestmatch[256];
  22. static pcx_header pcx;
  23.  
  24. void store_new_palette(char* fname);
  25. void calc_best_matches();
  26. int get_best_new_color(int oldcolor);
  27. int get_match_rank(int r1,int g1,int b1,int r2,int g2,int b2);
  28. void replace_colors(int w,int h);
  29.  
  30. int main(int argc,char** argv)
  31.   {
  32.   int w,h;
  33.   if (argc<3)
  34.     {
  35.     cout << "\nUSAGE : CVTPAL <pcxfile> <palettefile>\n";
  36.     cout << "  CVTPAL modifies 'pcxfile' so that it uses the palette\n";
  37.     cout << "  defined in 'palettefile'\n";
  38.     return -1;
  39.     }
  40.   if (access(argv[1],0)!=0)
  41.     {
  42.     cout << "can't open file '" << argv[1] << "'\n";
  43.     return -1;
  44.     }
  45.   if (access(argv[2],0)!=0)
  46.     {
  47.     cout << "can't open file '" << argv[2] << "'\n";
  48.     return -1;
  49.     }
  50.  
  51.   fg_pcxhead(argv[1],(char*)&pcx);
  52.   cout << "width = " << pcx.width << '\n';
  53.   cout << "height = " << pcx.height << '\n';
  54.   if (argc>3)
  55.     {
  56.     w=atoi(argv[3])-1;
  57.     h=atoi(argv[4])-1;
  58.     }
  59.   else
  60.     {
  61.     w=pcx.width+1-pcx.x;
  62.     h=pcx.height+1-pcx.y;
  63.     }
  64.  
  65.   int oldmode=fg_getmode();
  66.   fg_setmode(VMODE);
  67.   fg_setcolor(0);
  68.   fg_rect(0,319,0,239);
  69.  
  70.   fg_move(0,0);
  71.   fg_showpcx(argv[1],2);
  72.  
  73.   fg_getdacs(0,256,(char*)oldpal);
  74.   store_new_palette(argv[2]);
  75.  
  76.   fg_setdacs(0,256,(char*)newpal);
  77.  
  78.   calc_best_matches();
  79.   replace_colors(w,h);
  80.   fg_makepcx(0,w-1,0,h-1,argv[1]);
  81.  
  82.   fg_setmode(oldmode);
  83.   return 0;
  84.   }
  85.  
  86. void store_new_palette(char* fname)
  87.   // read in a Neopaint (c) ascii palette file
  88.   // into the global array 'newpal'
  89.   {
  90.   int r,g,b;
  91.   static char str[STRLEN];
  92.  
  93.   ifstream pal(fname);
  94.   if (pal.bad())  return;
  95.  
  96.   pal.getline(str,STRLEN);  // NeoPaint ...
  97.   pal.getline(str,STRLEN);  // blah blah...
  98.   pal.getline(str,STRLEN);  // palette size
  99.   if (atoi(str)!=256)
  100.     {
  101.     fg_setmode(3);
  102.     cout << "the palettefile should contain 256 entries.\n";
  103.     exit(1);
  104.     };
  105.   for (int i=0;i<256;i++)
  106.     {
  107.     pal >> r;
  108.     pal >> g;
  109.     pal >> b;
  110.     newpal[i].r=(unsigned char)r;
  111.     newpal[i].g=(unsigned char)g;
  112.     newpal[i].b=(unsigned char)b;
  113.     }
  114.   }
  115.  
  116. void calc_best_matches()
  117.   {
  118.   int oldcolor;
  119.   for (oldcolor=0;oldcolor<256;oldcolor++)
  120.     {
  121.     bestmatch[oldcolor]=get_best_new_color(oldcolor);
  122.     }
  123.   }
  124.  
  125. int get_best_new_color(int oldcolor)
  126.   {
  127.   int matchval,bestval=MAXINT;
  128.   int bestindex;
  129.   unsigned char r,g,b;
  130.   r=oldpal[oldcolor].r;
  131.   g=oldpal[oldcolor].g;
  132.   b=oldpal[oldcolor].b;
  133.  
  134.   for (int i=0;i<256;i++)
  135.     {
  136.     matchval=get_match_rank(r,g,b,newpal[i].r,newpal[i].g,newpal[i].b);
  137.     if (matchval<bestval)
  138.       {
  139.       bestval=matchval;
  140.       bestindex=i;
  141.       }
  142.     }
  143.   return bestindex;
  144.   }
  145.  
  146. int get_match_rank(int r1,int g1,int b1,int r2,int g2,int b2)
  147.   {
  148.   return (abs(r1-r2) + abs(g1-g2) + abs(b1-b2));
  149.   }
  150.  
  151. void replace_colors(int w,int h)
  152.   {
  153.   for (int wi=0;wi<w;wi++)
  154.     {
  155.     for (int hi=0;hi<h;hi++)
  156.       {
  157.       fg_setcolor(bestmatch[fg_getpixel(wi,hi)]);
  158.       fg_point(wi,hi);
  159.       }
  160.     }
  161.   }
  162.