home *** CD-ROM | disk | FTP | other *** search
- /* CLIPGIF.c - Clip and re-encode GIF files
-
- Written by Steve Becquer (74155,767)
-
- Version 1.01 last revised 10/22/88
-
- GIF and 'Graphics Interchange Format' are trademarks (tm) of
- CompuServe Incorporated, an H&R Block Company */
-
- #include <stdio.h>
- #include <conio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <malloc.h>
-
- #define MAXSTRLEN 255
- #define EOS 0
- #define TRUE -1
- #define FALSE 0
-
- extern int Decompress(unsigned int,int (*)(),void (*)(unsigned int));
- extern int Compress(unsigned int,int (*)(),void (*)(unsigned int));
-
- unsigned char InFile[MAXSTRLEN];
- FILE *InGIF;
- unsigned char OutFile[MAXSTRLEN];
- FILE *OutGIF;
-
- unsigned int width, height, left, top, iwidth, iheight;
- unsigned int newwidth, newheight, newleft, newtop, newiwidth, newiheight;
- unsigned int interlaced, relace, image;
-
- int block_count, block_offset;
- unsigned char buffer[256];
-
- unsigned char far **GIF_buf;
- unsigned char far *rsv_buf;
-
- unsigned int pass, line, line_offset, last_line, eom;
- unsigned line_inc[5] = {8,8,4,2,0};
- unsigned line_start[5] = {0,4,2,1,0};
-
- long pTimer()
- {
- long far *clock_count = (long far *) 0x046C;
-
- return(*clock_count);
- }
-
- void Upper(string)
- char *string;
- {
-
- while (*string != EOS) {
- *string = islower(*string) ? toupper(*string) : *string;
- string++;
- }
- }
-
- unsigned int Aski(string,deflt)
- unsigned char *string;
- unsigned int deflt;
- {
- unsigned char avalue[MAXSTRLEN];
- int temp;
-
- printf(string);
- gets(avalue);
- if (avalue[0] == EOS)
- return(deflt);
- temp = atoi(avalue);
- if (temp < 0)
- return(deflt);
- else
- return(temp);
- }
-
- unsigned int Askyn(string,deflt)
- unsigned char *string;
- unsigned int deflt;
- {
- unsigned char avalue[MAXSTRLEN];
- int temp;
-
- printf(string);
- gets(avalue);
- if (avalue[0] == EOS)
- return(deflt);
- if (avalue[0] == 'Y' || avalue[0] == 'y')
- return(TRUE);
- if (avalue[0] == 'N' || avalue[0] == 'n')
- return(FALSE);
- return(deflt);
- }
-
- unsigned int Getword()
- {
-
- return(fgetc(InGIF) | (fgetc(InGIF) << 8));
- }
-
- void Putword(wvalue)
- unsigned int wvalue;
- {
- int temp;
-
- temp = fputc(wvalue,OutGIF);
- temp = fputc((wvalue >> 8),OutGIF);
- }
-
- unsigned char Getbyte()
- {
-
- return(fgetc(InGIF));
- }
-
- void Putbyte(bvalue)
- unsigned char bvalue;
- {
- int temp;
-
- temp = fputc(bvalue,OutGIF);
- }
-
- void Get_buf(y)
- int y;
- {
- if (GIF_buf[y] == NULL) {
- GIF_buf[y] = (unsigned char far *) _fmalloc(newwidth);
- if (GIF_buf[y] == NULL) {
- GIF_buf[y] = GIF_buf[last_line];
- eom = TRUE;
- }
- else
- last_line = y;
- }
- }
-
- int Get_raster_byte()
- {
- int byte, temp;
-
- if (block_count == 0) {
- block_count = fgetc(InGIF);
- if (block_count == 0)
- return(-1);
- temp = fread(buffer,1,block_count,InGIF);
- block_offset = 0;
- }
- byte = buffer[block_offset++];
- block_count--;
- return(byte);
- }
-
- void Put_raster_byte(byte)
- unsigned int byte;
- {
- int temp;
-
- if (block_count == 255) {
- buffer[0] = block_count;
- temp = fwrite(buffer,1,256,OutGIF);
- block_count = 0;
- }
- buffer[++block_count] = byte;
- }
-
- int Get_pixel()
- {
-
- if (line_offset >= newiwidth) {
- line_offset = 0;
- if (relace) {
- line += line_inc[pass];
- if (line >= newiheight)
- if (++pass > 3)
- return(-1);
- else
- line = line_start[pass];
- }
- else
- if (++line >= newiheight)
- return(-1);
- }
- return(GIF_buf[line][line_offset++]);
- }
-
- void Put_pixel(pixel)
- unsigned int pixel;
- {
-
- if (pass > 3)
- return;
- if (line_offset >= iwidth) {
- line_offset = 0;
- if (interlaced) {
- line += line_inc[pass];
- if (line >= iheight) {
- line = line_start[++pass];
- if (pass > 3)
- return;
- }
- }
- else
- if (++line >= iheight) {
- pass = 4;
- return;
- }
- if (line < newiheight)
- Get_buf(line);
- }
- if (line < newiheight && line_offset < newiwidth)
- GIF_buf[line][line_offset] = pixel;
- line_offset++;
- }
-
- void Flush()
- {
- int i, temp;
-
- if (block_count != 0) {
- buffer[0] = block_count;
- temp = fwrite(buffer,1,block_count+1,OutGIF);
- }
- }
-
- void PrintHelp()
- {
-
- puts("\nThis program can be used to clip and re-encode GIF files.");
- puts("You will be prompted for new GIF parameter values. Enter");
- puts("new value or hit enter to maintain old value.");
- puts("\nUsage: CLIPGIF [drive:][path][infile] [drive:][path][outfile]");
- puts(" infile ........ Input GIF file (extension defaults to .GIF)");
- puts(" outfile ....... Output GIF file (extension defaults to .GIF)");
- }
-
- void Signature()
- {
- int i, temp;
- unsigned char signature[6];
-
- for (i=0; i<6; i++)
- signature[i] = fgetc(InGIF);
- signature[i] = '\0';
- if (strncmp(signature,"GIF87a",6)) {
- printf("\n%s is not a valid GIF file\n",InFile);
- exit(1);
- }
- temp = fputs(signature,OutGIF);
- }
-
- void ScreenDescriptor()
- {
- unsigned char avalue[MAXSTRLEN], byte;
- int i, gcm, colors;
-
- width = Getword();
- printf("\nScreen width: %d\n",width);
- height = Getword();
- printf("Screen height: %d\n",height);
- newwidth = Aski("\nEnter new screen width: ",width);
- while (newwidth > width)
- newwidth = Aski("New screen width to large, renter: ",width);
- Putword(newwidth);
- newheight = Aski("Enter new screen height: ",height);
- while (newheight > height)
- newheight = Aski("New screen height to large, renter: ",height);
- Putword(newheight);
- byte = Getbyte();
- gcm = byte & 0x80;
- colors = 1 << ((byte & 0x07) + 1);
- Putbyte(byte);
- Putbyte(Getbyte());
- Putbyte(Getbyte());
- if (gcm)
- for (i=0; i<colors; i++) {
- Putbyte(Getbyte());
- Putbyte(Getbyte());
- Putbyte(Getbyte());
- }
- }
-
- void SkipImage()
- {
- int i, lcm, colors;
- unsigned char byte;
-
- for (i=0; i<8; i++)
- byte = Getbyte();
- colors = 1 << ((byte & 0x07) + 1);
- byte = Getbyte();
- lcm = byte & 0x80;
- colors = 1 << ((byte & 0x07) + 1);
- if (lcm)
- for (i=0; i<colors; i++) {
- byte = Getbyte();
- byte = Getbyte();
- byte = Getbyte();
- }
- byte = Getbyte();
- while ((i = Get_raster_byte()) >= 0);
- }
-
- void ImageDescriptor()
- {
- unsigned char avalue[MAXSTRLEN], byte;
- int i, lcm, colors, codesize, status;
-
- printf("\nImage descriptor %d found\n",++image);
- i = Askyn("\nDiscard this image? ",FALSE);
- if (i) {
- SkipImage();
- return;
- }
- Putbyte(',');
- left = Getword();
- printf("\nImage left: %d\n",left);
- top = Getword();
- printf("\Image top: %d\n",top);
- iwidth = Getword();
- printf("\Image width: %d\n",width);
- iheight = Getword();
- printf("\Image height: %d\n",height);
- newleft = Aski("\nEnter new image left: ",left);
- Putword(newleft);
- newtop = Aski("Enter new image top: ",top);
- Putword(newtop);
- newiwidth = Aski("Enter new image width: ",iwidth);
- while (newiwidth > newwidth)
- newiwidth = Aski("New image width to large, renter: ",iwidth);
- Putword(newiwidth);
- newiheight = Aski("Enter new image height: ",iheight);
- while (newiheight > newheight)
- newiwidth = Aski("New image height to large, renter: ",iheight);
- Putword(newiheight);
- byte = Getbyte();
- lcm = byte & 0x80;
- interlaced = byte & 0x40;
- if (interlaced)
- relace = !Askyn("\nImage is interlaced, make it sequential? ",FALSE);
- else
- relace = Askyn("\nImage is sequential, make it interlaced? ",FALSE);
- if (relace)
- byte |= 0x40;
- else
- byte &= 0xBF;
- Putbyte(byte);
- colors = 1 << ((byte & 0x07) + 1);
- if (lcm)
- for (i=0; i<colors; i++) {
- Putbyte(Getbyte());
- Putbyte(Getbyte());
- Putbyte(Getbyte());
- }
- codesize = Getbyte();
- Putbyte(codesize);
- block_count = 0;
- line = 0;
- line_offset = 0;
- pass = 0;
- eom = FALSE;
- Get_buf(0);
- status = Decompress(codesize,Get_raster_byte,Put_pixel);
- if (status) {
- puts("\nError in Decompress routine");
- exit(1);
- }
- if (eom)
- puts("\nMemory was exhausted, possible incomplete image");
- block_count = 0;
- line = 0;
- line_offset = 0;
- pass = 0;
- status = Compress(codesize,Get_pixel,Put_raster_byte);
- if (status) {
- puts("\nError in Compress routine");
- exit(1);
- }
- Flush();
- Putbyte(0x00);
- }
-
- void ExtensionBlock()
- {
- int i, j;
-
- Putbyte('!');
- Putbyte(Getbyte());
- while (i = Getbyte()) {
- Putbyte(i);
- for (j=0; j<i; j++)
- Putbyte(Getbyte());
- }
- Putbyte(0x00);
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int i, done = FALSE, separator;
-
- puts("\nCLIPGIF Version 1.01 - Clip and re-encode GIF files");
- if (argc < 3)
- PrintHelp();
- puts("\nGIF and 'Graphics Interchange Format' are trademarks (tm)");
- puts("of CompuServe Incorporated, an H&R Block Company");
- if (argc < 3)
- exit(0);
-
- strcpy(InFile,argv[1]);
- Upper(InFile);
- if (strchr(InFile,'.') == NULL)
- strcat(InFile,".GIF");
- strcpy(OutFile,argv[2]);
- Upper(OutFile);
- if (strchr(OutFile,'.') == NULL)
- strcat(OutFile,".GIF");
- if ((InGIF = fopen(InFile,"rb")) == NULL) {
- printf("\nCan't open input file %s\n",InFile);
- exit(1);
- }
- if ((OutGIF = fopen(OutFile,"wb")) == NULL) {
- printf("\nCan't open output file %s\n",InFile);
- exit(1);
- }
-
- Signature();
- ScreenDescriptor();
- GIF_buf = (unsigned char far **) malloc(newheight*sizeof(char far *));
- if (GIF_buf == NULL) {
- puts("\nNot enough memory to run CLIPGIF");
- exit(1);
- }
- for (i=0; i<newheight; i++)
- GIF_buf[i] = NULL;
- while (!done && ((separator = fgetc(InGIF)) != EOF)) {
- switch (separator) {
- case ',': {
- ImageDescriptor();
- break;
- }
-
- case '!': {
- ExtensionBlock();
- break;
- }
-
- case ';': {
- Putbyte(';');
- done = TRUE;
- break;
- }
- }
- }
-
- fclose(InGIF);
- fclose(OutGIF);
- }