home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- * *
- * Copyright (c) 1991, Frank van der Hulst *
- * All Rights Reserved *
- * *
- * Authors: *
- * FvdH - Frank van der Hulst (Wellington, NZ) *
- * *
- * Versions: *
- * V1.1 910626 FvdH - QUANT released for DBW_RENDER *
- * V1.2 911021 FvdH - QUANT released for PoV Ray *
- * V1.3 911031 FvdH - Added 320x200x256x4 pages support *
- * *
- ************************************************************************/
- /*
- * quant.c
- *
- * Program to do colour quantization. This program reads PoV Ray raw
- * format files and quantizes the image(s) to produce a file in one of
- * 3 formats -- 2D, 3D or GIF. It can use either Heckbert's median-splitting
- * algorithm, or else the Octree Quantisation algorithm by Michael Gervautz
- * and Werner Purgathofer.
- *
- * This program compiles using Turbo-C v2.01 and runs on an MS-DOS machine,
- * or using cc on a SCO Unix system.
- */
-
- #include <string.h>
- #ifdef __TURBOC__
- #include <ctype.h>
- #endif
-
- #include "quant.h"
-
- #ifdef HECKBERT
- #include "heckbert.h"
- #else
- #include "octree.h"
- #endif
-
- unsigned long HUGE_PTR Histogram; /* image histogram */
- unsigned char HUGE_PTR RGBmap; /* RGB -> index map */
-
- unsigned int ColormaxI; /* # of colors, 2^input_bits */
- UCHAR palette[MAXCOLORS][3];
-
- char disp_image = 1; /* Display image while quantising */
-
- static int output_bits = 6; /* No. of sig. bits on output (must be <= 8) */
- #ifdef HECKBERT
- static int fast_quant = 1; /* Quantisation speed switch */
- /* If zero, the rgbmap will be built very slowly, but more accurately. The
- error introduced by the approximation is usually small.
-
- If one, the rgbmap will be constructed quickly. */
- #endif
-
- static int image_width = 320; /* Width of image in pixels */
- static int image_height = 200; /* Height of image in pixels */
- static int output_colours = 256; /* No. of separate colours to produce ( <= 256) */
- static int output_type = 1; /* Output format switch */
-
- #define MAX_FILES 50
- static char* input_file[MAX_FILES];
- int num_files = 0;
-
- /********************************************************************
- Process command line arguments. */
-
- void get_args(int argc, char *argv[])
- {
- int i;
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] != '/' && argv[i][0] != '-') {
- if (num_files == MAX_FILES) {
- printf("Can only process %d files at a time.\n", MAX_FILES);
- exit(1);
- }
- input_file[num_files++] = argv[i];
- continue;
- }
- if (argv[i][1] == '?') {
- printf("Command syntax: %s [/O=outputbits][/C=colours][/S=speed][/T=type]\n");
- printf(" [/D=display][/W=width][/H=height]file1 [file2]...\n\n", argv[0]);
- printf("outputbits = bits per colour being output [6]\n");
- #ifdef HECKBERT
- printf("speed = 0 or 1 [%d]\n", fast_quant);
- #endif
- printf("type = 0 for 4-plane, 1 for planar,2 for GIF [%d]\n", output_type);
- printf("display = 1 or 0 for displaying during output [%d]\n", disp_image);
- printf("colours = number of separate colours to produce [%d]\n", output_colours);
- printf("width = width of image in pixels [%d]\n", image_width);
- printf("height = height of image in pixels [%d]\n", image_height);
- printf("file1, file2 = name of file to read, without extension\n");
- exit(0);
- }
- if (argv[i][2] != '=') {
- printf("Invalid command line switch: %s\n(Must be /%c=VALUE)\n", &argv[i][1]);
- exit(1);
- }
- switch(toupper(argv[i][1])) {
- case 'O': output_bits = atoi(&argv[i][3]); break;
- #ifdef HECKBERT
- case 'S': fast_quant = atoi(&argv[i][3]); break;
- #endif
- case 'T': output_type = atoi(&argv[i][3]); break;
- case 'D': disp_image = atoi(&argv[i][3]); break;
- case 'C': output_colours = atoi(&argv[i][3]); break;
- case 'W': image_width = atoi(&argv[i][3]); break;
- case 'H': image_height = atoi(&argv[i][3]); break;
- default:
- printf("Invalid command line switch: %s\n(Must be /C, /D, /T, /O, or /S)\n", argv[i]);
- exit(1);
- }
- }
- if (num_files == 0) {
- printf("No files to process.\n");
- exit(0);
- }
- }
-
- void cdecl main(int argc, char *argv[])
- {
- int colors, i;
- #ifdef HECKBERT
- long int li;
- #else
- #endif
-
- printf("QUANT v1.30 -- Colour quantisation for PVRay\n");
- #ifdef HECKBERT
- printf("By F van der Hulst, based on COLORQUANT by Craig E. Kolb.\n\n");
- #else
- printf("By F van der Hulst, based on Octree Quantisation by Wolfgang Stuerzlinger.\n\n");
- #endif
-
- get_args(argc, argv);
- if (output_type == 2)
- if (num_files != 1) {
- printf("Can only convert one file to GIF format.\n");
- exit(1);
- }
- if ((output_type == 0) &&
- ((image_width != 320) ||
- ((image_height != 400) && (image_height != 200)))) {
- printf("Only 320x400 and 320x200 images can be written in 4-plane format.\n");
- exit(1);
- }
-
- #ifdef HECKBERT
- CHECK_ALLOC(RGBmap, unsigned char, BYTE_COUNT, "RGB map");
-
- CHECK_ALLOC(Histogram, unsigned long, BYTE_COUNT, "Histogram");
- for (li = 0; li < BYTE_COUNT; li++) Histogram[li] = 0L;
- open_box_file(output_colours);
-
- /* The projected frequency arrays of the largest box are zeroed out as
- as part of open_box_file(). */
- #endif
-
- for (i = 0; i < num_files; i++) {
- open_file(input_file[i]);
-
- #ifdef HECKBERT
- printf("Building Histogram from %s: ...", input_file[i]);
- QuantHistogram(get_box(0));
- printf("\b\b\bDone\n");
- #else
- printf("Building Octree from %s: ...", input_file[i]);
- generateoctree(); /* read the file through */
- printf("\b\b\bDone\n");
- #endif
- close_file();
- }
-
- for (i = 0; i < MAXCOLORS; i++) /* init palette */
- palette[i][0] = palette[i][1] = palette[i][2] = 0;
- /* 0 usually is black ! */
-
- #ifdef HECKBERT
- colors = colorquant(output_colours, INPUT_BITS, fast_quant,
- (double) ((1 << output_bits) - 1) / ((1 << INPUT_BITS) - 1));
-
- close_box_file();
- #ifdef __TURBOC__
- free((void far *)Histogram);
- #else
- free(Histogram);
- #endif
- #else
- colors = calc_palette(1,
- (double) ((1 << output_bits) - 1) / 0xff);
- /* entry 0 is left black here ! */
- #endif
-
- printf("%d %s quantized to %d colors.\n", num_files, num_files == 1 ? "file" : "files", colors);
- write_file(num_files, input_file, image_width, image_height, colors, output_type);
- #ifdef HECKBERT
- #ifdef __TURBOC__
- free((void far *)RGBmap);
- #else
- free(RGBmap);
- #endif
- #endif
- }