/* get_next_code() * - gets the next code from the GIF file. Returns the code, or else * a negative number in case of file errors... */ static short get_next_code() { short i, x; ULONG ret; if (nbits_left == 0) { if (navail_bytes <= 0) { /* Out of bytes in current block, so read next block */ pbytes = byte_buff; if ((navail_bytes = gif_get_byte()) < 0) return(navail_bytes); else if (navail_bytes) { for (i = 0; i < navail_bytes; ++i) { if ((x = gif_get_byte()) < 0) return(x); byte_buff[i] = (UTINY) x; } } } b1 = *pbytes++; nbits_left = 8; --navail_bytes; } ret = b1 >> (8 - nbits_left); while (curr_size > nbits_left) { if (navail_bytes <= 0) { /* Out of bytes in current block, so read next block */ pbytes = byte_buff; if ((navail_bytes = gif_get_byte()) < 0) return(navail_bytes); else if (navail_bytes) { for (i = 0; i < navail_bytes; ++i) { if ((x = gif_get_byte()) < 0) return(x); byte_buff[i] = (UTINY) x; } } } b1 = *pbytes++; ret |= b1 << nbits_left; nbits_left += 8; --navail_bytes; } nbits_left -= curr_size; ret &= code_mask[curr_size]; return((short)(ret)); }
static short decoder( short linewidth, unsigned char far * buf, unsigned char far * stack, unsigned char far * suffix, unsigned short far * prefix) { unsigned char far *sp; unsigned char far *bufptr; register short code, fc, oc, bufcnt; short c, size, ret; /* * Initialize for decoding a new image... */ if ((size = gif_get_byte()) < 0) return (size); if (size < 2 || 9 < size) return (BAD_CODE_SIZE); init_exp(size); /* * Initialize in case they forgot to put in a clear code. (This * shouldn't happen, but we'll try and decode it anyway...) */ oc = fc = 0; /* * Set up the stack pointer and decode buffer pointer */ sp = stack; bufptr = buf; bufcnt = linewidth; /* * This is the main loop. For each code we get we pass through the * linked list of prefix codes, pushing the corresponding "character" * for each code onto the stack. When the list reaches a single * "character" we push that on the stack too, and then start * unstacking each character for output in the correct order. Special * handling is included for the clear code, and the whole thing ends * when we get an ending code. */ while ((c = get_next_code()) != ending) { /* * If we had a file error, return without completing the * decode */ if (c < 0) { return (c); } /* * If the code is a clear code, reinitialize all necessary * items. */ if (c == clear) { curr_size = size + 1; slot = newcodes; top_slot = 1 << curr_size; /* * Continue reading codes until we get a non-clear * code (Another unlikely, but possible case...) */ while ((c = get_next_code()) == clear) ; /* * If we get an ending code immediately after a clear * code (Yet another unlikely case), then break out * of the loop. */ if (c == ending) break; /* * Finally, if the code is beyond the range of * already set codes, (This one had better NOT * happen... I have no idea what will result from * this, but I doubt it will look good...) then set * it to color zero. */ if (c >= slot) c = 0; oc = fc = c; /* * And let us not forget to put the char into the * buffer... And if, on the off chance, we were * exactly one pixel from the end of the line, we * have to send the buffer to the gif_out_line() * routine... */ *bufptr++ = c; if (--bufcnt == 0) { if ((ret = gif_out_line(buf, linewidth)) < 0) { return (ret); } bufptr = buf; bufcnt = linewidth; } } else { /* * In this case, it's not a clear code or an ending * code, so it must be a code code... So we can now * decode the code into a stack of character codes. * (Clear as mud, right?) */ code = c; /* * Here we go again with one of those off chances... * If, on the off chance, the code we got is beyond * the range of those already set up (Another thing * which had better NOT happen...) we trick the * decoder into thinking it actually got the last * code read. (Hmmn... I'm not sure why this works... * But it does...) */ if (code >= slot) { if (code > slot) ++bad_code_count; code = oc; *sp++ = fc; } /* * Here we scan back along the linked list of * prefixes, pushing helpless characters (ie. * suffixes) onto the stack as we do so. */ while (code >= newcodes) { *sp++ = suffix[code]; code = prefix[code]; } /* * Push the last character on the stack, and set up * the new prefix and suffix, and if the required * slot number is greater than that allowed by the * current bit size, increase the bit size. (NOTE - * If we are all full, we *don't* save the new suffix * and prefix... I'm not certain if this is * correct... it might be more proper to overwrite * the last code... */ *sp++ = code; if (slot < top_slot) { suffix[slot] = fc = code; prefix[slot++] = oc; oc = c; } if (slot >= top_slot) if (curr_size < 12) { top_slot <<= 1; ++curr_size; } /* * Now that we've pushed the decoded string (in * reverse order) onto the stack, lets pop it off and * put it into our decode buffer... And when the * decode buffer is full, write another line... */ while (sp > stack) { *bufptr++ = *(--sp); if (--bufcnt == 0) { if ((ret = gif_out_line(buf, linewidth)) < 0) { return (ret); } bufptr = buf; bufcnt = linewidth; } } } } ret = 0; if (bufcnt != linewidth) ret = gif_out_line(buf, (linewidth - bufcnt)); return (ret); }
short decoder (int i_linewidth) { short linewidth; FAST UTINY *sp, *bufptr; UTINY *buf; FAST short code, fc, oc, bufcnt; short c, size, ret; linewidth = (short)i_linewidth; /* Initialize for decoding a new image... */ if ((size = gif_get_byte()) < 0) return(size); if (size < 2 || 9 < size) return(BAD_CODE_SIZE); init_exp((int)size); /* changed param to int */ dstack = (UTINY *)POV_MALLOC((MAX_CODES + 1)*sizeof(UTINY), "GIF dstack"); suffix = (UTINY *)POV_MALLOC((MAX_CODES + 1)*sizeof(UTINY), "GIF suffix"); prefix = (UWORD *)POV_MALLOC((MAX_CODES + 1)*sizeof(UWORD), "GIF prefix"); /* Initialize in case they forgot to put in a clear code. * (This shouldn't happen, but we'll try and decode it anyway...) */ oc = fc = 0; buf = decoderline; bad_code_count = 0; /* Set up the stack pointer and decode buffer pointer */ sp = dstack; bufptr = buf; bufcnt = linewidth; /* This is the main loop. For each code we get we pass through the * linked list of prefix codes, pushing the corresponding "character" for * each code onto the stack. When the list reaches a single "character" * we push that on the stack too, and then start unstacking each * character for output in the correct order. Special handling is * included for the clear code, and the whole thing ends when we get * an ending code. */ while ((c = get_next_code()) != ending) { Do_Cooperate(0); /* If we had a file error, return without completing the decode */ if (c < 0) { cleanup_gif_decoder(); return(0); } /* If the code is a clear code, reinitialize all necessary items. */ if (c == clear_code) { curr_size = size + 1; slot = newcodes; top_slot = 1 << curr_size; /* Continue reading codes until we get a non-clear code * (Another unlikely, but possible case...) */ while ((c = get_next_code()) == clear_code) ; /* If we get an ending code immediately after a clear code * (Yet another unlikely case), then break out of the loop. */ if (c == ending) break; /* Finally, if the code is beyond the range of already set codes, * (This one had better NOT happen... I have no idea what will * result from this, but I doubt it will look good...) then set it * to color zero. */ if (c >= slot) c = 0; oc = fc = c; /* And let us not forget to put the char into the buffer... And * if, on the off chance, we were exactly one pixel from the end * of the line, we have to send the buffer to the out_line() * routine... */ *bufptr++ = (UTINY) c; if (--bufcnt == 0) { Do_Cooperate(1); if ((ret = out_line(buf, linewidth)) < 0) { cleanup_gif_decoder(); return(ret); } bufptr = buf; bufcnt = linewidth; } } else { /* In this case, it's not a clear code or an ending code, so * it must be a code code... So we can now decode the code into * a stack of character codes. (Clear as mud, right?) */ code = c; /* Here we go again with one of those off chances... If, on the * off chance, the code we got is beyond the range of those already * set up (Another thing which had better NOT happen...) we trick * the decoder into thinking it actually got the last code read. * (Hmmn... I'm not sure why this works... But it does...) */ if (code >= slot) { if (code > slot) ++bad_code_count; code = oc; *sp++ = (UTINY) fc; } /* Here we scan back along the linked list of prefixes, pushing * helpless characters (ie. suffixes) onto the stack as we do so. */ while (code >= newcodes) { *sp++ = suffix[code]; code = prefix[code]; } /* Push the last character on the stack, and set up the new * prefix and suffix, and if the required slot number is greater * than that allowed by the current bit size, increase the bit * size. (NOTE - If we are all full, we *don't* save the new * suffix and prefix... I'm not certain if this is correct... * it might be more proper to overwrite the last code... */ *sp++ = (UTINY) code; if (slot < top_slot) { fc = code; suffix[slot] = (UTINY) fc; prefix[slot++] = oc; oc = c; } if (slot >= top_slot) if (curr_size < 12) { top_slot <<= 1; ++curr_size; } /* Now that we've pushed the decoded string (in reverse order) * onto the stack, lets pop it off and put it into our decode * buffer... And when the decode buffer is full, write another * line... */ while (sp > dstack) { *bufptr++ = *(--sp); if (--bufcnt == 0) { Do_Cooperate(1); if ((ret = out_line(buf, linewidth)) < 0) { cleanup_gif_decoder(); return(ret); } bufptr = buf; bufcnt = linewidth; } } } } ret = 0; if (bufcnt != linewidth) ret = out_line(buf, (linewidth - bufcnt)); cleanup_gif_decoder(); return(ret); }