home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / MISC / PVQUAN15.ZIP / QUANT.ZIP / FILES.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-06  |  10.0 KB  |  342 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 911030 FvdH - Added 320x200x256x4 pages support              *
  13.  *                     - Fixed bug in output_anim_files                 *
  14.  *    V1.4 920303 FvdH - Ported to GNU C                                *
  15.  *    V1.5 920331 FvdH - Allow Targa input                              *
  16.  *         920403 FvdH - Allow any number of files                      *
  17.  *                                                                      *
  18.  ************************************************************************/
  19.  
  20. #include <string.h>
  21. #ifdef __TURBOC__
  22. #include <dos.h>
  23.  
  24. #define SC_INDEX           0x3c4
  25. #define MAP_MASK           2
  26. #endif
  27.  
  28. #ifdef __GNUC__
  29. #define SEEK_SET 0
  30. #endif
  31.  
  32. #include "gif_lib.h"
  33. #include "quant.h"
  34.  
  35. int (*get_pixel)(UCHAR *pixel);
  36.  
  37. static FILE *out_file;
  38. static FILE *in_file[3];
  39.  
  40. static int get_pixel_raw(UCHAR *pixel)
  41. {
  42.     int t;
  43.  
  44. #if INPUT_BITS == 8
  45.     if ((t = getc(in_file[2])) == EOF) return FALSE;
  46.     pixel[BLUE] = t;
  47.     if ((t = getc(in_file[1])) == EOF) return FALSE;
  48.     pixel[GREEN] = t;
  49.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  50.     pixel[RED] = t;
  51. #else
  52. #define MAX_IN  ((0xff << (8 - INPUT_BITS)) & 0xff)
  53. #define ROUND   (1 << (7 - INPUT_BITS))
  54. #define R_SHIFT (8 - INPUT_BITS)
  55.     if ((t = getc(in_file[2])) == EOF) return FALSE;
  56.     pixel[BLUE]  = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  57.     if ((t = getc(in_file[1])) == EOF) return FALSE;
  58.     pixel[GREEN] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  59.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  60.     pixel[RED]   = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  61. #undef MAX_IN
  62. #undef ROUND
  63. #undef R_SHIFT
  64. #endif
  65.     return TRUE;
  66. }
  67.  
  68.  
  69. static int get_pixel_targa(UCHAR *pixel)
  70. {
  71.     int t;
  72.  
  73. #if INPUT_BITS == 8
  74.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  75.     pixel[BLUE] = t;
  76.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  77.     pixel[GREEN] = t;
  78.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  79.     pixel[RED] = t;
  80. #else
  81. #define MAX_IN  ((0xff << (8 - INPUT_BITS)) & 0xff)
  82. #define ROUND   (1 << (7 - INPUT_BITS))
  83. #define R_SHIFT (8 - INPUT_BITS)
  84.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  85.     pixel[BLUE]  = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  86.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  87.     pixel[GREEN] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  88.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  89.     pixel[RED]   = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  90. #undef MAX_IN
  91. #undef ROUND
  92. #undef R_SHIFT
  93. #endif
  94.     return TRUE;
  95. }
  96.  
  97.  
  98. /* The "+ft" option of PVRAY writes out Targa format.  Specifically, the
  99.     fields are:
  100.  
  101. Header:
  102.    00 00 02 00 00      - Fixed header information for uncompressed type 2 image
  103.    00 00 00
  104.    0000                - Horizontal offset always is at 0000
  105.     llll                - Vertical offset (1st line number, 16 bits, LSB first)
  106.     wwww hhhh           - width, height of image (16 bits each, LSB first)
  107.    18 20               - 24 bits per pixel, Top-down raster
  108.  
  109. For each line:
  110.     bb gg rr bb gg rr ... - blue, green, and red data, 8 bits for each pixel.
  111. */
  112.  
  113. void open_file(char *fname, int num)
  114. {
  115. char filename[256];
  116.  
  117.     if (input_type == 0) {
  118.         sprintf(filename, "%s_%d.red", fname, num);
  119.         if ((in_file[0] = fopen(filename, "rb")) == NULL) {
  120.             printf("Cannot open %s.\n", filename);
  121.             exit(1);
  122.         }
  123.         sprintf(filename, "%s_%d.grn", fname, num);
  124.         if ((in_file[1] = fopen(filename, "rb")) == NULL) {
  125.             printf("Cannot open %s.\n", filename);
  126.             exit(1);
  127.         }
  128.         sprintf(filename, "%s_%d.blu", fname, num);
  129.         if ((in_file[2] = fopen(filename, "rb")) == NULL) {
  130.             printf("Cannot open %s.\n", filename);
  131.             exit(1);
  132.         }
  133.         get_pixel = get_pixel_raw;
  134.         return;
  135.     }
  136.     if (input_type == 1) {
  137.         sprintf(filename, "%s_%d.tga", fname, num);
  138.         if ((in_file[0] = fopen(filename, "rb")) == NULL) {
  139.             printf("Cannot open %s.\n", filename);
  140.             exit(1);
  141.         }
  142.         fseek(in_file[0], 18, SEEK_SET);        /* Skip header */
  143.         get_pixel = get_pixel_targa;
  144.         return;
  145.     }
  146. }
  147.  
  148. void close_file(void)
  149. {
  150.     fclose(in_file[0]);
  151.     if (input_type == 0) {
  152.         fclose(in_file[1]);
  153.         fclose(in_file[2]);
  154.     }
  155. }
  156.  
  157. void write_4_planes(char *infname, int num, UINT Xres, UINT Yres)
  158. {
  159.     UINT plane, x, y;
  160.     UCHAR pixel[3];
  161.     char more_data;
  162.     char dummy[3];
  163. #ifdef __TURBOC__
  164.     char far *VGA_addr = MK_FP(0xa000,0);
  165. #endif
  166.  
  167.     open_file(infname, num);
  168.     for (plane = 0; plane < 4; plane++) {
  169.         more_data = 1;
  170.         fseek(in_file[0], (long)plane, SEEK_SET);
  171.         fseek(in_file[1], (long)plane, SEEK_SET);
  172.         fseek(in_file[2], (long)plane, SEEK_SET);
  173. #ifdef __TURBOC__
  174.         if (disp_image)     outport(SC_INDEX, (0x100 << plane) | MAP_MASK);
  175. #endif
  176.         for (y = 0; y < Yres; y++) {
  177.             for (x = plane; x < Xres; x += 4) {
  178.                 if (more_data) {
  179.                     if (!get_pixel(pixel))
  180.                         pixel[RED] = pixel[GREEN] = pixel[BLUE] = more_data = 0;
  181.                     else {
  182.                         fread(dummy, 3, 1, in_file[0]);   /* Skip to next pixel for this plane */
  183.                         fread(dummy, 3, 1, in_file[1]);
  184.                         fread(dummy, 3, 1, in_file[2]);
  185.                     }
  186.                     putc(pal_index(pixel), out_file);
  187. #ifdef __TURBOC__
  188.                     if (disp_image)        *VGA_addr++ = pal_index(pixel);
  189. #endif
  190.                 } else    putc(pal_index(pixel), out_file);
  191.             }
  192.         }
  193.     }
  194.     close_file();
  195. }
  196.  
  197. static void write_linear(char *infname, int num, UINT Xres, UINT Yres)
  198. {
  199.     UINT x, y;
  200.     UCHAR pixel[3];
  201.     char more_data;
  202. #ifdef __TURBOC__
  203.     char far *VGA_addr = MK_FP(0xa000,0);
  204. #endif
  205.  
  206.     open_file(infname, num);
  207.     more_data = 1;
  208.     for (y = 0; y < Yres; y++) {
  209.         for (x = 0; x < Xres; x++) {
  210.             if (more_data) {
  211.                 if (!get_pixel(pixel))
  212.                     pixel[RED] = pixel[GREEN] = pixel[BLUE] = more_data = 0;
  213.             }
  214.             putc(pal_index(pixel), out_file);
  215. #ifdef __TURBOC__
  216.             if (disp_image) {
  217.                 outport(SC_INDEX, (0x100 << (x & 3)) | MAP_MASK);
  218.                 VGA_addr[y*(320/4)+x/4] = pal_index(pixel);
  219.             }
  220. #endif
  221.         }
  222.     }
  223.     close_file();
  224. }
  225.  
  226. /****************************************************************************
  227.     Convert Raw image (One byte per pixel) into Gif file. Raw data is read
  228.     from in_file, and Gif is dumped to out_fname. ImageWidth times ImageHeight
  229.     bytes are read. Color map is dumped from ColorMap.
  230. */
  231.  
  232. static void output_gif_file(char *infname, int num, char *out_fname, UINT Xres, UINT Yres, UINT num_colours)
  233. {
  234.     int i, x;
  235.     UCHAR pixel[3];
  236.     UCHAR *ScanLine;
  237.  
  238.     open_file(infname, num);
  239.     for (i = 0; i < 8 && (2 << i) < num_colours; i++);
  240.     num_colours = 2 << i;
  241.     if (num_colours > 256) {
  242.         printf("Colour map must be less than 256 colours.\n");
  243.         exit(3);
  244.     }
  245.  
  246.     if (EGifOpenFileName(out_fname) == -1)     return;
  247.     EGifPutScreenDesc(Xres, Yres, 6, 0, 8, palette);
  248.     EGifPutImageDesc(0, 0, Xres, Yres, 8);
  249.  
  250.      CHECK_ALLOC(ScanLine, UCHAR, Xres, "Scan Line");
  251.  
  252.      /* Here it is - get one raw line from in_file, and dump to Gif: */
  253.     printf("\nImage size is %dx%d:     ", Xres, Yres);
  254.  
  255.     for (i = 0; i < Yres; i++) {
  256.     /* Note we assume here PixelSize == Byte, which is not necessarily   */
  257.     /* so. If not - must read one byte at a time, and coerce to pixel.   */
  258.         for (x = 0; x < Xres; x++) {
  259.             if (!get_pixel(pixel)) {
  260.                 printf("RAW input file ended prematurely.\n");
  261.                 exit(3);
  262.             }
  263.             ScanLine[x] = pal_index(pixel);
  264.         }
  265.  
  266.         if (EGifPutLine(ScanLine, Xres)) break;
  267.         printf("\b\b\b\b%-4d", i);
  268.     }
  269.  
  270.     EGifCloseFile();
  271.     free(ScanLine);
  272.     close_file();
  273. }
  274.  
  275. void output_xd_file(char *infname, int num, char *out_fname, int colors,
  276.                           int num_files, int Xres, int Yres, int type)
  277. {
  278. int i;
  279.  
  280.     if ((out_file = fopen(out_fname, "wb")) == NULL) {
  281.         printf("Couldn't open %s.\n", out_fname);
  282.         exit(1);
  283.     }
  284.     putc(num_files + '1', out_file);
  285.     putc('D', out_file);
  286.     putw(Xres, out_file);
  287.     putw(Yres, out_file);
  288.     putc(colors, out_file);
  289.     fwrite(palette, 3, colors, out_file);
  290.  
  291. #ifdef __TURBOC__
  292.     if ((Xres != 320) || ((Yres != 200) && (Yres != 400))) disp_image = FALSE;
  293.     if (disp_image) {
  294.         if (Yres == 200)             set320x200x4mode();
  295.         else if (Yres == 400)     set320x400mode();
  296.         setvgapalette(&palette, colors);
  297.     }
  298. #endif
  299.     for (i = 0; i < num_files; i++)
  300.         if (type == 0)     write_4_planes(infname, num + i, Xres, Yres);
  301.         else              write_linear(infname, num + i, Xres, Yres);
  302.     fclose(out_file);
  303. #ifdef __TURBOC__
  304.     if (disp_image)
  305.         if (Yres == 200)        end320x200mode();
  306.         else                        end320x400mode();
  307. #endif
  308. }
  309.  
  310. void output_anim_files(char *infname, char *out_fname,
  311.                             int colors, int num_files, UINT Xres, UINT Yres, int type)
  312. {
  313.     int i;
  314.     char outname[256];
  315.  
  316.     for (i = 0; i < num_files; i++) {
  317.         sprintf(outname, "%s.%d", out_fname, i);
  318.         printf("Outputting to %s\n", outname);
  319.         output_xd_file(infname, i, outname, colors, 1, Xres, Yres, type);
  320.     }
  321. }
  322.  
  323. void write_file(int num_files, char *input_file, int Xres, int Yres,
  324.                      int colors, int output_type)
  325. {
  326. char outfilename[256];
  327.  
  328.     if (num_files > 2)     strcpy(outfilename, input_file);
  329.     else if (output_type == 2)
  330.         sprintf(outfilename, "%s.gif", input_file);
  331.     else
  332.         sprintf(outfilename, "%s.%cd", input_file, num_files + '1');
  333.  
  334.     printf("Outputting to %s\n", outfilename);
  335.  
  336.     if (output_type == 2)
  337.         output_gif_file(input_file, 0, outfilename, Xres, Yres, colors);
  338.     else if (num_files < 3) {
  339.         output_xd_file(input_file, 0, outfilename, colors, num_files, Xres, Yres, output_type);
  340.     } else output_anim_files(input_file, outfilename, colors, num_files, Xres, Yres, output_type);
  341. }
  342.