📄 tkimggif.c
字号:
int *transparent;{ static unsigned char buf[256]; int count; switch (label) { case 0x01: /* Plain Text Extension */ break; case 0xff: /* Application Extension */ break; case 0xfe: /* Comment Extension */ do { count = GetDataBlock(chan, (unsigned char*) buf); } while (count > 0); return count; case 0xf9: /* Graphic Control Extension */ count = GetDataBlock(chan, (unsigned char*) buf); if (count < 0) { return 1; } if ((buf[0] & 0x1) != 0) { *transparent = buf[3]; } do { count = GetDataBlock(chan, (unsigned char*) buf); } while (count > 0); return count; } do { count = GetDataBlock(chan, (unsigned char*) buf); } while (count > 0); return count;}static int ZeroDataBlock = 0;static intGetDataBlock(chan, buf) Tcl_Channel chan; unsigned char *buf;{ unsigned char count; if (! ReadOK(chan, &count,1)) { return -1; } ZeroDataBlock = count == 0; if ((count != 0) && (! ReadOK(chan, buf, count))) { return -1; } return count;}static intReadImage(interp, imagePtr, chan, len, rows, cmap, width, height, srcX, srcY, interlace, transparent) Tcl_Interp *interp; char *imagePtr; Tcl_Channel chan; int len, rows; unsigned char cmap[MAXCOLORMAPSIZE][4]; int width, height; int srcX, srcY; int interlace; int transparent;{ unsigned char c; int v; int xpos = 0, ypos = 0, pass = 0; char *pixelPtr; /* * Initialize the Compression routines */ if (! ReadOK(chan, &c, 1)) { Tcl_AppendResult(interp, "error reading GIF image: ", Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } if (LWZReadByte(chan, 1, c) < 0) { interp->result = "format error in GIF image"; return TCL_ERROR; } if (transparent!=-1) { cmap[transparent][CM_RED] = 0; cmap[transparent][CM_GREEN] = 0; cmap[transparent][CM_BLUE] = 0; cmap[transparent][CM_ALPHA] = 0; } pixelPtr = imagePtr; while ((v = LWZReadByte(chan, 0, c)) >= 0 ) { if ((xpos>=srcX) && (xpos<srcX+len) && (ypos>=srcY) && (ypos<srcY+rows)) { *pixelPtr++ = cmap[v][CM_RED]; *pixelPtr++ = cmap[v][CM_GREEN]; *pixelPtr++ = cmap[v][CM_BLUE]; *pixelPtr++ = cmap[v][CM_ALPHA]; } ++xpos; if (xpos == width) { xpos = 0; if (interlace) { switch (pass) { case 0: case 1: ypos += 8; break; case 2: ypos += 4; break; case 3: ypos += 2; break; } while (ypos >= height) { ++pass; switch (pass) { case 1: ypos = 4; break; case 2: ypos = 2; break; case 3: ypos = 1; break; default: return TCL_OK; } } } else { ++ypos; } pixelPtr = imagePtr + (ypos-srcY) * len * 4; } if (ypos >= height) break; } return TCL_OK;}static intLWZReadByte(chan, flag, input_code_size) Tcl_Channel chan; int flag; int input_code_size;{ static int fresh = 0; int code, incode; static int code_size, set_code_size; static int max_code, max_code_size; static int firstcode, oldcode; static int clear_code, end_code; static int table[2][(1<< MAX_LWZ_BITS)]; static int stack[(1<<(MAX_LWZ_BITS))*2], *sp; register int i; if (flag) { set_code_size = input_code_size; code_size = set_code_size+1; clear_code = 1 << set_code_size ; end_code = clear_code + 1; max_code_size = 2*clear_code; max_code = clear_code+2; GetCode(chan, 0, 1); fresh = 1; for (i = 0; i < clear_code; ++i) { table[0][i] = 0; table[1][i] = i; } for (; i < (1<<MAX_LWZ_BITS); ++i) { table[0][i] = table[1][0] = 0; } sp = stack; return 0; } else if (fresh) { fresh = 0; do { firstcode = oldcode = GetCode(chan, code_size, 0); } while (firstcode == clear_code); return firstcode; } if (sp > stack) { return *--sp; } while ((code = GetCode(chan, code_size, 0)) >= 0) { if (code == clear_code) { for (i = 0; i < clear_code; ++i) { table[0][i] = 0; table[1][i] = i; } for (; i < (1<<MAX_LWZ_BITS); ++i) { table[0][i] = table[1][i] = 0; } code_size = set_code_size+1; max_code_size = 2*clear_code; max_code = clear_code+2; sp = stack; firstcode = oldcode = GetCode(chan, code_size, 0); return firstcode; } else if (code == end_code) { int count; unsigned char buf[260]; if (ZeroDataBlock) { return -2; } while ((count = GetDataBlock(chan, buf)) > 0) /* Empty body */; if (count != 0) { return -2; } } incode = code; if (code >= max_code) { *sp++ = firstcode; code = oldcode; } while (code >= clear_code) { *sp++ = table[1][code]; if (code == table[0][code]) { return -2; /* * Used to be this instead, Steve Ball suggested * the change to just return. printf("circular table entry BIG ERROR\n"); */ } code = table[0][code]; } *sp++ = firstcode = table[1][code]; if ((code = max_code) <(1<<MAX_LWZ_BITS)) { table[0][code] = oldcode; table[1][code] = firstcode; ++max_code; if ((max_code>=max_code_size) && (max_code_size < (1<<MAX_LWZ_BITS))) { max_code_size *= 2; ++code_size; } } oldcode = incode; if (sp > stack) return *--sp; } return code;}static intGetCode(chan, code_size, flag) Tcl_Channel chan; int code_size; int flag;{ static unsigned char buf[280]; static int curbit, lastbit, done, last_byte; int i, j, ret; unsigned char count; if (flag) { curbit = 0; lastbit = 0; done = 0; return 0; } if ( (curbit+code_size) >= lastbit) { if (done) { /* ran off the end of my bits */ return -1; } if (last_byte >= 2) { buf[0] = buf[last_byte-2]; } if (last_byte >= 1) { buf[1] = buf[last_byte-1]; } if ((count = GetDataBlock(chan, &buf[2])) == 0) { done = 1; } last_byte = 2 + count; curbit = (curbit - lastbit) + 16; lastbit = (2+count)*8 ; } ret = 0; for (i = curbit, j = 0; j < code_size; ++i, ++j) { ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; } curbit += code_size; return ret;}/* *---------------------------------------------------------------------- * * Minit -- -- * * This procedure initializes a base64 decoder handle * * Results: * none * * Side effects: * the base64 handle is initialized * *---------------------------------------------------------------------- */static voidmInit(string, handle) unsigned char *string; /* string containing initial mmencoded data */ MFile *handle; /* mmdecode "file" handle */{ handle->data = string; handle->state = 0;}/* *---------------------------------------------------------------------- * * Mread -- * * This procedure is invoked by the GIF file reader as a * temporary replacement for "fread", to get GIF data out * of a string (using Mgetc). * * Results: * The return value is the number of characters "read" * * Side effects: * The base64 handle will change state. * *---------------------------------------------------------------------- */static intMread(dst, chunkSize, numChunks, handle) unsigned char *dst; /* where to put the result */ size_t chunkSize; /* size of each transfer */ size_t numChunks; /* number of chunks */ MFile *handle; /* mmdecode "file" handle */{ register int i, c; int count = chunkSize * numChunks; for(i=0; i<count && (c=Mgetc(handle)) != GIF_DONE; i++) { *dst++ = c; } return i;}/* * get the next decoded character from an mmencode handle * This causes at least 1 character to be "read" from the encoded string *//* *---------------------------------------------------------------------- * * Mgetc -- * * This procedure decodes and returns the next byte from a base64 * encoded string. * * Results: * The next byte (or GIF_DONE) is returned. * * Side effects: * The base64 handle will change state. * *---------------------------------------------------------------------- */static intMgetc(handle) MFile *handle; /* Handle containing decoder data and state. */{ int c; int result = 0; /* Initialization needed only to prevent * gcc compiler warning. */ if (handle->state == GIF_DONE) { return(GIF_DONE); } do { c = char64(*handle->data); handle->data++; } while (c==GIF_SPACE); if (c>GIF_SPECIAL) { handle->state = GIF_DONE; return(handle->state ? handle->c : GIF_DONE); } switch (handle->state++) { case 0: handle->c = c<<2; result = Mgetc(handle); break; case 1: result = handle->c | (c>>4); handle->c = (c&0xF)<<4; break; case 2: result = handle->c | (c>>2); handle->c = (c&0x3) << 6; break; case 3: result = handle->c | c; handle->state = 0; break; } return(result);}/* *---------------------------------------------------------------------- * * char64 -- * * This procedure converts a base64 ascii character into its binary * equivalent. This code is a slightly modified version of the * char64 proc in N. Borenstein's metamail decoder. * * Results: * The binary value, or an error code. * * Side effects: * None. *---------------------------------------------------------------------- */static intchar64(c)int c;{ switch(c) { case 'A': return(0); case 'B': return(1); case 'C': return(2); case 'D': return(3); case 'E': return(4); case 'F': return(5); case 'G': return(6); case 'H': return(7); case 'I': return(8); case 'J': return(9); case 'K': return(10); case 'L': return(11); case 'M': return(12); case 'N': return(13); case 'O': return(14); case 'P': return(15); case 'Q': return(16); case 'R': return(17); case 'S': return(18); case 'T': return(19); case 'U': return(20); case 'V': return(21); case 'W': return(22); case 'X': return(23); case 'Y': return(24); case 'Z': return(25); case 'a': return(26); case 'b': return(27); case 'c': return(28); case 'd': return(29); case 'e': return(30); case 'f': return(31); case 'g': return(32); case 'h': return(33); case 'i': return(34); case 'j': return(35); case 'k': return(36); case 'l': return(37); case 'm': return(38); case 'n': return(39); case 'o': return(40); case 'p': return(41); case 'q': return(42); case 'r': return(43); case 's': return(44); case 't': return(45); case 'u': return(46); case 'v': return(47); case 'w': return(48); case 'x': return(49); case 'y': return(50); case 'z': return(51); case '0': return(52); case '1': return(53); case '2': return(54); case '3': return(55); case '4': return(56); case '5': return(57); case '6': return(58); case '7': return(59); case '8': return(60); case '9': return(61); case '+': return(62); case '/': return(63); case ' ': case '\t': case '\n': case '\r': case '\f': return(GIF_SPACE); case '=': return(GIF_PAD); case '\0': return(GIF_DONE); default: return(GIF_BAD); }}/* *---------------------------------------------------------------------- * * Fread -- * * This procedure calls either fread or Mread to read data * from a file or a base64 encoded string. * * Results: - same as fread * *---------------------------------------------------------------------- */static intFread(dst, hunk, count, chan) unsigned char *dst; /* where to put the result */ size_t hunk,count; /* how many */ Tcl_Channel chan;{ if (fromData) { return(Mread(dst, hunk, count, (MFile *) chan)); } else { return Tcl_Read(chan, (char *) dst, (int) (hunk * count)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -