Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

gifread.c File Reference

#include "gif.h"
#include <stdarg.h>
#include <assert.h>
#include <string.h>

Go to the source code of this file.


Data Structures

struct  Gif_Context
struct  Gif_Reader

Defines

#define inline
#define gifgetc(grr)   ((char)(*grr->byte_getter)(grr))
#define gifgetbyte(grr)   ((*grr->byte_getter)(grr))
#define gifgetblock(ptr, size, grr)   ((*grr->block_getter)(ptr, size, grr))
#define gifgetoffset(grr)   ((*grr->offseter)(grr))
#define gifeof(grr)   ((*grr->eofer)(grr))
#define CUR_BUMP_CODE   (1 << bits_needed)
#define CUR_CODE_MASK   ((1 << bits_needed) - 1)

Typedefs

typedef Gif_Reader Gif_Reader

Functions

u_int16_t gifgetunsigned (Gif_Reader *grr)
byte file_byte_getter (Gif_Reader *grr)
void file_block_getter (byte *p, u_int32_t s, Gif_Reader *grr)
u_int32_t file_offseter (Gif_Reader *grr)
int file_eofer (Gif_Reader *grr)
byte record_byte_getter (Gif_Reader *grr)
void record_block_getter (byte *p, u_int32_t s, Gif_Reader *grr)
u_int32_t record_offseter (Gif_Reader *grr)
int record_eofer (Gif_Reader *grr)
void make_data_reader (Gif_Reader *grr, const byte *data, u_int32_t length)
void gif_read_error (Gif_Context *gfc, const char *error)
byte one_code (Gif_Context *gfc, Gif_Code code)
int read_image_block (Gif_Reader *grr, byte *buffer, int *bit_pos_store, int *bit_len_store, int bits_needed)
void read_image_data (Gif_Context *gfc, Gif_Reader *grr)
Gif_Colormapread_color_table (int size, Gif_Reader *grr)
int read_logical_screen_descriptor (Gif_Stream *gfs, Gif_Reader *grr)
int read_compressed_image (Gif_Image *gfi, Gif_Reader *grr, int read_flags)
int uncompress_image (Gif_Context *gfc, Gif_Image *gfi, Gif_Reader *grr)
int Gif_FullUncompressImage (Gif_Image *gfi, Gif_ReadErrorHandler h, void *hthunk)
int read_image (Gif_Reader *grr, Gif_Context *gfc, Gif_Image *gfi, int read_flags)
void read_graphic_control_extension (Gif_Context *gfc, Gif_Image *gfi, Gif_Reader *grr)
char * suck_data (char *data, int *store_len, Gif_Reader *grr)
int read_unknown_extension (Gif_Stream *gfs, int kind, char *app_name, int position, Gif_Reader *grr)
int read_application_extension (Gif_Context *gfc, Gif_Image *gfi, int position, Gif_Reader *grr)
int read_comment_extension (Gif_Image *gfi, Gif_Reader *grr)
Gif_Streamread_gif (Gif_Reader *grr, int read_flags, Gif_ReadErrorHandler handler, void *handler_thunk)
Gif_StreamGif_FullReadFile (FILE *f, int read_flags, Gif_ReadErrorHandler h, void *hthunk)
Gif_StreamGif_FullReadRecord (const Gif_Record *gifrec, int read_flags, Gif_ReadErrorHandler h, void *hthunk)
Gif_StreamGif_ReadFile (FILE *f)
Gif_StreamGif_ReadRecord (const Gif_Record *gifrec)

Variables

char * last_name

Define Documentation

#define CUR_BUMP_CODE   (1 << bits_needed)
 

#define CUR_CODE_MASK   ((1 << bits_needed) - 1)
 

#define gifeof grr       ((*grr->eofer)(grr))
 

Definition at line 70 of file gifread.c.

Referenced by read_gif().

#define gifgetblock ptr,
size,
grr       ((*grr->block_getter)(ptr, size, grr))
 

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().

#define gifgetbyte grr       ((*grr->byte_getter)(grr))
 

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().

#define gifgetc grr       ((char)(*grr->byte_getter)(grr))
 

Definition at line 66 of file gifread.c.

Referenced by read_gif().

#define gifgetoffset grr       ((*grr->offseter)(grr))
 

Definition at line 69 of file gifread.c.

Referenced by read_gif().

#define inline
 

Definition at line 18 of file gifread.c.


Typedef Documentation

typedef struct Gif_Reader Gif_Reader
 


Function Documentation

void file_block_getter byte   p,
u_int32_t    s,
Gif_Reader   grr
[static]
 

Definition at line 89 of file gifread.c.

References Gif_Reader::f, p, and u_int32_t.

Referenced by Gif_FullReadFile().

00090 {
00091   fread(p, 1, s, grr->f);
00092 }

byte file_byte_getter Gif_Reader   grr [static]
 

