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