home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / MISC / PVQUAN15.ZIP / QUANT.ZIP / QUANT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-03  |  7.6 KB  |  226 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *                  Copyright (c) 1991, Frank van der Hulst             *
  4.  *                          All Rights Reserved                         *
  5.  *                                                                      *
  6.  * Authors:                                                             *
  7.  *        FvdH - Frank van der Hulst (Wellington, NZ)                   *
  8.  *                                                                      *
  9.  * Versions:                                                            *
  10.  *    V1.1 910626 FvdH - QUANT released for DBW_RENDER                    *
  11.  *    V1.2 911021 FvdH - QUANT released for PoV Ray                       *
  12.  *    V1.3 911031 FvdH - Added 320x200x256x4 pages support              *
  13.  *    V1.4 920303 FvdH - Ported to GNU                                  *
  14.  *                     - Changed usage() to fix bug                     *
  15.  *       V1.5 920331 FvdH - Read Targa file format                         *
  16.  *         920403 FvdH - Allow any number of files                      *
  17.  *                                                                      *
  18.  ************************************************************************/
  19. /*
  20.  * quant.c
  21.  *
  22.  * Program to do colour quantization. This program reads PoV Ray raw
  23.  * format files and quantizes the image(s) to produce a file in one of
  24.  * 3 formats -- 2D, 3D or GIF. It can use either Heckbert's median-splitting
  25.  * algorithm, or else the Octree Quantisation algorithm by Michael Gervautz
  26.  * and Werner Purgathofer.
  27.  *
  28.  * This program compiles using Turbo-C v2.01 and runs on an MS-DOS machine,
  29.  * using cc on a SCO Unix system, or gcc on a Sun system.
  30.  */
  31.  
  32. #include <string.h>
  33. #ifdef __TURBOC__
  34. #include <ctype.h>
  35. #endif
  36.  
  37. #include "quant.h"
  38.  
  39. #ifdef HECKBERT
  40. #include "heckbert.h"
  41. #else
  42. #include "octree.h"
  43. #endif
  44.  
  45. unsigned long HUGE_PTR Histogram;        /* image histogram */
  46. unsigned char HUGE_PTR RGBmap;            /* RGB -> index map */
  47.  
  48. unsigned int    ColormaxI;                /* # of colors, 2^input_bits */
  49. UCHAR palette[MAXCOLORS][3];
  50.  
  51. #ifdef __TURBOC__
  52. char                disp_image    = 1;        /* Display image while quantising */
  53. #else
  54. char                disp_image    = 0;        /* Display image while quantising */
  55. #endif
  56. char                 input_type  = 0;        /* Input format switch */
  57.  
  58. static int output_bits        = 6;        /* No. of sig. bits on output (must be <= 8) */
  59. #ifdef HECKBERT
  60. static int fast_quant        = 0;        /* Quantisation speed switch */
  61. /*    If zero, the rgbmap will be built very slowly, but more accurately. The
  62.     error introduced by the approximation is usually small.
  63.  
  64.     If one, the rgbmap will be constructed quickly. */
  65. #endif
  66.  
  67. static int image_width        = 320;    /* Width of image in pixels */
  68. static int image_height        = 200;    /* Height of image in pixels */
  69. static int output_colours     = 256;    /* No. of separate colours to produce ( <= 256) */
  70. static int output_type     = 1;     /* Output format switch */
  71.  
  72. char *input_file;
  73. int num_files = 1;
  74.  
  75. void usage(char *prog_name)
  76. {
  77.     printf("Command syntax: %s [-O=outputbits][-C=colours][-S=speed][-T=outtype]\n", prog_name);
  78.     printf("                   [-D=display][-W=width][-H=height][-I=intype][-N=numfiles] filename\n\n");
  79.     printf("outputbits = bits per colour being output          [6]\n");
  80. #ifdef HECKBERT
  81.     printf("speed      = 0 or 1                                [%d]\n", fast_quant);
  82. #endif
  83.     printf("outtype    = 0 for 4-plane, 1 for planar,2 for GIF [%d]\n", output_type);
  84.     printf("intype     = 0 for raw, 1 for Targa                [%d]\n", input_type);
  85. #ifdef __TURBOC__
  86.     printf("display    = 1 or 0 for displaying during output   [%d]\n", disp_image);
  87. #endif
  88.     printf("colours    = number of separate colours to produce [%d]\n", output_colours);
  89.     printf("width      = width of image in pixels              [%d]\n", image_width);
  90.     printf("height     = height of image in pixels             [%d]\n", image_height);
  91.     printf("numfiles   = number of files to quantise           [%d]\n", num_files);
  92.     printf("filename   = name part of file(s) to read, without extension\n");
  93.     exit(0);
  94. }
  95.  
  96. /********************************************************************
  97.  Process command line arguments. */
  98.  
  99. void get_args(int argc, char *argv[])
  100. {
  101.     int i;
  102.  
  103.     if (argc == 1) usage(argv[0]);
  104.  
  105.     for (i = 1; i < argc; i++) {
  106.         if (argv[i][0] != '/' && argv[i][0] != '-') {
  107.             input_file = argv[i];
  108.             continue;
  109.         }
  110.  
  111.         if (argv[i][2] != '=') {
  112.             printf("Invalid command line switch: %s\n", argv[i]);
  113.             usage(argv[0]);
  114.         }
  115.  
  116.         switch(toupper(argv[i][1])) {
  117.         case 'O': output_bits        = atoi(&argv[i][3]); break;
  118. #ifdef HECKBERT
  119.         case 'S': fast_quant            = atoi(&argv[i][3]); break;
  120. #endif
  121.         case 'T': output_type        = atoi(&argv[i][3]); break;
  122.         case 'I': input_type            = atoi(&argv[i][3]); break;
  123. #ifdef __TURBOC__
  124.         case 'D': disp_image           = atoi(&argv[i][3]); break;
  125. #endif
  126.         case 'C': output_colours     = atoi(&argv[i][3]); break;
  127.         case 'W': image_width        = atoi(&argv[i][3]); break;
  128.         case 'H': image_height     = atoi(&argv[i][3]); break;
  129.         case 'N': num_files        = atoi(&argv[i][3]);    break;
  130.         default:
  131.             printf("Invalid command line switch: %s\n", argv[i]);
  132.             usage(argv[0]);
  133.         }
  134.     }
  135. }
  136.  
  137. #ifdef __GNUC__
  138. void main(int argc, char *argv[])
  139. #else
  140. void cdecl main(int argc, char *argv[])
  141. #endif
  142. {
  143.     int colors, i;
  144. #ifdef HECKBERT
  145.     long int li;
  146. #else
  147. #endif
  148.  
  149.     printf("QUANT v1.50 -- Colour quantisation for PVRay\n");
  150. #ifdef HECKBERT
  151.     printf("By F van der Hulst, based on COLORQUANT by Craig E. Kolb.\n\n");
  152. #else
  153.     printf("By F van der Hulst, based on Octree Quantisation by Wolfgang Stuerzlinger.\n\n");
  154. #endif
  155.  
  156.     get_args(argc, argv);
  157.     if (output_type == 2)
  158.         if (num_files != 1) {
  159.             printf("Can only convert one file to GIF format.\n");
  160.             exit(1);
  161.         }
  162.     if ((output_type == 0) &&
  163.          ((image_width != 320) ||
  164.           ((image_height != 400) && (image_height != 200)))) {
  165.         printf("Only 320x400 and 320x200 images can be written in 4-plane format.\n");
  166.         exit(1);
  167.     }
  168.  
  169. #ifdef HECKBERT
  170.     CHECK_ALLOC(RGBmap, unsigned char, BYTE_COUNT, "RGB map");
  171.  
  172.     CHECK_ALLOC(Histogram, unsigned long, BYTE_COUNT, "Histogram");
  173.     for (li = 0; li < BYTE_COUNT; li++)        Histogram[li] = 0L;
  174.     open_box_file(output_colours);
  175.  
  176. /* The projected frequency arrays of the largest box are zeroed out as
  177.     as part of open_box_file(). */
  178. #endif
  179.  
  180.     for (i = 0; i < num_files; i++) {
  181.         open_file(input_file, i);
  182.  
  183. #ifdef HECKBERT
  184.         printf("Building Histogram from %s_%d: ...", input_file, i);
  185.         QuantHistogram(get_box(0));
  186.         printf("\b\b\bDone\n");
  187. #else
  188.         printf("Building Octree from %s_%d: ...", input_file, i);
  189.         generateoctree();            /* read the file through */
  190.         printf("\b\b\bDone\n");
  191. #endif
  192.         close_file();
  193.     }
  194.  
  195.     for (i = 0; i < MAXCOLORS; i++)          /* init palette */
  196.         palette[i][0] = palette[i][1] = palette[i][2] = 0;
  197.                                                         /* 0 usually is black ! */
  198.  
  199. #ifdef HECKBERT
  200.     colors = colorquant(output_colours, INPUT_BITS, fast_quant,
  201.                         (double) ((1 << output_bits) - 1) / ((1 << INPUT_BITS) - 1));
  202.  
  203.     close_box_file();
  204. #ifdef __TURBOC__
  205.     free((void far *)Histogram);
  206. #else
  207.     free(Histogram);
  208. #endif
  209. #else
  210.     colors = calc_palette(1,
  211.                         (double) ((1 << output_bits) - 1) / 0xff);
  212.                         /* entry 0 is left black here ! */
  213. #endif
  214.  
  215.     printf("%d %s quantized to %d colors.\n", num_files, num_files == 1 ? "file" : "files", colors);
  216.     write_file(num_files, input_file, image_width, image_height, colors, output_type);
  217. #ifdef HECKBERT
  218. #ifdef __TURBOC__
  219.     free((void far *)RGBmap);
  220. #else
  221.     free(RGBmap);
  222. #endif
  223. #endif
  224. }
  225.  
  226.