Definition at line 82 of file gifread.c.

References Gif_Reader::f, and i.

Referenced by Gif_FullReadFile().

00083 {
00084   int i = getc(grr->f);
00085   return i == EOF ? 0 : (byte)i;
00086 }

int file_eofer Gif_Reader   grr [static]
 

Definition at line 101 of file gifread.c.

References Gif_Reader::f.

Referenced by Gif_FullReadFile().

00102 {
00103   return feof(grr->f);
00104 }

u_int32_t file_offseter Gif_Reader   grr [static]
 

Definition at line 95 of file gifread.c.

References Gif_Reader::f.

Referenced by Gif_FullReadFile().

00096 {
00097   return ftell(grr->f);
00098 }

Gif_Stream* Gif_FullReadFile FILE *    f,
int    read_flags,
Gif_ReadErrorHandler    h,
void *    hthunk
 

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 }

Gif_Stream* Gif_FullReadRecord const Gif_Record   gifrec,
int    read_flags,
Gif_ReadErrorHandler    h,
void *    hthunk
 

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 }

int Gif_FullUncompressImage Gif_Image   gfi,
Gif_ReadErrorHandler    h,
void *    hthunk
 

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 }

void gif_read_error Gif_Context   gfc,
const char *    error
[static]
 

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().

00150 {
00151   gfc->stream->errors++;
00152   if (gfc->handler)
00153     gfc->handler(error, gfc->stream->nimages, gfc->handler_thunk);
00154 }

Gif_Stream* Gif_ReadFile FILE *    f
 

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 }

Gif_Stream* Gif_ReadRecord const Gif_Record   gifrec
 

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 }

u_int16_t gifgetunsigned Gif_Reader   grr [inline, static]
 

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 }

void make_data_reader Gif_Reader   grr,
const byte   data,
u_int32_t    length
[static]
 

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 }

byte one_code Gif_Context   gfc,
Gif_Code    code
[static]
 

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 }

int read_application_extension Gif_Context   gfc,
Gif_Image   gfi,
int    position,
Gif_Reader   grr
[static]
 

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 }

Gif_Colormap* read_color_table int    size,
Gif_Reader   grr
[static]
 

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 }

int read_comment_extension Gif_Image   gfi,
Gif_Reader   grr
[static]
 

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 }

int read_compressed_image Gif_Image   gfi,
Gif_Reader   grr,
int    read_flags
[static]
 

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 }

Gif_Stream* read_gif Gif_Reader   grr,
int    read_flags,
Gif_ReadErrorHandler    handler,
void *    handler_thunk
[static]
 

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 }

void read_graphic_control_extension Gif_Context   gfc,
Gif_Image   gfi,
Gif_Reader   grr
[static]
 

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 }

int read_image Gif_Reader   grr,
Gif_Context   gfc,
Gif_Image   gfi,
int    read_flags
[static]
 

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 }

int read_image_block Gif_Reader   grr,
byte   buffer,
int *    bit_pos_store,
int *    bit_len_store,
int    bits_needed
[static]
 

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 }

void read_image_data Gif_Context   gfc,
Gif_Reader   grr
[static]
 

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 }

int read_logical_screen_descriptor Gif_Stream   gfs,
Gif_Reader   grr
[static]
 

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 }

int read_unknown_extension Gif_Stream   gfs,
int    kind,
char *    app_name,
int    position,
Gif_Reader   grr
[static]
 

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 }

void record_block_getter byte   p,
u_int32_t    s,
Gif_Reader   grr
[static]
 

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().

00115 {
00116   if (s > grr->w) s = grr->w;
00117   memcpy(p, grr->v, s);
00118   grr->w -= s, grr->v += s;
00119 }

byte record_byte_getter Gif_Reader   grr [static]
 

Definition at line 108 of file gifread.c.

References Gif_Reader::v, and Gif_Reader::w.

Referenced by make_data_reader().

00109 {
00110   return grr->w ? (grr->w--, *grr->v++) : 0;
00111 }

int record_eofer Gif_Reader   grr [static]
 

Definition at line 128 of file gifread.c.

References Gif_Reader::w.

Referenced by make_data_reader().

00129 {
00130   return grr->w == 0;
00131 }

u_int32_t record_offseter Gif_Reader   grr [static]
 

Definition at line 122 of file gifread.c.

References Gif_Reader::length, and Gif_Reader::w.

Referenced by make_data_reader().

00123 {
00124   return grr->length - grr->w;
00125 }

char* suck_data char *    data,
int *    store_len,
Gif_Reader   grr
[static]
 

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 }

int uncompress_image Gif_Context   gfc,
Gif_Image   gfi,
Gif_Reader   grr
[static]
 

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

char* last_name [static]
 

Definition at line 622 of file gifread.c.

Referenced by read_gif().

 

Powered by Plone

This site conforms to the following standards: