#include <stdio.h>
#include <alloc.h>

typedef struct { unsigned char r,
                               g,
                               b;
               } Palette[256];

typedef struct { unsigned int  Width,
                               Height;
                 unsigned char ColInfo,
                               BackGround,
                               PixelAspect;
               } GIFDesc;

typedef struct { unsigned char Separator;
                 unsigned int  Left,
                               Top,
                               Width,
                               Height;
                 unsigned char Info;
               } ImageDesc;

void main(int argc, char * argv[])
{
    FILE *i, *o;
    char *image;
    char gifsig[6], *GIFSIG = "GIF";
    GIFDesc gd;
    ImageDesc id;
    Palette pal;
    long cp, len;
    int bpp, colors;

    /* Open the left GIF image file */

    if ((i = fopen(argv[1], "rb")) == NULL)
    {
        printf("Unable to open input file %s.\n", argv[1]);
        exit(-1);
    }

    if ((o = fopen(argv[3], "wb")) == NULL)
    {
        printf("Unable to open input file %s.\n", argv[3]);
        exit(-1);
    }

    /* Read in left file */

    fread(&gifsig, sizeof(gifsig), 1, i); /* Read in the signature "GIFxxx" */

    if (strncmp(gifsig, GIFSIG, 3) != 0)
    {
        printf("%s is not a .gif file.\n", argv[1]);
        exit(-1);
    }

    fread(&gd, sizeof(gd), 1, i);   /* Read in the GIF(screen) descriptor */

    bpp = (gd.ColInfo & 0x07) + 1;  /* Calculate the size of the color map */
    colors = 1 << bpp;

    fread(&pal, colors, 3, i);      /* Read in the palette */

    fread(&id, sizeof(id), 1, i);   /* Read in the image dascriptor */

    cp = ftell(i);                  /* Save the current position in the file */
    fseek(i, 0L, SEEK_END);         /* Seek to the end of the file */
    len = ftell(i) - cp;            /* Calculate te length of the LZW */
                                    /* encoded image */
    fseek(i, cp, SEEK_SET);         /* Seek to where we were */

    image = malloc(len - 1);        /* Allocate memory for the data */
    fread(image, len - 1, 1, i);    /* Read in the data, both minus the */
                                    /* ';' file terminator */

    close(i);                       /* Close the input file */

    /* Write out sig, headers and palette of left file */

    fwrite("GIF89a", 6, 1, o);
    fwrite(&gd, sizeof(gd), 1, o);
    fwrite(&pal, 768, 1, o);
    fwrite(&id, sizeof(id), 1, o);

    /* Write out left image */

    fwrite(image, len - 1, 1, o);
    free(image);                        /* and free the memory */

    /* Open the right GIF image file */

    if ((i = fopen(argv[2], "rb")) == NULL)
    {
        printf("Unable to open input file %s.\n", argv[2]);
        exit(-1);
    }

    /* Read in right file */

    fread(&gifsig, sizeof(gifsig), 1, i);

    if (strncmp(gifsig, GIFSIG, 3) != 0)
    {
        printf("%s is not a .gif file.\n", argv[2]);
        exit(-1);
    }

    fread(&gd, sizeof(gd), 1, i);   /* Read in the GIF(screen) descriptor */

    bpp = (gd.ColInfo & 0x07) + 1;  /* Calculate the size of the color map */
    colors = 1 << bpp;

    fread(&pal, colors, 3, i);      /* Read in the palette */

    fread(&id, sizeof(id), 1, i);   /* Read in the image dascriptor */

    cp = ftell(i);                  /* Save the current position in the file */
    fseek(i, 0L, SEEK_END);         /* Seek to the end of the file */
    len = ftell(i) - cp;            /* Calculate te length of the LZW */
                                    /* encoded image */
    fseek(i, cp, SEEK_SET);         /* Seek to where we were */

    image = malloc(len);            /* Allocate memory for the data */
    fread(image, len, 1, i);        /* Read in the data, both minus the */
                                    /* ';' file terminator */

    close(i);                       /* Close the input file */

    /* Write out header of right file*/

    fwrite(&id, 10, 1, o);

    /* Write out right image */

    fwrite(image, len, 1, o);
    free(image);                   /* and free the memory */

    close(o);                      /* Close the output file */
}


