home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / MISC / PVQUAN15.ZIP / ANIM.ZIP / ANIMGIF.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-01  |  8.0 KB  |  288 lines

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