Doxygen Source Code Documentation
gifread.c File Reference
#include "gif.h"
#include <stdarg.h>
#include <assert.h>
#include <string.h>
Go to the source code of this file.
Define Documentation
|
|
|
|
|
Definition at line 70 of file gifread.c. Referenced by read_gif(). |
|
Definition at line 68 of file gifread.c. Referenced by read_application_extension(), read_compressed_image(), read_graphic_control_extension(), read_image(), read_image_block(), read_image_data(), read_unknown_extension(), and suck_data(). |
|
Definition at line 67 of file gifread.c. Referenced by gifgetunsigned(), read_application_extension(), read_color_table(), read_compressed_image(), read_gif(), read_graphic_control_extension(), read_image(), read_image_block(), read_image_data(), read_logical_screen_descriptor(), read_unknown_extension(), and suck_data(). |
|
Definition at line 66 of file gifread.c. Referenced by read_gif(). |
|
Definition at line 69 of file gifread.c. Referenced by read_gif(). |
|
|
Typedef Documentation
|
|
Function Documentation
|
Definition at line 89 of file gifread.c. References Gif_Reader::f, p, and u_int32_t. Referenced by Gif_FullReadFile().
|
|
Definition at line 82 of file gifread.c. References Gif_Reader::f, and i. Referenced by Gif_FullReadFile().
|
|
Definition at line 101 of file gifread.c. References Gif_Reader::f. Referenced by Gif_FullReadFile().
00102 { 00103 return feof(grr->f); 00104 } |
|
Definition at line 95 of file gifread.c. References Gif_Reader::f. Referenced by Gif_FullReadFile().
00096 { 00097 return ftell(grr->f); 00098 } |
|
Definition at line 857 of file gifread.c. References Gif_Reader::block_getter, Gif_Reader::byte_getter, Gif_Reader::eofer, Gif_Reader::f, file_block_getter(), file_byte_getter(), file_eofer(), file_offseter(), Gif_ReadErrorHandler, Gif_Reader::is_record, Gif_Reader::offseter, and read_gif(). Referenced by get_input_stream(), Gif_ReadFile(), input_stream(), and main().
00859 { 00860 Gif_Reader grr; 00861 if (!f) return 0; 00862 grr.f = f; 00863 grr.is_record = 0; 00864 grr.byte_getter = file_byte_getter; 00865 grr.block_getter = file_block_getter; 00866 grr.offseter = file_offseter; 00867 grr.eofer = file_eofer; 00868 return read_gif(&grr, read_flags, h, hthunk); 00869 } |
|
Definition at line 872 of file gifread.c. References Gif_Record::data, GIF_READ_COMPRESSED, GIF_READ_CONST_RECORD, Gif_ReadErrorHandler, Gif_Record::length, make_data_reader(), and read_gif(). Referenced by Gif_ReadRecord().
00874 { 00875 Gif_Reader grr; 00876 if (!gifrec) return 0; 00877 make_data_reader(&grr, gifrec->data, gifrec->length); 00878 if (read_flags & GIF_READ_CONST_RECORD) 00879 read_flags |= GIF_READ_COMPRESSED; 00880 return read_gif(&grr, read_flags, h, hthunk); 00881 } |
|
Definition at line 502 of file gifread.c. References Gif_Image::compressed, Gif_Image::compressed_len, Gif_Stream::errors, Gif_Code, Gif_DeleteArray, GIF_MAX_CODE, Gif_NewArray, Gif_ReadErrorHandler, Gif_Context::handler, Gif_Context::handler_thunk, Gif_Image::image_data, Gif_Image::img, Gif_Context::length, make_data_reader(), Gif_Context::prefix, Gif_Context::stream, Gif_Context::suffix, u_int16_t, and uncompress_image().
00503 { 00504 Gif_Context gfc; 00505 Gif_Stream fake_gfs; 00506 Gif_Reader grr; 00507 int ok = 0; 00508 00509 /* return right away if image is already uncompressed. this might screw over 00510 people who expect re-uncompressing to restore the compressed version. */ 00511 if (gfi->img) 00512 return 1; 00513 if (gfi->image_data) 00514 /* we have uncompressed data, but not an `img' array; 00515 this shouldn't happen */ 00516 return 0; 00517 00518 fake_gfs.errors = 0; 00519 gfc.stream = &fake_gfs; 00520 gfc.prefix = Gif_NewArray(Gif_Code, GIF_MAX_CODE); 00521 gfc.suffix = Gif_NewArray(byte, GIF_MAX_CODE); 00522 gfc.length = Gif_NewArray(u_int16_t, GIF_MAX_CODE); 00523 gfc.handler = h; 00524 gfc.handler_thunk = hthunk; 00525 00526 if (gfi && gfc.prefix && gfc.suffix && gfc.length && gfi->compressed) { 00527 make_data_reader(&grr, gfi->compressed, gfi->compressed_len); 00528 ok = uncompress_image(&gfc, gfi, &grr); 00529 } 00530 00531 Gif_DeleteArray(gfc.prefix); 00532 Gif_DeleteArray(gfc.suffix); 00533 Gif_DeleteArray(gfc.length); 00534 return ok && !fake_gfs.errors; 00535 } |
|
Definition at line 149 of file gifread.c. References Gif_Stream::errors, Gif_Context::handler, Gif_Context::handler_thunk, Gif_Stream::nimages, and Gif_Context::stream. Referenced by one_code(), read_application_extension(), read_gif(), read_graphic_control_extension(), and read_image_data().
|
|
Definition at line 888 of file gifread.c. References Gif_FullReadFile(), and GIF_READ_UNCOMPRESSED.
00889 { 00890 return Gif_FullReadFile(f, GIF_READ_UNCOMPRESSED, 0, 0); 00891 } |
|
Definition at line 894 of file gifread.c. References Gif_FullReadRecord(), and GIF_READ_UNCOMPRESSED.
00895 { 00896 return Gif_FullReadRecord(gifrec, GIF_READ_UNCOMPRESSED, 0, 0); 00897 } |
|
Definition at line 73 of file gifread.c. References gifgetbyte. Referenced by read_application_extension(), read_graphic_control_extension(), read_image(), and read_logical_screen_descriptor().
00074 { 00075 byte one = gifgetbyte(grr); 00076 byte two = gifgetbyte(grr); 00077 return one | (two << 8); 00078 } |
|
Definition at line 135 of file gifread.c. References Gif_Reader::block_getter, Gif_Reader::byte_getter, Gif_Reader::eofer, Gif_Reader::is_record, Gif_Reader::length, Gif_Reader::offseter, record_block_getter(), record_byte_getter(), record_eofer(), record_offseter(), u_int32_t, Gif_Reader::v, and Gif_Reader::w. Referenced by Gif_FullReadRecord(), Gif_FullUncompressImage(), and read_image().
00136 { 00137 grr->v = data; 00138 grr->length = length; 00139 grr->w = length; 00140 grr->is_record = 1; 00141 grr->byte_getter = record_byte_getter; 00142 grr->block_getter = record_block_getter; 00143 grr->offseter = record_offseter; 00144 grr->eofer = record_eofer; 00145 } |
|
Definition at line 158 of file gifread.c. References Gif_Context::decodepos, Gif_Code, gif_read_error(), Gif_Context::image, Gif_Context::length, Gif_Context::maximage, Gif_Context::prefix, Gif_Context::suffix, and u_int16_t. Referenced by read_image_data().
00159 { 00160 byte *suffixes = gfc->suffix; 00161 Gif_Code *prefixes = gfc->prefix; 00162 byte *ptr; 00163 int lastsuffix; 00164 u_int16_t codelength = gfc->length[code]; 00165 00166 gfc->decodepos += codelength; 00167 ptr = gfc->image + gfc->decodepos; 00168 if (ptr > gfc->maximage || !codelength) { 00169 gif_read_error(gfc, (!codelength ? "bad code" : "too much image data")); 00170 /* 5/26/98 It's not good enough simply to count an error, because in the 00171 read_image_data function, if code == next_code, we will store a byte in 00172 gfc->image[gfc->decodepos-1]. Thus, fix decodepos so it's w/in the 00173 image. */ 00174 gfc->decodepos = gfc->maximage - gfc->image; 00175 return 0; 00176 } 00177 00178 /* codelength will always be greater than 0. */ 00179 do { 00180 lastsuffix = suffixes[code]; 00181 *--ptr = lastsuffix; 00182 code = prefixes[code]; 00183 } while (--codelength > 0); 00184 00185 /* return the first pixel in the code, which, since we walked backwards 00186 through the code, was the last suffix we processed. */ 00187 return lastsuffix; 00188 } |
|
Definition at line 686 of file gifread.c. References GIF_MAX_BLOCK, gif_read_error(), gifgetblock, gifgetbyte, gifgetunsigned(), Gif_Stream::loopcount, memcmp(), position, read_unknown_extension(), and Gif_Context::stream. Referenced by read_gif().
00688 { 00689 Gif_Stream *gfs = gfc->stream; 00690 byte buffer[GIF_MAX_BLOCK + 1]; 00691 byte len = gifgetbyte(grr); 00692 gifgetblock(buffer, len, grr); 00693 00694 /* Read the Netscape loop extension. */ 00695 if (len == 11 && memcmp(buffer, "NETSCAPE2.0", 11) == 0) { 00696 00697 len = gifgetbyte(grr); 00698 if (len == 3) { 00699 gifgetbyte(grr); /* throw away the 1 */ 00700 gfs->loopcount = gifgetunsigned(grr); 00701 len = gifgetbyte(grr); 00702 if (len) gif_read_error(gfc, "bad loop extension"); 00703 } else 00704 gif_read_error(gfc, "bad loop extension"); 00705 00706 while (len > 0) { 00707 gifgetblock(buffer, len, grr); 00708 len = gifgetbyte(grr); 00709 } 00710 return 1; 00711 00712 } else { 00713 buffer[len] = 0; 00714 return read_unknown_extension(gfs, 0xFF, (char *)buffer, position, grr); 00715 } 00716 } |
|
Definition at line 374 of file gifread.c. References Gif_Color::blue, c, Gif_Colormap::col, GIF_DEBUG, Gif_NewFullColormap(), gifgetbyte, Gif_Color::green, Gif_Color::haspixel, and Gif_Color::red. Referenced by read_image(), and read_logical_screen_descriptor().
00375 { 00376 Gif_Colormap *gfcm = Gif_NewFullColormap(size, size); 00377 Gif_Color *c; 00378 if (!gfcm) return 0; 00379 00380 GIF_DEBUG(("colormap(%d)", size)); 00381 for (c = gfcm->col; size; size--, c++) { 00382 c->red = gifgetbyte(grr); 00383 c->green = gifgetbyte(grr); 00384 c->blue = gifgetbyte(grr); 00385 c->haspixel = 0; 00386 } 00387 00388 return gfcm; 00389 } |
|
Definition at line 720 of file gifread.c. References Gif_Image::comment, Gif_AddCommentTake(), Gif_NewComment(), and suck_data(). Referenced by read_gif().
00721 { 00722 int len; 00723 Gif_Comment *gfcom = gfi->comment; 00724 char *m = suck_data(0, &len, grr); 00725 if (m) { 00726 if (!gfcom) 00727 gfcom = gfi->comment = Gif_NewComment(); 00728 if (!gfcom || !Gif_AddCommentTake(gfcom, m, len)) 00729 return 0; 00730 } 00731 return 1; 00732 } |
|
Definition at line 420 of file gifread.c. References Gif_Image::compressed, Gif_Image::compressed_len, Gif_Image::free_compressed, Gif_DeleteArrayFunc, Gif_NewArray, GIF_READ_CONST_RECORD, Gif_ReArray, gifgetblock, gifgetbyte, i, Gif_Reader::is_record, u_int32_t, Gif_Reader::v, and Gif_Reader::w. Referenced by read_image().
00421 { 00422 if (grr->is_record) { 00423 const byte *first = grr->v; 00424 u_int32_t pos; 00425 00426 /* scan over image */ 00427 pos = 1; /* skip min code size */ 00428 while (pos < grr->w) { 00429 int amt = grr->v[pos]; 00430 pos += amt + 1; 00431 if (amt == 0) break; 00432 } 00433 if (pos > grr->w) pos = grr->w; 00434 00435 gfi->compressed_len = pos; 00436 if (read_flags & GIF_READ_CONST_RECORD) { 00437 gfi->compressed = (byte *)first; 00438 gfi->free_compressed = 0; 00439 } else { 00440 gfi->compressed = Gif_NewArray(byte, gfi->compressed_len); 00441 gfi->free_compressed = Gif_DeleteArrayFunc; 00442 if (!gfi->compressed) return 0; 00443 memcpy(gfi->compressed, first, gfi->compressed_len); 00444 } 00445 00446 /* move reader over that image */ 00447 grr->v += pos; 00448 grr->w -= pos; 00449 00450 } else { 00451 /* non-record; have to read it block by block. */ 00452 u_int32_t comp_cap = 1024; 00453 u_int32_t comp_len; 00454 byte *comp = Gif_NewArray(byte, comp_cap); 00455 int i; 00456 if (!comp) return 0; 00457 00458 /* min code size */ 00459 i = gifgetbyte(grr); 00460 comp[0] = i; 00461 comp_len = 1; 00462 00463 i = gifgetbyte(grr); 00464 while (i > 0) { 00465 /* add 2 before check so we don't have to check after loop when appending 00466 0 block */ 00467 if (comp_len + i + 2 > comp_cap) { 00468 comp_cap *= 2; 00469 Gif_ReArray(comp, byte, comp_cap); 00470 if (!comp) return 0; 00471 } 00472 comp[comp_len] = i; 00473 gifgetblock(comp + comp_len + 1, i, grr); 00474 comp_len += i + 1; 00475 i = gifgetbyte(grr); 00476 } 00477 comp[comp_len++] = 0; 00478 00479 gfi->compressed = comp; 00480 gfi->compressed_len = comp_len; 00481 gfi->free_compressed = Gif_DeleteArrayFunc; 00482 } 00483 00484 return 1; 00485 } |
|
Definition at line 736 of file gifread.c. References Gif_Image::comment, Gif_Stream::comment, Gif_AddImage(), Gif_Code, GIF_DEBUG, Gif_DeleteArray, Gif_DeleteImage(), GIF_MAX_CODE, Gif_NewArray, Gif_NewImage(), Gif_NewStream(), gif_read_error(), Gif_ReadErrorHandler, gifeof, gifgetbyte, gifgetc, gifgetoffset, Gif_Context::handler, Gif_Context::handler_thunk, Gif_Image::identifier, last_name, Gif_Context::length, Gif_Stream::nimages, Gif_Context::prefix, read_application_extension(), read_comment_extension(), read_graphic_control_extension(), read_image(), read_logical_screen_descriptor(), read_unknown_extension(), Gif_Context::stream, suck_data(), Gif_Context::suffix, and u_int16_t. Referenced by Gif_FullReadFile(), and Gif_FullReadRecord().
00738 { 00739 Gif_Stream *gfs; 00740 Gif_Image *gfi; 00741 Gif_Image *new_gfi; 00742 Gif_Context gfc; 00743 int extension_position = 0; 00744 int unknown_block_type = 0; 00745 00746 if (gifgetc(grr) != 'G' || 00747 gifgetc(grr) != 'I' || 00748 gifgetc(grr) != 'F') 00749 return 0; 00750 (void)gifgetc(grr); 00751 (void)gifgetc(grr); 00752 (void)gifgetc(grr); 00753 00754 gfs = Gif_NewStream(); 00755 gfi = Gif_NewImage(); 00756 00757 gfc.stream = gfs; 00758 gfc.prefix = Gif_NewArray(Gif_Code, GIF_MAX_CODE); 00759 gfc.suffix = Gif_NewArray(byte, GIF_MAX_CODE); 00760 gfc.length = Gif_NewArray(u_int16_t, GIF_MAX_CODE); 00761 gfc.handler = handler; 00762 gfc.handler_thunk = handler_thunk; 00763 00764 if (!gfs || !gfi || !gfc.prefix || !gfc.suffix || !gfc.length) 00765 goto done; 00766 00767 GIF_DEBUG(("\nGIF")); 00768 if (!read_logical_screen_descriptor(gfs, grr)) 00769 goto done; 00770 GIF_DEBUG(("logscrdesc")); 00771 00772 while (!gifeof(grr)) { 00773 00774 byte block = gifgetbyte(grr); 00775 00776 switch (block) { 00777 00778 case ',': /* image block */ 00779 GIF_DEBUG(("imageread %d", gfs->nimages)); 00780 00781 gfi->identifier = last_name; 00782 last_name = 0; 00783 if (!read_image(grr, &gfc, gfi, read_flags) 00784 || !Gif_AddImage(gfs, gfi)) { 00785 Gif_DeleteImage(gfi); 00786 goto done; 00787 } 00788 00789 new_gfi = Gif_NewImage(); 00790 if (!new_gfi) goto done; 00791 00792 gfi = new_gfi; 00793 extension_position++; 00794 break; 00795 00796 case ';': /* terminator */ 00797 GIF_DEBUG(("term\n")); 00798 goto done; 00799 00800 case '!': /* extension */ 00801 block = gifgetbyte(grr); 00802 GIF_DEBUG(("ext(0x%02X)", block)); 00803 switch (block) { 00804 00805 case 0xF9: 00806 read_graphic_control_extension(&gfc, gfi, grr); 00807 break; 00808 00809 case 0xCE: 00810 last_name = suck_data(last_name, 0, grr); 00811 break; 00812 00813 case 0xFE: 00814 if (!read_comment_extension(gfi, grr)) goto done; 00815 break; 00816 00817 case 0xFF: 00818 read_application_extension(&gfc, gfi, extension_position, grr); 00819 break; 00820 00821 default: 00822 read_unknown_extension(gfs, block, 0, extension_position, grr); 00823 break; 00824 00825 } 00826 break; 00827 00828 default: 00829 if (!unknown_block_type) { 00830 char buf[256]; 00831 sprintf(buf, "unknown block type %d at file offset %d", block, gifgetoffset(grr) - 1); 00832 gif_read_error(&gfc, buf); 00833 unknown_block_type = 1; 00834 } 00835 break; 00836 00837 } 00838 00839 } 00840 00841 done: 00842 00843 /* Move comments after last image into stream. */ 00844 gfs->comment = gfi->comment; 00845 gfi->comment = 0; 00846 00847 Gif_DeleteImage(gfi); 00848 Gif_DeleteArray(last_name); 00849 Gif_DeleteArray(gfc.prefix); 00850 Gif_DeleteArray(gfc.suffix); 00851 Gif_DeleteArray(gfc.length); 00852 return gfs; 00853 } |
|
Definition at line 590 of file gifread.c. References Gif_Image::delay, Gif_Image::disposal, GIF_MAX_BLOCK, gif_read_error(), gifgetblock, gifgetbyte, gifgetunsigned(), packed, and Gif_Image::transparent. Referenced by read_gif().
00592 { 00593 byte len; 00594 byte crap[GIF_MAX_BLOCK]; 00595 00596 len = gifgetbyte(grr); 00597 00598 if (len == 4) { 00599 byte packed = gifgetbyte(grr); 00600 gfi->disposal = (packed >> 2) & 0x07; 00601 gfi->delay = gifgetunsigned(grr); 00602 gfi->transparent = gifgetbyte(grr); 00603 if (!(packed & 0x01)) /* transparent color doesn't exist */ 00604 gfi->transparent = -1; 00605 len -= 4; 00606 } 00607 00608 if (len > 0) { 00609 gif_read_error(gfc, "odd graphic extension format"); 00610 gifgetblock(crap, len, grr); 00611 } 00612 00613 len = gifgetbyte(grr); 00614 while (len > 0) { 00615 gif_read_error(gfc, "odd graphic extension format"); 00616 gifgetblock(crap, len, grr); 00617 len = gifgetbyte(grr); 00618 } 00619 } |
|
Definition at line 539 of file gifread.c. References Gif_Image::compressed, Gif_Image::compressed_len, GIF_DEBUG, GIF_MAX_BLOCK, GIF_READ_COMPRESSED, GIF_READ_UNCOMPRESSED, gifgetblock, gifgetbyte, gifgetunsigned(), Gif_Image::height, i, Gif_Image::interlace, Gif_Image::left, Gif_Image::local, make_data_reader(), ncol, packed, read_color_table(), read_compressed_image(), Gif_Colormap::refcount, Gif_Image::top, uncompress_image(), and Gif_Image::width. Referenced by read_gif().
00541 { 00542 byte packed; 00543 00544 gfi->left = gifgetunsigned(grr); 00545 gfi->top = gifgetunsigned(grr); 00546 gfi->width = gifgetunsigned(grr); 00547 gfi->height = gifgetunsigned(grr); 00548 packed = gifgetbyte(grr); 00549 GIF_DEBUG(("<%ux%u>", gfi->width, gfi->height)); 00550 00551 if (packed & 0x80) { /* have a local color table */ 00552 int ncol = 1 << ((packed & 0x07) + 1); 00553 gfi->local = read_color_table(ncol, grr); 00554 if (!gfi->local) return 0; 00555 gfi->local->refcount = 1; 00556 } 00557 00558 gfi->interlace = (packed & 0x40) != 0; 00559 00560 /* Keep the compressed data if asked */ 00561 if (read_flags & GIF_READ_COMPRESSED) { 00562 if (!read_compressed_image(gfi, grr, read_flags)) 00563 return 0; 00564 if (read_flags & GIF_READ_UNCOMPRESSED) { 00565 Gif_Reader new_grr; 00566 make_data_reader(&new_grr, gfi->compressed, gfi->compressed_len); 00567 if (!uncompress_image(gfc, gfi, &new_grr)) 00568 return 0; 00569 } 00570 00571 } else if (read_flags & GIF_READ_UNCOMPRESSED) { 00572 if (!uncompress_image(gfc, gfi, grr)) 00573 return 0; 00574 00575 } else { 00576 /* skip over the image */ 00577 byte buffer[GIF_MAX_BLOCK]; 00578 int i = gifgetbyte(grr); 00579 while (i > 0) { 00580 gifgetblock(buffer, i, grr); 00581 i = gifgetbyte(grr); 00582 } 00583 } 00584 00585 return 1; 00586 } |
|
Definition at line 191 of file gifread.c. References GIF_DEBUG, gifgetblock, gifgetbyte, and i. Referenced by read_image_data().
00193 { 00194 int bit_position = *bit_pos_store; 00195 int bit_length = *bit_len_store; 00196 byte block_len; 00197 00198 while (bit_position + bits_needed > bit_length) { 00199 /* Read in the next data block. */ 00200 if (bit_position >= 8) { 00201 /* Need to shift down the upper, unused part of `buffer' */ 00202 int i = bit_position / 8; 00203 buffer[0] = buffer[i]; 00204 buffer[1] = buffer[i+1]; 00205 bit_position -= i * 8; 00206 bit_length -= i * 8; 00207 } 00208 block_len = gifgetbyte(grr); 00209 GIF_DEBUG(("\nimage_block(%d)", block_len)); 00210 if (block_len == 0) return 0; 00211 gifgetblock(buffer + bit_length / 8, block_len, grr); 00212 bit_length += block_len * 8; 00213 } 00214 00215 *bit_pos_store = bit_position; 00216 *bit_len_store = bit_length; 00217 return 1; 00218 } |
|
Definition at line 222 of file gifread.c. References Gif_Context::decodepos, Gif_Code, GIF_DEBUG, GIF_MAX_BLOCK, GIF_MAX_CODE_BITS, gif_read_error(), gifgetblock, gifgetbyte, i, Gif_Context::image, Gif_Context::length, Gif_Context::maximage, one_code(), Gif_Context::prefix, read_image_block(), Gif_Context::suffix, and u_int32_t. Referenced by uncompress_image().
00223 { 00224 /* we need a bit more than GIF_MAX_BLOCK in case a single code is split 00225 across blocks */ 00226 byte buffer[GIF_MAX_BLOCK + 5]; 00227 int i; 00228 u_int32_t accum; 00229 00230 int bit_position; 00231 int bit_length; 00232 00233 Gif_Code code; 00234 Gif_Code old_code; 00235 Gif_Code clear_code; 00236 Gif_Code eoi_code; 00237 Gif_Code next_code; 00238 #define CUR_BUMP_CODE (1 << bits_needed) 00239 #define CUR_CODE_MASK ((1 << bits_needed) - 1) 00240 00241 int min_code_size; 00242 int bits_needed; 00243 00244 gfc->decodepos = 0; 00245 00246 min_code_size = gifgetbyte(grr); 00247 GIF_DEBUG(("\n\nmin_code_size(%d)", min_code_size)); 00248 if (min_code_size >= GIF_MAX_CODE_BITS) { 00249 gif_read_error(gfc, "min_code_size too big"); 00250 min_code_size = GIF_MAX_CODE_BITS - 1; 00251 } else if (min_code_size < 2) { 00252 gif_read_error(gfc, "min_code_size too small"); 00253 min_code_size = 2; 00254 } 00255 clear_code = 1 << min_code_size; 00256 for (code = 0; code < clear_code; code++) { 00257 gfc->prefix[code] = 49428; 00258 gfc->suffix[code] = (byte)code; 00259 gfc->length[code] = 1; 00260 } 00261 eoi_code = clear_code + 1; 00262 00263 next_code = eoi_code; 00264 bits_needed = min_code_size + 1; 00265 00266 code = clear_code; 00267 00268 bit_length = bit_position = 0; 00269 /* Thus the `Read in the next data block.' code below will be invoked on the 00270 first time through: exactly right! */ 00271 00272 while (1) { 00273 00274 old_code = code; 00275 00276 /* GET A CODE INTO THE `code' VARIABLE. 00277 * 00278 * 9.Dec.1998 - Rather than maintain a byte pointer and a bit offset into 00279 * the current byte (and the processing associated with that), we maintain 00280 * one number: the offset, in bits, from the beginning of `buffer'. This 00281 * much cleaner choice was inspired by Patrick J. Naughton 00282 * <naughton@wind.sun.com>'s GIF-reading code, which does the same thing. 00283 * His code distributed as part of XV in xvgif.c. */ 00284 00285 if (bit_position + bits_needed > bit_length) 00286 /* Read in the next data block. */ 00287 if (!read_image_block(grr, buffer, &bit_position, &bit_length, 00288 bits_needed)) 00289 goto zero_length_block; 00290 00291 i = bit_position / 8; 00292 accum = buffer[i] + (buffer[i+1] << 8); 00293 if (bits_needed >= 8) 00294 accum |= (buffer[i+2]) << 16; 00295 code = (Gif_Code)((accum >> (bit_position % 8)) & CUR_CODE_MASK); 00296 bit_position += bits_needed; 00297 00298 GIF_DEBUG(("%d", code)); 00299 00300 /* CHECK FOR SPECIAL OR BAD CODES: clear_code, eoi_code, or a code that is 00301 * too large. */ 00302 if (code == clear_code) { 00303 bits_needed = min_code_size + 1; 00304 next_code = eoi_code; 00305 continue; 00306 00307 } else if (code == eoi_code) 00308 break; 00309 00310 else if (code > next_code && next_code) { 00311 /* code > next_code: a (hopefully recoverable) error. 00312 00313 Bug fix, 5/27: Do this even if old_code == clear_code, and set code 00314 to 0 to prevent errors later. (If we didn't zero code, we'd later set 00315 old_code = code; then we had old_code >= next_code; so the prefixes 00316 array got all screwed up!) */ 00317 gif_read_error(gfc, "unexpected code"); 00318 code = 0; 00319 } 00320 00321 /* PROCESS THE CURRENT CODE and define the next code. If no meaningful 00322 * next code should be defined, then we have set next_code to either 00323 * `eoi_code' or `clear_code' -- so we'll store useless prefix/suffix data 00324 * in a useless place. */ 00325 00326 /* *First,* set up the prefix and length for the next code 00327 (in case code == next_code). */ 00328 gfc->prefix[next_code] = old_code; 00329 gfc->length[next_code] = gfc->length[old_code] + 1; 00330 00331 /* Use one_code to process code. It's nice that it returns the first 00332 pixel in code: that's what we need. */ 00333 gfc->suffix[next_code] = one_code(gfc, code); 00334 00335 /* Special processing if code == next_code: we didn't know code's final 00336 suffix when we called one_code, but we do now. */ 00337 if (code == next_code) 00338 gfc->image[gfc->decodepos - 1] = gfc->suffix[next_code]; 00339 00340 /* Increment next_code except for the `clear_code' special case (that's 00341 when we're reading at the end of a GIF) */ 00342 if (next_code != clear_code) { 00343 next_code++; 00344 if (next_code == CUR_BUMP_CODE) { 00345 if (bits_needed < GIF_MAX_CODE_BITS) 00346 bits_needed++; 00347 else 00348 next_code = clear_code; 00349 } 00350 } 00351 00352 } 00353 00354 /* read blocks until zero-length reached. */ 00355 i = gifgetbyte(grr); 00356 GIF_DEBUG(("\nafter_image(%d)\n", i)); 00357 while (i > 0) { 00358 gifgetblock(buffer, i, grr); 00359 i = gifgetbyte(grr); 00360 GIF_DEBUG(("\nafter_image(%d)\n", i)); 00361 } 00362 00363 /* zero-length block reached. */ 00364 zero_length_block: 00365 00366 if (gfc->image + gfc->decodepos < gfc->maximage) 00367 gif_read_error(gfc, "not enough image data for image size"); 00368 else if (gfc->image + gfc->decodepos > gfc->maximage) 00369 gif_read_error(gfc, "too much image data for image size"); 00370 } |
|
Definition at line 393 of file gifread.c. References Gif_Stream::background, gifgetbyte, gifgetunsigned(), Gif_Stream::global, ncol, packed, read_color_table(), Gif_Colormap::refcount, Gif_Stream::screen_height, and Gif_Stream::screen_width. Referenced by read_gif().
00395 { 00396 byte packed; 00397 00398 /* we don't care about logical screen width or height */ 00399 gfs->screen_width = gifgetunsigned(grr); 00400 gfs->screen_height = gifgetunsigned(grr); 00401 00402 packed = gifgetbyte(grr); 00403 gfs->background = gifgetbyte(grr); 00404 00405 /* don't care about pixel aspect ratio */ 00406 gifgetbyte(grr); 00407 00408 if (packed & 0x80) { /* have a global color table */ 00409 int ncol = 1 << ((packed & 0x07) + 1); 00410 gfs->global = read_color_table(ncol, grr); 00411 if (!gfs->global) return 0; 00412 gfs->global->refcount = 1; 00413 } 00414 00415 return 1; 00416 } |
|
Definition at line 648 of file gifread.c. References Gif_Extension::data, Gif_AddExtension(), Gif_DeleteArray, GIF_MAX_BLOCK, Gif_NewArray, Gif_NewExtension(), Gif_ReArray, gifgetblock, gifgetbyte, Gif_Extension::length, and position. Referenced by read_application_extension(), and read_gif().
00650 { 00651 byte block_len = gifgetbyte(grr); 00652 byte *data = 0; 00653 byte data_len = 0; 00654 Gif_Extension *gfex = 0; 00655 00656 while (block_len > 0) { 00657 if (data) Gif_ReArray(data, byte, data_len + block_len + 1); 00658 else data = Gif_NewArray(byte, block_len + 1); 00659 if (!data) goto done; 00660 gifgetblock(data + data_len, block_len, grr); 00661 data_len += block_len; 00662 block_len = gifgetbyte(grr); 00663 } 00664 00665 if (data) 00666 gfex = Gif_NewExtension(kind, app_name); 00667 if (gfex) { 00668 gfex->data = data; 00669 gfex->length = data_len; 00670 data[data_len] = 0; 00671 Gif_AddExtension(gfs, gfex, position); 00672 } 00673 00674 done: 00675 if (!gfex) Gif_DeleteArray(data); 00676 while (block_len > 0) { 00677 byte buffer[GIF_MAX_BLOCK]; 00678 gifgetblock(buffer, block_len, grr); 00679 block_len = gifgetbyte(grr); 00680 } 00681 return gfex != 0; 00682 } |
|
Definition at line 114 of file gifread.c. References p, u_int32_t, Gif_Reader::v, and Gif_Reader::w. Referenced by make_data_reader().
|
|
Definition at line 108 of file gifread.c. References Gif_Reader::v, and Gif_Reader::w. Referenced by make_data_reader().
|
|
Definition at line 128 of file gifread.c. References Gif_Reader::w. Referenced by make_data_reader().
00129 { 00130 return grr->w == 0; 00131 } |
|
Definition at line 122 of file gifread.c. References Gif_Reader::length, and Gif_Reader::w. Referenced by make_data_reader().
|
|
Definition at line 626 of file gifread.c. References Gif_ReArray, gifgetblock, and gifgetbyte. Referenced by read_comment_extension(), and read_gif().
00627 { 00628 byte len = gifgetbyte(grr); 00629 int total_len = 0; 00630 00631 while (len > 0) { 00632 Gif_ReArray(data, char, total_len + len + 1); 00633 if (!data) return 0; 00634 gifgetblock((byte *)data, len, grr); 00635 00636 total_len += len; 00637 data[total_len] = 0; 00638 00639 len = gifgetbyte(grr); 00640 } 00641 00642 if (store_len) *store_len = total_len; 00643 return data; 00644 } |
|
Definition at line 489 of file gifread.c. References Gif_CreateUncompressedImage(), Gif_Image::height, Gif_Context::height, Gif_Context::image, Gif_Image::image_data, Gif_Context::maximage, read_image_data(), Gif_Image::width, and Gif_Context::width. Referenced by Gif_FullUncompressImage(), and read_image().
00490 { 00491 if (!Gif_CreateUncompressedImage(gfi)) return 0; 00492 gfc->width = gfi->width; 00493 gfc->height = gfi->height; 00494 gfc->image = gfi->image_data; 00495 gfc->maximage = gfi->image_data + gfi->width * gfi->height; 00496 read_image_data(gfc, grr); 00497 return 1; 00498 } |
Variable Documentation
|
Definition at line 622 of file gifread.c. Referenced by read_gif(). |