📄 whirlgif.c
字号:
left = j; break; } } }/* Finally test between bottom and top at the right hand side */ for (i = bot-1; i >= top; i-- ) { k= (i+1) * wi-1; p = &pix[k]; po = &pixold[k]; for (j = wi-1; j > right; j-- ) { if ( *p-- != *po-- ) { right = j; break; } } } gifimage.left += left; gifimage.top += top; gifimage.width = right-left+1; gifimage.height = bot-top+1; WriteImageHeader(fout);/* The rectangle containing diffs is transferred to the mem area of pixold */ po = pixold; for (i = top; i <= bot; i++ ) { p = &pix[i * wi+left]; for (j = left; j <= right; j++ ) { *po++ = *p++; } } GifEncode(fout, pixold, gifscrn.pixbits+1, gifimage.height * gifimage.width); if (debugFlag) fprintf(stderr, " encoded: width= %d, height = %d, left = %d, top = %d\n", gifimage.width, gifimage.height, gifimage.left, gifimage.top); } else {alike: WriteImageHeader(fout); gifimageold = gifimage; GifEncode(fout, pix, gifscrn.pixbits+1, gifimage.height * gifimage.width); if (debugFlag) fprintf(stderr, " picture re-encoded\n");/* Undocumented feature: If two subsequent images are alike, then send the whole image to the output stream (to keep the timing between frames, and not confuse the viewer with empty images) */ } free(pixold); pixold = pix; fputc(0, fout); /* block count of zero */ } else { WriteImageHeader(fout); i = Xgetc(fp); fputc(i, fout); /* the LZW code size */ while ( ( gifBlockSize = Xgetc(fp) ) > 0 ) { fputc(gifBlockSize, fout); while ( gifBlockSize-- > 0 ) fputc(Xgetc(fp),fout); } if ( gifBlockSize == 0 ) fputc(gifBlockSize, fout); else TheEnd1("GifPassing: Unexpected End of File\n"); } fclose(fp);}/* * read Gif header */void GifScreenHeader(FILE *fp, FILE *fout, int firstTime){ int temp, i; for(i = 0; i < 6; i++) { temp = Xgetc(fp); if(i == 4 && temp == '7') temp = '9'; if (firstTime) fputc(temp, fout); } gifscrn.width = GifGetShort(fp); gifscrn.height = GifGetShort(fp); temp = Xgetc(fp); if (firstTime) { GifPutShort(gifscrn.width, fout); GifPutShort(gifscrn.height, fout); fputc(temp, fout); } gifscrn.m = temp & 0x80; gifscrn.cres = (temp & 0x70) >> 4; gifscrn.pixbits = temp & 0x07; gifscrn.bc = Xgetc(fp); if (firstTime) { if (debugFlag) fprintf(stderr, "First Time ... "); if(GifBgcolor) gifscrn.bc = GifBgcolor & 0xff; fputc(gifscrn.bc, fout); } temp = Xgetc(fp); if (firstTime) { fputc(temp, fout); if ( minimize && gifscrn.bc == 0 ) { /* Set a pseudo screen filled with the background color. This is only done for background color index == 0 because of Netscape and I.E.'s strange handling of backgrounds not covered by an image. */ temp = gifscrn.width * gifscrn.height; if (( pixold = (UBYTE *)malloc(temp * sizeof(UBYTE)) ) == NULL ) TheEnd1("No memory for image\n"); if (debugFlag) fprintf(stderr, "BACKGROUND = %d\n", gifscrn.bc); while (temp > 0) pixold[--temp] = 0; /* gifscrn.bc; */ gifimageold.left = gifimageold.top = 0; gifimageold.width = gifscrn.width; gifimageold.height = gifscrn.height; gifimageold.pixbits = gifscrn.pixbits; } } imagec = gifPtwo[(1+gifscrn.pixbits)]; if (debugFlag) fprintf(stderr, "Screen #%d: %dx%dx%d m=%d cres=%d bkgnd=%d pix=%d\n", count, gifscrn.width, gifscrn.height, imagec, gifscrn.m, gifscrn.cres, gifscrn.bc, gifscrn.pixbits); if (gifscrn.m) { for(i = 0; i < imagec; i++) { gifCmap[i].cmap.red = temp = Xgetc(fp); if (firstTime) fputc(temp, fout); gifCmap[i].cmap.green = temp = Xgetc(fp); if (firstTime) fputc(temp, fout); gifCmap[i].cmap.blue = temp = Xgetc(fp); if (firstTime) fputc(temp, fout); if(firstTime && (global.trans.type==TRANS_RGB && global.trans.valid==0) ) if (global.trans.red == gifCmap[i].cmap.red && global.trans.green == gifCmap[i].cmap.green && global.trans.blue == gifCmap[i].cmap.blue) { if(debugFlag > 1) fprintf(stderr, " Transparent match at %d\n", i); global.trans.map = i; global.trans.valid = 1; } else if(debugFlag > 1) fprintf(stderr, "No transp. RGB=(%x,%x,%x)\n", gifCmap[i].cmap.red, gifCmap[i].cmap.green, gifCmap[i].cmap.blue); } }}void ReadImageHeader(FILE *fp){ int tnum, i, flag; gifimage.left = GifGetShort(fp); if(global.left) gifimage.left += global.left; gifimage.top = GifGetShort(fp); if(global.top) gifimage.top += global.top; gifimage.width = GifGetShort(fp); gifimage.height = GifGetShort(fp); flag = Xgetc(fp); gifimage.i = flag & 0x40; gifimage.pixbits = flag & 0x07; gifimage.m = flag & 0x80; imagex = gifimage.width; imagey = gifimage.height; tnum = gifPtwo[(1+gifimage.pixbits)]; if (debugFlag > 1) fprintf(stderr, "Image: %dx%dx%d (%d,%d) m=%d i=%d pix=%d \n", imagex, imagey, tnum, gifimage.left, gifimage.top, gifimage.m, gifimage.i, gifimage.pixbits); /* if there is an image cmap then read it */ if (gifimage.m) { if(debugFlag>1) fprintf(stderr, "DEBUG:Transferring colormap of %d colors\n", imagec); /* * note below assignment, it may make the subsequent code confusing */ gifscrn.pixbits = gifimage.pixbits; for(i = 0; i < tnum; i++) { gifCmap[i].cmap.red = Xgetc(fp); gifCmap[i].cmap.green = Xgetc(fp); gifCmap[i].cmap.blue = Xgetc(fp); } } gifimage.m = 0; if ( globscrn.m && globscrn.pixbits == gifscrn.pixbits ) { for (i = gifMask[1+globscrn.pixbits]; i >= 0; i--) { if (gifGmap[i].cmap.red != gifCmap[i].cmap.red || gifGmap[i].cmap.green != gifCmap[i].cmap.green || gifGmap[i].cmap.blue != gifCmap[i].cmap.blue ) { gifimage.m = 0x80; break; } } } else gifimage.m = 0x80; return;}void WriteImageHeader(FILE *fout){ int temp, i, flag; /* compute a Gif_GCL */ fputc(0x21, fout); fputc(0xF9, fout); fputc(0x04, fout); flag = global.disposal <<2; if(global.time) flag |= 0x80; if(global.trans.type == TRANS_RGB && global.trans.valid == 0) gifimage.m = 0x80; temp = global.trans.map; if (gifimage.m != 0 && global.trans.type == TRANS_RGB ) { temp = 0; /* set a default value, in case nothing found */ for (i = gifMask[1+gifscrn.pixbits]; i >= 0; i--) { if(global.trans.red == gifCmap[i].cmap.red && global.trans.green == gifCmap[i].cmap.green && global.trans.blue == gifCmap[i].cmap.blue) { if(debugFlag > 1) fprintf(stderr, " Transparent match at %d\n", i); temp = i; flag |= 0x01; } } } else if(global.trans.valid) flag |= 0x01; fputc(flag, fout); GifPutShort(global.time, fout); /* the delay speed - 0 is instantaneous */ fputc(temp, fout); /* the transparency index */ if(debugFlag > 1) { fprintf(stderr, "GCL: delay %d", global.time); if(flag && 0x1) fprintf(stderr, " Transparent: %d", temp); fputc('\n', stderr); } fputc(0, fout); /* end of Gif_GCL */ fputc(',', fout); /* image separator */ GifPutShort(gifimage.left , fout); GifPutShort(gifimage.top , fout); GifPutShort(gifimage.width , fout); GifPutShort(gifimage.height, fout); fputc(gifscrn.pixbits | gifimage.i | gifimage.m, fout); if ( gifimage.m ) { for(i = 0; i < imagec; i++) { fputc(gifCmap[i].cmap.red, fout); fputc(gifCmap[i].cmap.green, fout); fputc(gifCmap[i].cmap.blue, fout); } if(debugFlag) fprintf(stderr, "Local %d color map for picture #%d\n", imagec, count); }}void GifComment(FILE *fout, char *string){ int len; if( (len = strlen(string)) > 254 ) fprintf(stderr, "GifComment: String too long ; dropped\n"); else if ( len > 0 ) { /* Undocumented feature: Empty comment string means no comment block in outfile */ fputc(0x21, fout); fputc(0xFE, fout); fputc(len, fout); fputs(string, fout); fputc(0, fout); } return;}/* * Write a Netscape loop marker. */void GifLoop(FILE *fout, unsigned int repeats){ fputc(0x21, fout); fputc(0xFF, fout); fputc(0x0B, fout); fputs("NETSCAPE2.0", fout); fputc(0x03, fout); fputc(0x01, fout); GifPutShort(repeats, fout); /* repeat count */ fputc(0x00, fout); /* terminator */ if(debugFlag) fprintf(stderr, "Wrote loop extension\n");}void CalcTrans(char *string){ if(string[0] != '#') { global.trans.type = TRANS_MAP; global.trans.map = atoi(string); global.trans.valid = 1; } else { /* it's an RGB value */ int r, g, b; string++; if (debugFlag > 1) fprintf(stderr, "String is %s\n", string); if(3 == sscanf(string, "%2x%2x%2x", &r, &g, &b)) { global.trans.red = r; global.trans.green = g; global.trans.blue = b; global.trans.type = TRANS_RGB; global.trans.valid = 0; if(debugFlag > 1) fprintf(stderr, "Transparent RGB=(%x,%x,%x) = (%d,%d,%d)\n", r, g, b, r, g, b); } } if(debugFlag > 1) fprintf(stderr, "DEBUG:CalcTrans is %d\n", global.trans.type);}void SetOffset(char *string){ int npar, offX, offY; char sep; if ( (npar = sscanf(string, "%d%c%d", &offX, &sep, &offY)) == 3 ) { /* set the offset */ global.left = offX; global.top = offY; if(debugFlag > 1) fprintf(stderr, "Offset set to %d,%d\n", global.left, global.top); return; } fprintf(stderr, "Offset string: '%s'; fields = %d\n", string, npar); TheEnd1("Couldn't parse offset values.\n");}void TheEnd(){ exit(0);}void TheEnd1(char *p){ fprintf(stderr, "Image #%d: %s", count, p); TheEnd();}void Usage(){ fprintf(stderr, "\nUsage: whirlgif %s\n %s\n %s\n", "[-o outfile] [-loop [count]] [-time #delay]", "\t-disp [ none | back | prev | not ]", "\t[ -i listfile] file1 [ -time #delay] file2 ..."); exit(0);}UBYTE Xgetc(FILE *fin){ int i; if ( ( i = fgetc(fin) ) == EOF ) { TheEnd1("Unexpected EOF in input file\n"); } return(i & 0xff);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -