home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / sega / pvquant / anim / animgif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-28  |  6.5 KB  |  263 lines

  1. /*
  2.   This program calculates the location of the first and last differences
  3.   between two graphic images. The start and length of the difference region
  4.   is written to a file, along with the difference region. This file can then
  5.   be read by ANIM to produce animation */
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #ifdef __TURBOC__
  11. #include <alloc.h>
  12. #include <mem.h>
  13. #endif
  14.  
  15. #define FALSE     0
  16. #define TRUE    1
  17.  
  18. #define UCHAR unsigned char
  19. #define UINT  unsigned int
  20.  
  21. #ifdef __TURBOC__
  22. #define CHECK_ALLOC( ptr, type, number, msg) {\
  23.     if ((ptr = (type *) farmalloc((long)sizeof(type) * (unsigned long)(number))) == NULL) {\
  24.         printf("\nCreating %s: MALLOC - out of memory\n", msg);\
  25.         exit(1);\
  26.      } \
  27.   }
  28. #else
  29. #define CHECK_ALLOC(ptr, type, number, msg) { \
  30.     if ((ptr = (type *) malloc(sizeof(type) * number)) == NULL) { \
  31.         printf("\nCreating %s: malloc - out of memory\n, msg"); \
  32.         exit(1); \
  33.     } \
  34. }
  35.  
  36. #define putw(word, file) {\
  37.     putc((word) & 0xff, file);\
  38.     putc((word) >> 8, file);\
  39.     }
  40.  
  41. int getw(FILE *fp)
  42. {
  43.     int temp;
  44.     temp = getc(fp);
  45.     temp = getc(fp) * 0x100 + temp;
  46.     return temp;
  47. }
  48. #endif
  49.  
  50. #include "gif_lib.h"
  51.  
  52. extern FILE *GIF_file;
  53.  
  54. char palette[256][3];
  55. int colours;
  56.  
  57. /****************************************************************************
  58.     Convert Raw image (One byte per pixel) into Gif file. Raw data is read
  59.     from in_file, and Gif is dumped to out_fname. ImageWidth times ImageHeight
  60.     bytes are read. Color map is dumped from ColorMap.
  61. */
  62.  
  63. static void create_gif_header(char *out_fname, char *in_name)
  64. {
  65.     int i;
  66.     UINT Xres, Yres, num_colours;
  67.     FILE *in;
  68.  
  69.     if ((in = fopen(in_name, "rb")) == NULL) {
  70.         printf( "Error opening %s.\n", in_name);
  71.         exit(1);
  72.     }
  73.     if (getc(in) != '2') {
  74.         printf( "Incorrect signature on file.\n");
  75.         exit(1);
  76.     }
  77.     if (getc(in) != 'D') {        /* Check signature for 320x400 format */
  78.         printf( "Incorrect signature on file.\n");
  79.         exit(1);
  80.     }
  81.     Xres = getw(in);         /* store columns */
  82.     Yres = getw(in);        /* store rows */
  83.     if (Xres != 320 || Yres != 200) {
  84.         printf( "Invalid image size -- must be 320*200, but is %d*%d.\n", Xres, Yres);
  85.         exit(1);
  86.     }
  87.  
  88.     num_colours = getc(in);
  89.     if (num_colours == 0) num_colours = 256;
  90.     fread(palette, 3, num_colours, in);
  91.  
  92.     for (i = 0; i < 8 && (2 << i) < num_colours; i++);
  93.     num_colours = 2 << i;
  94.     if (num_colours > 256) {
  95.         printf("Colour map must be less than 256 colours.\n");
  96.         exit(3);
  97.     }
  98.     fclose(in);
  99.  
  100.     if (EGifOpenFileName(out_fname) == -1)     return;
  101.     EGifPutScreenDesc(Xres/4, Yres*4, 6, 0, 8, palette);
  102.     printf("\nImage size is %dx%d\n", Xres, Yres);
  103. }
  104.  
  105. static int write_gif_image(char *in_name, UINT Xres, UINT top, UINT bottom)
  106. {
  107.     UINT i, plane;
  108.     char *ScanLine;
  109.     FILE *fp;
  110.     UINT maxcol, maxrow;
  111.     UINT Yres = 200;
  112.  
  113.     if ((fp = fopen(in_name, "rb")) == NULL) return FALSE;
  114.  
  115.     if (getc(fp) != '2') {
  116.         printf( "\nIncorrect signature on file.\n");
  117.         exit(1);
  118.     }
  119.     if (getc(fp) != 'D') {        /* Check signature for 320x200 format */
  120.         printf( "\nIncorrect signature on file.\n");
  121.         exit(1);
  122.     }
  123.  
  124.     maxcol = getw(fp);         /* store columns */
  125.     maxrow = getw(fp);        /* store rows */
  126.     if (maxcol != 320 || maxrow != 200) {
  127.         printf( "\nInvalid image size -- must be 320*200, but is %d*%d.\n",
  128.                         maxcol, maxrow);
  129.         exit(1);
  130.     }
  131.     colours = getc(fp);
  132.     if (colours == 0) colours = 256;
  133.     fread(palette, 3, colours, fp);
  134.  
  135.     EGifPutImageDesc(0, top, Xres, (bottom - top + 1)*4, 8);
  136.     CHECK_ALLOC(ScanLine, UCHAR, Xres, "Scan Line");
  137.  
  138.      /* Here it is - get one raw line from in_file, and dump to Gif: */
  139.     for (plane = 0; plane < 4; plane++) {
  140.         printf(".");
  141.         fseek(fp, top * Xres, SEEK_CUR);        /* Skip first common bit */
  142.         for (i = top; i <= bottom; i++) {
  143.             fread(ScanLine, 1, Xres, fp);
  144.             if (EGifPutLine(ScanLine, Xres)) break;
  145.         }
  146.         fseek(fp, (Yres - bottom - 1) * Xres, SEEK_CUR);    /* Skip end common bit */
  147.     }
  148.     printf("\n");
  149.     fclose(fp);
  150.     free(ScanLine);
  151.     return TRUE;
  152. }
  153.  
  154. int convert(char *in_name1, char *in_name2)
  155. {
  156.     UINT i, plane, maxcol, maxrow;
  157.     FILE *fp;
  158.     char *image[2][4];
  159.     UINT block_size, min, max;
  160.     char *in_name[2];
  161.  
  162.     in_name[0] = in_name1;
  163.     in_name[1] = in_name2;
  164.  
  165.     printf("Converting %s & %s\t", in_name1, in_name2);
  166.     for (i = 0; i < 2; i++) {
  167.         if ((fp = fopen(in_name[i], "rb")) == NULL) return FALSE;
  168.  
  169.         if (getc(fp) != '2') {
  170.             printf( "\nIncorrect signature on file.\n");
  171.             exit(1);
  172.         }
  173.         if (getc(fp) != 'D') {        /* Check signature for 320x400 format */
  174.             printf( "\nIncorrect signature on file.\n");
  175.             exit(1);
  176.         }
  177.  
  178.         maxcol = getw(fp);         /* store columns */
  179.         maxrow = getw(fp);        /* store rows */
  180.         if (maxcol != 320 || maxrow != 200) {
  181.             printf( "\nInvalid image size -- must be 320*200, but is %d*%d.\n", maxcol, maxrow);
  182.             exit(1);
  183.         }
  184.         block_size = maxcol * maxrow / 4;
  185.         colours = getc(fp);
  186.         if (colours == 0) colours = 256;
  187.         fread(palette, 3, colours, fp);
  188.         for (plane = 0; plane < 4; plane++) {
  189.             CHECK_ALLOC(image[i][plane], char, block_size, "Image buffer");
  190.             fread(image[i][plane], 1, block_size, fp);
  191.         }
  192.         fclose(fp);
  193.     }
  194.  
  195.     min = block_size;
  196.     for (plane = 0; plane < 4; plane++) {
  197.         for (i = 0 ; i < min; i++) {
  198.             if (image[0][plane][i] != image[1][plane][i]) {
  199.                 min = i;
  200.                 break;
  201.             }
  202.         }
  203.     }
  204.  
  205.     if (min == block_size) printf("Images are the same\n");
  206.     else {
  207.         max = min;
  208.         for (plane = 0; plane < 4; plane++) {
  209.             for (i = block_size - 1; i > max; i--) {
  210.                 if (image[0][plane][i] != image[1][plane][i]) {
  211.                     max = i;
  212.                     break;
  213.                 }
  214.             }
  215.         }
  216.  
  217.         min /= 80;
  218.         max = (max+79)/80;
  219.         printf("Lines %d:%d", min, max);
  220.  
  221.         write_gif_image(in_name2, 80, min, max);
  222.     }
  223.  
  224.     for (plane = 0; plane < 4; plane++) {
  225.         free(image[0][plane]);
  226.         free(image[1][plane]);
  227.     }
  228.  
  229.     return TRUE;
  230. }
  231.  
  232. void cdecl main(int argc, char *argv[])
  233. {
  234.     char in_fname1[256], in_fname2[256], out_fname[256];
  235.     int file_no;
  236.  
  237.     printf("ANIMGIF v1.00 -- Create a GIF file containing an animation sequence.\n");
  238.     printf("By F van der Hulst. Copyright 1991\n\n");
  239.     if (argc != 3) {
  240.         printf("Two filenames must be specified\n");
  241.         exit(1);
  242.     }
  243.  
  244.     sprintf(in_fname1, "%s.0", argv[1]);
  245.     sprintf(out_fname, "%s.gif", argv[2]);
  246.     create_gif_header(out_fname, in_fname1);
  247.     printf("Outputting %s", in_fname1);
  248.     write_gif_image(in_fname1, 80, 0, 199);
  249.  
  250.     sprintf(in_fname2, "%s.1", argv[1]);
  251.     convert(in_fname1, in_fname2);
  252.  
  253.     sprintf(in_fname2, "%s.2", argv[1]);
  254.  
  255.     file_no = 3;
  256.     while (convert(in_fname1, in_fname2)) {
  257.         sprintf(in_fname1, "%s.%d", argv[1], file_no - 2);
  258.         sprintf(in_fname2, "%s.%d", argv[1], file_no);
  259.         file_no++;
  260.     }
  261.     EGifCloseFile();
  262. }
  263.