home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- * *
- * Copyright (c) 1992, Frank van der Hulst *
- * All Rights Reserved *
- * *
- ************************************************************************
- * *
- * Authors: *
- * FvdH - Frank van der Hulst (Wellington, NZ) *
- * *
- * Versions: *
- * V1.0 911031 FvdH - Released as part of PVQUAN13.ZIP *
- * V1.4 920306 FvdH - Ported to GNU C (PVQUAN14.ZIP) *
- * - Fixed bug in frame size calculation *
- * *
- ************************************************************************/
-
- /*
- This program calculates the location of the first and last differences
- between two graphic images. The start and length of the difference region
- is written to a file, along with the difference region. This file can then
- be read by ANIM to produce animation */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #ifdef __TURBOC__
- #include <alloc.h>
- #include <mem.h>
- #endif
-
- #ifdef __GNUC__
- #define SEEK_CUR 1
- #endif
-
- #define FALSE 0
- #define TRUE 1
-
- #define UCHAR unsigned char
- #define UINT unsigned int
-
- #ifdef __TURBOC__
- #define CHECK_ALLOC( ptr, type, number, msg) {\
- if ((ptr = (type *) farmalloc((long)sizeof(type) * (unsigned long)(number))) == NULL) {\
- printf("\nCreating %s: MALLOC - out of memory\n", msg);\
- exit(1);\
- } \
- }
- #else
- #define CHECK_ALLOC(ptr, type, number, msg) { \
- if ((ptr = (type *) malloc(sizeof(type) * number)) == NULL) { \
- printf("\nCreating %s: malloc - out of memory\n, msg"); \
- exit(1); \
- } \
- }
-
- #define putw(word, file) {\
- putc((word) & 0xff, file);\
- putc((word) >> 8, file);\
- }
-
- int getw(FILE *fp)
- {
- int temp;
- temp = getc(fp);
- temp = getc(fp) * 0x100 + temp;
- return temp;
- }
- #endif
-
- #include "gif_lib.h"
-
- extern FILE *GIF_file;
-
- unsigned char palette[256][3];
- int colours;
-
- /****************************************************************************
- 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 create_gif_header(char *out_fname, char *in_name)
- {
- int i;
- UINT Xres, Yres, num_colours;
- FILE *in;
-
- if ((in = fopen(in_name, "rb")) == NULL) {
- printf( "Error opening %s.\n", in_name);
- exit(1);
- }
- if (getc(in) != '2') {
- printf( "Incorrect signature on file.\n");
- exit(1);
- }
- if (getc(in) != 'D') { /* Check signature for 320x400 format */
- printf( "Incorrect signature on file.\n");
- exit(1);
- }
- Xres = getw(in); /* store columns */
- Yres = getw(in); /* store rows */
- if (Xres != 320 || Yres != 200) {
- printf( "Invalid image size -- must be 320*200, but is %d*%d.\n", Xres, Yres);
- exit(1);
- }
-
- num_colours = getc(in);
- if (num_colours == 0) num_colours = 256;
- fread(palette, 3, num_colours, in);
-
- 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);
- }
- fclose(in);
-
- if (EGifOpenFileName(out_fname) == -1) return;
- EGifPutScreenDesc(Xres/4, Yres*4, 6, 0, 8, palette);
- printf("\nImage size is %dx%d\n", Xres, Yres);
- }
-
- static int write_gif_image(char *in_name, UINT Xres, UINT top, UINT bottom)
- {
- UINT i, plane;
- UCHAR *ScanLine;
- FILE *fp;
- UINT maxcol, maxrow;
- UINT Yres = 200;
-
- if ((fp = fopen(in_name, "rb")) == NULL) return FALSE;
-
- if (getc(fp) != '2') {
- printf( "\nIncorrect signature on file.\n");
- exit(1);
- }
- if (getc(fp) != 'D') { /* Check signature for 320x200 format */
- printf( "\nIncorrect signature on file.\n");
- exit(1);
- }
-
- maxcol = getw(fp); /* store columns */
- maxrow = getw(fp); /* store rows */
- if (maxcol != 320 || maxrow != 200) {
- printf( "\nInvalid image size -- must be 320*200, but is %d*%d.\n",
- maxcol, maxrow);
- exit(1);
- }
- colours = getc(fp);
- if (colours == 0) colours = 256;
- fread(palette, 3, colours, fp);
-
- EGifPutImageDesc(0, top, Xres, (bottom - top + 1)*4, 8);
- CHECK_ALLOC(ScanLine, UCHAR, Xres, "Scan Line");
-
- /* Here it is - get one raw line from in_file, and dump to Gif: */
- for (plane = 0; plane < 4; plane++) {
- printf(".");
- fseek(fp, top * Xres, SEEK_CUR); /* Skip first common bit */
- for (i = top; i <= bottom; i++) {
- fread(ScanLine, 1, Xres, fp);
- if (EGifPutLine(ScanLine, Xres)) break;
- }
- fseek(fp, (Yres - bottom - 1) * Xres, SEEK_CUR); /* Skip end common bit */
- }
- printf("\n");
- fclose(fp);
- free(ScanLine);
- return TRUE;
- }
-
- int convert(char *in_name1, char *in_name2)
- {
- UINT i, plane, maxcol, maxrow;
- FILE *fp;
- char *image[2][4];
- UINT block_size, min, max;
- char *in_name[2];
-
- in_name[0] = in_name1;
- in_name[1] = in_name2;
-
- printf("Converting %s & %s\t", in_name1, in_name2);
- for (i = 0; i < 2; i++) {
- if ((fp = fopen(in_name[i], "rb")) == NULL) return FALSE;
-
- if (getc(fp) != '2') {
- printf( "\nIncorrect signature on file.\n");
- exit(1);
- }
- if (getc(fp) != 'D') { /* Check signature for 320x400 format */
- printf( "\nIncorrect signature on file.\n");
- exit(1);
- }
-
- maxcol = getw(fp); /* store columns */
- maxrow = getw(fp); /* store rows */
- if (maxcol != 320 || maxrow != 200) {
- printf( "\nInvalid image size -- must be 320*200, but is %d*%d.\n", maxcol, maxrow);
- exit(1);
- }
- block_size = maxcol * maxrow / 4;
- colours = getc(fp);
- if (colours == 0) colours = 256;
- fread(palette, 3, colours, fp);
- for (plane = 0; plane < 4; plane++) {
- CHECK_ALLOC(image[i][plane], char, block_size, "Image buffer");
- fread(image[i][plane], 1, block_size, fp);
- }
- fclose(fp);
- }
-
- min = block_size;
- for (plane = 0; plane < 4; plane++) {
- for (i = 0 ; i < min; i++) {
- if (image[0][plane][i] != image[1][plane][i]) {
- min = i;
- break;
- }
- }
- }
-
- if (min == block_size) printf("Images are the same\n");
- else {
- max = min;
- for (plane = 0; plane < 4; plane++) {
- for (i = block_size - 1; i > max; i--) {
- if (image[0][plane][i] != image[1][plane][i]) {
- max = i;
- break;
- }
- }
- }
-
- min /= 80;
- max /= 80;
- printf("Lines %d:%d", min, max);
-
- write_gif_image(in_name2, 80, min, max);
- }
-
- for (plane = 0; plane < 4; plane++) {
- free(image[0][plane]);
- free(image[1][plane]);
- }
-
- return TRUE;
- }
-
- void cdecl main(int argc, char *argv[])
- {
- char in_fname1[256], in_fname2[256], out_fname[256];
- int file_no;
-
- printf("ANIMGIF v1.5 -- Create a GIF file containing an animation sequence.\n");
- printf("By F van der Hulst. Copyright 1992\n\n");
- if (argc != 3) {
- printf("Usage: %s frame output\n", argv[0]);
- printf(" frame is the name (without extension) of the input frame files\n");
- printf(" output is the name (without extension) of the GIF output file\n\n");
- exit(1);
- }
-
- sprintf(in_fname1, "%s.0", argv[1]);
- sprintf(out_fname, "%s.gif", argv[2]);
- create_gif_header(out_fname, in_fname1);
- printf("Outputting %s", in_fname1);
- write_gif_image(in_fname1, 80, 0, 199);
-
- sprintf(in_fname2, "%s.1", argv[1]);
- convert(in_fname1, in_fname2);
-
- sprintf(in_fname2, "%s.2", argv[1]);
-
- file_no = 3;
- while (convert(in_fname1, in_fname2)) {
- sprintf(in_fname1, "%s.%d", argv[1], file_no - 2);
- sprintf(in_fname2, "%s.%d", argv[1], file_no);
- file_no++;
- }
- EGifCloseFile();
- printf("\n\n");
- }
-
-