home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / sega / pvquant / quant / files.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-21  |  7.7 KB  |  269 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.  *                                                                      *
  15.  ************************************************************************/
  16.  
  17. #include <string.h>
  18. #ifdef __TURBOC__
  19. #include <dos.h>
  20.  
  21. #define SC_INDEX           0x3c4
  22. #define MAP_MASK           2
  23. #endif
  24.  
  25. #include "gif_lib.h"
  26. #include "quant.h"
  27.  
  28. static FILE *out_file;
  29. static FILE *in_file[3];
  30.  
  31. void open_file(char *fname)
  32. {
  33. char filename[256];
  34.  
  35.     sprintf(filename, "%s.red", fname);
  36.     if ((in_file[0] = fopen(filename, "rb")) == NULL) {
  37.         printf("Cannot open %s.\n", filename);
  38.         exit(1);
  39.     }
  40.     sprintf(filename, "%s.grn", fname);
  41.     if ((in_file[1] = fopen(filename, "rb")) == NULL) {
  42.         printf("Cannot open %s.\n", filename);
  43.         exit(1);
  44.     }
  45.     sprintf(filename, "%s.blu", fname);
  46.     if ((in_file[2] = fopen(filename, "rb")) == NULL) {
  47.         printf("Cannot open %s.\n", filename);
  48.         exit(1);
  49.     }
  50. }
  51.  
  52. void close_file(void)
  53. {
  54.     fclose(in_file[0]);
  55.     fclose(in_file[1]);
  56.     fclose(in_file[2]);
  57. }
  58.  
  59. int get_pixel(UCHAR *pixel)
  60. {
  61.     int t;
  62.  
  63. #if INPUT_BITS == 8
  64.     if ((t = getc(in_file[2])) == EOF) return FALSE;
  65.     pixel[BLUE] = t;
  66.     if ((t = getc(in_file[1])) == EOF) return FALSE;
  67.     pixel[GREEN] = t;
  68.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  69.     pixel[RED] = t;
  70. #else
  71. #define MAX_IN  ((0xff << (8 - INPUT_BITS)) & 0xff)
  72. #define ROUND   (1 << (7 - INPUT_BITS))
  73. #define R_SHIFT (8 - INPUT_BITS)
  74.     if ((t = getc(in_file[2])) == EOF) return FALSE;
  75.     pixel[BLUE]  = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  76.     if ((t = getc(in_file[1])) == EOF) return FALSE;
  77.     pixel[GREEN] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  78.     if ((t = getc(in_file[0])) == EOF) return FALSE;
  79.     pixel[RED]   = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
  80. #undef MAX_IN
  81. #undef ROUND
  82. #undef R_SHIFT
  83. #endif
  84.     return TRUE;
  85. }
  86.  
  87. void write_4_planes(char *infname, UINT Xres, UINT Yres)
  88. {
  89.     UINT plane, x, y;
  90.     UCHAR pixel[3];
  91.     char more_data;
  92.     char dummy[3];
  93. #ifdef __TURBOC__
  94.     char far *VGA_addr = MK_FP(0xa000,0);
  95. #endif
  96.  
  97.     open_file(infname);
  98.     for (plane = 0; plane < 4; plane++) {
  99.         more_data = 1;
  100.         fseek(in_file[0], (long)plane, SEEK_SET);
  101.         fseek(in_file[1], (long)plane, SEEK_SET);
  102.         fseek(in_file[2], (long)plane, SEEK_SET);
  103. #ifdef __TURBOC__
  104.         if (disp_image)     outport(SC_INDEX, (0x100 << plane) | MAP_MASK);
  105. #endif
  106.         for (y = 0; y < Yres; y++) {
  107.             for (x = plane; x < Xres; x += 4) {
  108.                 if (more_data) {
  109.                     if (!get_pixel(pixel))
  110.                         pixel[RED] = pixel[GREEN] = pixel[BLUE] = more_data = 0;
  111.                     else {
  112.                         fread(dummy, 3, 1, in_file[0]);   /* Skip to next pixel for this plane */
  113.                         fread(dummy, 3, 1, in_file[1]);
  114.                         fread(dummy, 3, 1, in_file[2]);
  115.                     }
  116.                     putc(pal_index(pixel), out_file);
  117. #ifdef __TURBOC__
  118.                     if (disp_image)        *VGA_addr++ = pal_index(pixel);
  119. #endif
  120.                 } else    putc(pal_index(pixel), out_file);
  121.             }
  122.         }
  123.     }
  124.     close_file();
  125. }
  126.  
  127. static void write_linear(char *infname, UINT Xres, UINT Yres)
  128. {
  129.     UINT x, y;
  130.     UCHAR pixel[3];
  131.     char more_data;
  132. #ifdef __TURBOC__
  133.     char far *VGA_addr = MK_FP(0xa000,0);
  134. #endif
  135.  
  136.     open_file(infname);
  137.     more_data = 1;
  138.     for (y = 0; y < Yres; y++) {
  139.         for (x = 0; x < Xres; x++) {
  140.             if (more_data) {
  141.                 if (!get_pixel(pixel))
  142.                     pixel[RED] = pixel[GREEN] = pixel[BLUE] = more_data = 0;
  143.             }
  144.             putc(pal_index(pixel), out_file);
  145. #ifdef __TURBOC__
  146.             if (disp_image) {
  147.                 outport(SC_INDEX, (0x100 << (x & 3)) | MAP_MASK);
  148.                 VGA_addr[y*(320/4)+x/4] = pal_index(pixel);
  149.             }
  150. #endif
  151.         }
  152.     }
  153.     close_file();
  154. }
  155.  
  156. /****************************************************************************
  157.     Convert Raw image (One byte per pixel) into Gif file. Raw data is read
  158.     from in_file, and Gif is dumped to out_fname. ImageWidth times ImageHeight
  159.     bytes are read. Color map is dumped from ColorMap.
  160. */
  161.  
  162. static void output_gif_file(char *infname, char *out_fname, UINT Xres, UINT Yres, UINT num_colours)
  163. {
  164.     int i, x;
  165.     UCHAR pixel[3];
  166.     char *ScanLine;
  167.  
  168.     open_file(infname);
  169.     for (i = 0; i < 8 && (2 << i) < num_colours; i++);
  170.     num_colours = 2 << i;
  171.     if (num_colours > 256) {
  172.         printf("Colour map must be less than 256 colours.\n");
  173.         exit(3);
  174.     }
  175.  
  176.     if (EGifOpenFileName(out_fname) == -1)     return;
  177.     EGifPutScreenDesc(Xres, Yres, 6, 0, 8, palette);
  178.     EGifPutImageDesc(0, 0, Xres, Yres, 8);
  179.  
  180.     CHECK_ALLOC(ScanLine, UCHAR, Xres, "Scan Line");
  181.  
  182.      /* Here it is - get one raw line from in_file, and dump to Gif: */
  183.     printf("\nImage size is %dx%d:     ", Xres, Yres);
  184.  
  185.     for (i = 0; i < Yres; i++) {
  186.     /* Note we assume here PixelSize == Byte, which is not necessarily   */
  187.     /* so. If not - must read one byte at a time, and coerce to pixel.   */
  188.         for (x = 0; x < Xres; x++) {
  189.             if (!get_pixel(pixel)) {
  190.                 printf("RAW input file ended prematurely.\n");
  191.                 exit(3);
  192.             }
  193.             ScanLine[x] = pal_index(pixel);
  194.         }
  195.  
  196.         if (EGifPutLine(ScanLine, Xres)) break;
  197.         printf("\b\b\b\b%-4d", i);
  198.     }
  199.  
  200.     EGifCloseFile();
  201.     free(ScanLine);
  202.     close_file();
  203. }
  204.  
  205. void output_xd_file(char *infname[], char *out_fname, int colors,
  206.                           int num_files, int Xres, int Yres, int type)
  207. {
  208. int i;
  209.  
  210.     if ((out_file = fopen(out_fname, "wb")) == NULL) {
  211.         printf("Couldn't open %s.\n", out_fname);
  212.         exit(1);
  213.     }
  214.     putc(num_files + '1', out_file);
  215.     putc('D', out_file);
  216.     putw(Xres, out_file);
  217.     putw(Yres, out_file);
  218.     putc(colors, out_file);
  219.     fwrite(palette, 3, colors, out_file);
  220.  
  221.     if (Xres != 320 || Yres != 400) disp_image = FALSE;
  222. #ifdef __TURBOC__
  223.     if (disp_image) {
  224.         set320x400mode();
  225.         setvgapalette(&palette, colors);
  226.     }
  227. #endif
  228.     for (i = 0; i < num_files; i++)
  229.         if (type == 0)     write_4_planes(infname[i], Xres, Yres);
  230.         else              write_linear(infname[i], Xres, Yres);
  231.     fclose(out_file);
  232. #ifdef __TURBOC__
  233.     if (disp_image)        end320x400mode();
  234. #endif
  235. }
  236.  
  237. void output_anim_files(char *infname[], char *out_fname,
  238.                             int colors, int num_files, UINT Xres, UINT Yres, int type)
  239. {
  240.     int i;
  241.     char outname[256];
  242.  
  243.     for (i = 0; i < num_files; i++) {
  244.         sprintf(outname, "%s.%d", out_fname, i);
  245.         printf("Outputting to %s\n", outname);
  246.         output_xd_file(&infname[i], outname, colors, 1, Xres, Yres, type);
  247.     }
  248. }
  249.  
  250. void write_file(int num_files, char *input_file[], int Xres, int Yres,
  251.                      int colors, int output_type)
  252. {
  253. char outfilename[256];
  254.  
  255.     if (num_files > 2)     strcpy(outfilename, input_file[0]);
  256.     else if (output_type == 2)
  257.         sprintf(outfilename, "%s.gif", input_file[0]);
  258.     else
  259.         sprintf(outfilename, "%s.%cd", input_file[0], num_files + '1');
  260.  
  261.     printf("Outputting to %s\n", outfilename);
  262.  
  263.     if (output_type == 2)
  264.         output_gif_file(input_file[0], outfilename, Xres, Yres, colors);
  265.     else if (num_files < 3) {
  266.         output_xd_file(input_file, outfilename, colors, num_files, Xres, Yres, output_type);
  267.     } else output_anim_files(input_file, outfilename, colors, num_files, Xres, Yres, output_type);
  268. }
  269.