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 911030 FvdH - Added 320x200x256x4 pages support *
- * - Fixed bug in output_anim_files *
- * V1.4 920303 FvdH - Ported to GNU C *
- * V1.5 920331 FvdH - Allow Targa input *
- * 920403 FvdH - Allow any number of files *
- * *
- ************************************************************************/
-
- #include <string.h>
- #ifdef __TURBOC__
- #include <dos.h>
-
- #define SC_INDEX 0x3c4
- #define MAP_MASK 2
- #endif
-
- #ifdef __GNUC__
- #define SEEK_SET 0
- #endif
-
- #include "gif_lib.h"
- #include "quant.h"
-
- int (*get_pixel)(UCHAR *pixel);
-
- static FILE *out_file;
- static FILE *in_file[3];
-
- static int get_pixel_raw(UCHAR *pixel)
- {
- int t;
-
- #if INPUT_BITS == 8
- if ((t = getc(in_file[2])) == EOF) return FALSE;
- pixel[BLUE] = t;
- if ((t = getc(in_file[1])) == EOF) return FALSE;
- pixel[GREEN] = t;
- if ((t = getc(in_file[0])) == EOF) return FALSE;
- pixel[RED] = t;
- #else
- #define MAX_IN ((0xff << (8 - INPUT_BITS)) & 0xff)
- #define ROUND (1 << (7 - INPUT_BITS))
- #define R_SHIFT (8 - INPUT_BITS)
- if ((t = getc(in_file[2])) == EOF) return FALSE;
- pixel[BLUE] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
- if ((t = getc(in_file[1])) == EOF) return FALSE;
- pixel[GREEN] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
- if ((t = getc(in_file[0])) == EOF) return FALSE;
- pixel[RED] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
- #undef MAX_IN
- #undef ROUND
- #undef R_SHIFT
- #endif
- return TRUE;
- }
-
-
- static int get_pixel_targa(UCHAR *pixel)
- {
- int t;
-
- #if INPUT_BITS == 8
- if ((t = getc(in_file[0])) == EOF) return FALSE;
- pixel[BLUE] = t;
- if ((t = getc(in_file[0])) == EOF) return FALSE;
- pixel[GREEN] = t;
- if ((t = getc(in_file[0])) == EOF) return FALSE;
- pixel[RED] = t;
- #else
- #define MAX_IN ((0xff << (8 - INPUT_BITS)) & 0xff)
- #define ROUND (1 << (7 - INPUT_BITS))
- #define R_SHIFT (8 - INPUT_BITS)
- if ((t = getc(in_file[0])) == EOF) return FALSE;
- pixel[BLUE] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
- if ((t = getc(in_file[0])) == EOF) return FALSE;
- pixel[GREEN] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
- if ((t = getc(in_file[0])) == EOF) return FALSE;
- pixel[RED] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
- #undef MAX_IN
- #undef ROUND
- #undef R_SHIFT
- #endif
- return TRUE;
- }
-
-
- /* The "+ft" option of PVRAY writes out Targa format. Specifically, the
- fields are:
-
- Header:
- 00 00 02 00 00 - Fixed header information for uncompressed type 2 image
- 00 00 00
- 0000 - Horizontal offset always is at 0000
- llll - Vertical offset (1st line number, 16 bits, LSB first)
- wwww hhhh - width, height of image (16 bits each, LSB first)
- 18 20 - 24 bits per pixel, Top-down raster
-
- For each line:
- bb gg rr bb gg rr ... - blue, green, and red data, 8 bits for each pixel.
- */
-
- void open_file(char *fname, int num)
- {
- char filename[256];
-
- if (input_type == 0) {
- sprintf(filename, "%s_%d.red", fname, num);
- if ((in_file[0] = fopen(filename, "rb")) == NULL) {
- printf("Cannot open %s.\n", filename);
- exit(1);
- }
- sprintf(filename, "%s_%d.grn", fname, num);
- if ((in_file[1] = fopen(filename, "rb")) == NULL) {
- printf("Cannot open %s.\n", filename);
- exit(1);
- }
- sprintf(filename, "%s_%d.blu", fname, num);
- if ((in_file[2] = fopen(filename, "rb")) == NULL) {
- printf("Cannot open %s.\n", filename);
- exit(1);
- }
- get_pixel = get_pixel_raw;
- return;
- }
- if (input_type == 1) {
- sprintf(filename, "%s_%d.tga", fname, num);
- if ((in_file[0] = fopen(filename, "rb")) == NULL) {
- printf("Cannot open %s.\n", filename);
- exit(1);
- }
- fseek(in_file[0], 18, SEEK_SET); /* Skip header */
- get_pixel = get_pixel_targa;
- return;
- }
- }
-
- void close_file(void)
- {
- fclose(in_file[0]);
- if (input_type == 0) {
- fclose(in_file[1]);
- fclose(in_file[2]);
- }
- }
-
- void write_4_planes(char *infname, int num, UINT Xres, UINT Yres)
- {
- UINT plane, x, y;
- UCHAR pixel[3];
- char more_data;
- char dummy[3];
- #ifdef __TURBOC__
- char far *VGA_addr = MK_FP(0xa000,0);
- #endif
-
- open_file(infname, num);
- for (plane = 0; plane < 4; plane++) {
- more_data = 1;
- fseek(in_file[0], (long)plane, SEEK_SET);
- fseek(in_file[1], (long)plane, SEEK_SET);
- fseek(in_file[2], (long)plane, SEEK_SET);
- #ifdef __TURBOC__
- if (disp_image) outport(SC_INDEX, (0x100 << plane) | MAP_MASK);
- #endif
- for (y = 0; y < Yres; y++) {
- for (x = plane; x < Xres; x += 4) {
- if (more_data) {
- if (!get_pixel(pixel))
- pixel[RED] = pixel[GREEN] = pixel[BLUE] = more_data = 0;
- else {
- fread(dummy, 3, 1, in_file[0]); /* Skip to next pixel for this plane */
- fread(dummy, 3, 1, in_file[1]);
- fread(dummy, 3, 1, in_file[2]);
- }
- putc(pal_index(pixel), out_file);
- #ifdef __TURBOC__
- if (disp_image) *VGA_addr++ = pal_index(pixel);
- #endif
- } else putc(pal_index(pixel), out_file);
- }
- }
- }
- close_file();
- }
-
- static void write_linear(char *infname, int num, UINT Xres, UINT Yres)
- {
- UINT x, y;
- UCHAR pixel[3];
- char more_data;
- #ifdef __TURBOC__
- char far *VGA_addr = MK_FP(0xa000,0);
- #endif
-
- open_file(infname, num);
- more_data = 1;
- for (y = 0; y < Yres; y++) {
- for (x = 0; x < Xres; x++) {
- if (more_data) {
- if (!get_pixel(pixel))
- pixel[RED] = pixel[GREEN] = pixel[BLUE] = more_data = 0;
- }
- putc(pal_index(pixel), out_file);
- #ifdef __TURBOC__
- if (disp_image) {
- outport(SC_INDEX, (0x100 << (x & 3)) | MAP_MASK);
- VGA_addr[y*(320/4)+x/4] = pal_index(pixel);
- }
- #endif
- }
- }
- close_file();
- }
-
- /****************************************************************************
- Convert Raw image (One byte per pixel) into Gif file. Raw data is read
- from in_file, and Gif is dumped to out_fname. ImageWidth times ImageHeight
- bytes are read. Color map is dumped from ColorMap.
- */
-
- static void output_gif_file(char *infname, int num, char *out_fname, UINT Xres, UINT Yres, UINT num_colours)
- {
- int i, x;
- UCHAR pixel[3];
- UCHAR *ScanLine;
-
- open_file(infname, num);
- for (i = 0; i < 8 && (2 << i) < num_colours; i++);
- num_colours = 2 << i;
- if (num_colours > 256) {
- printf("Colour map must be less than 256 colours.\n");
- exit(3);
- }
-
- if (EGifOpenFileName(out_fname) == -1) return;
- EGifPutScreenDesc(Xres, Yres, 6, 0, 8, palette);
- EGifPutImageDesc(0, 0, Xres, Yres, 8);
-
- CHECK_ALLOC(ScanLine, UCHAR, Xres, "Scan Line");
-
- /* Here it is - get one raw line from in_file, and dump to Gif: */
- printf("\nImage size is %dx%d: ", Xres, Yres);
-
- for (i = 0; i < Yres; i++) {
- /* Note we assume here PixelSize == Byte, which is not necessarily */
- /* so. If not - must read one byte at a time, and coerce to pixel. */
- for (x = 0; x < Xres; x++) {
- if (!get_pixel(pixel)) {
- printf("RAW input file ended prematurely.\n");
- exit(3);
- }
- ScanLine[x] = pal_index(pixel);
- }
-
- if (EGifPutLine(ScanLine, Xres)) break;
- printf("\b\b\b\b%-4d", i);
- }
-
- EGifCloseFile();
- free(ScanLine);
- close_file();
- }
-
- void output_xd_file(char *infname, int num, char *out_fname, int colors,
- int num_files, int Xres, int Yres, int type)
- {
- int i;
-
- if ((out_file = fopen(out_fname, "wb")) == NULL) {
- printf("Couldn't open %s.\n", out_fname);
- exit(1);
- }
- putc(num_files + '1', out_file);
- putc('D', out_file);
- putw(Xres, out_file);
- putw(Yres, out_file);
- putc(colors, out_file);
- fwrite(palette, 3, colors, out_file);
-
- #ifdef __TURBOC__
- if ((Xres != 320) || ((Yres != 200) && (Yres != 400))) disp_image = FALSE;
- if (disp_image) {
- if (Yres == 200) set320x200x4mode();
- else if (Yres == 400) set320x400mode();
- setvgapalette(&palette, colors);
- }
- #endif
- for (i = 0; i < num_files; i++)
- if (type == 0) write_4_planes(infname, num + i, Xres, Yres);
- else write_linear(infname, num + i, Xres, Yres);
- fclose(out_file);
- #ifdef __TURBOC__
- if (disp_image)
- if (Yres == 200) end320x200mode();
- else end320x400mode();
- #endif
- }
-
- void output_anim_files(char *infname, char *out_fname,
- int colors, int num_files, UINT Xres, UINT Yres, int type)
- {
- int i;
- char outname[256];
-
- for (i = 0; i < num_files; i++) {
- sprintf(outname, "%s.%d", out_fname, i);
- printf("Outputting to %s\n", outname);
- output_xd_file(infname, i, outname, colors, 1, Xres, Yres, type);
- }
- }
-
- void write_file(int num_files, char *input_file, int Xres, int Yres,
- int colors, int output_type)
- {
- char outfilename[256];
-
- if (num_files > 2) strcpy(outfilename, input_file);
- else if (output_type == 2)
- sprintf(outfilename, "%s.gif", input_file);
- else
- sprintf(outfilename, "%s.%cd", input_file, num_files + '1');
-
- printf("Outputting to %s\n", outfilename);
-
- if (output_type == 2)
- output_gif_file(input_file, 0, outfilename, Xres, Yres, colors);
- else if (num_files < 3) {
- output_xd_file(input_file, 0, outfilename, colors, num_files, Xres, Yres, output_type);
- } else output_anim_files(input_file, outfilename, colors, num_files, Xres, Yres, output_type);
- }