.\" This file is in the public domain. .Dd December 15, 2018 .Dt LIBGIF 3 .Os NetBSD 1.4BETA .Sh NAME .Nm gifreader_open , .Nm gifreader_read , .Nm gifreader_done .Nd GIF manipulation routines .Sh SYNOPSIS .Fd #include .br .Nm cc .Op Ar arguments .Fl lgif .br .Ft GIFREADER * .Fn gifreader_open "const GIFREADER_OPS *ops" "const void *arg" "unsigned int detail" .Ft void .Fn gifreader_read "GIFREADER *reader" .Ft void .Fn gifreader_done "GIFREADER *reader" .Sh DESCRIPTION These functions are a GIF file manipulation library. Or, rather, the beginnings of one; at the moment, only reading is implemented. .Pp A GIF reader is represented by a pointer to an opaque type, .Dv GIFREADER . To create one, call .Fn gifreader_open . .Pp .Fa ops is a pointer to a .Dv GIFREADER_OPS , a typedef for a struct type with at least the following members (in some order): .Bd -literal -offset indent int (*read_input)(void *, void *, int); void (*error)(void *, int, ...); void (*detail)(void *, unsigned int, ...); .Ed .Pp As a convenience, there is a macro .Fn GIFREADER_OPS_INIT prefix which takes a name prefix and expands to something suitable as an initializer for a .Dv GIFREADER_OPS where the function names are formed by concatenating the prefix, an underscore, and the names of the .Dv GIFREADER_OPS struct members as given above. (For example, .Dl GIFREADER_OPS gr = GIFREADER_OPS_INIT(foo); will set up to use functions with names like .Fn foo_read_input and .Fn foo_error . ) See below for the semantics of these functions. .Pp .Fa arg is a generic pointer, opaque to the library, which is passed as the first argument to all of the .Dv GIFREADER_OPS functions. .Pp .Fa detail is a bitmask holding zero or more of the .Dv GIFREAD_DETAIL_ bits listed below. .Pp If .Fn gifreader_open succeeds, it returns the .Dv GIFREADER pointer; otherwise, it returns nil. .Pp Once the .Dv GIFREADER has been created, .Fn gifreader_read reads and processes the GIF file, making callbacks as appropriate. .Pp Finally, .Fn gifreader_done shuts down the .Dv GIFREADER , cleaning up all resources allocated to it. .Sh CALLBACKS The .Dv GIFREADER_OPS holds pointers to three callback functions, which are responsible for mediating all interaction between the library and its surrounding code. .Pp .Fn read_input is called to read more of the GIF file. Like all callbacks, its first argument is the opaque cookie passed to .Fn gifreader_open . The second and third arguments are a buffer pointer and length. This routine should fill the buffer with as much input data as is available, up to the amount requested, and return the fill amount, or a negative value to indicate a read error. For it to return a nonnegative value less than the requested byte count indicates that an unexpected EOF was encountered. .Pp .Fn error is called when an error occurs. Like all callbacks, its first argument is the opaque cookie passed to .Fn gifreader_open . The second argument is an error number, one of the .Dv GIFREAD_ERR_ constants detailed below. The further arguments, if any, and their semantics depend on the error number and are documented below with the error numbers. Some errors are .Sq fatal ; these errors cause .Fn gifreader_read to abort reading the file. Other errors' recovery conditions are documented below, with the errors. .Pp .Bl -tag -width indent .It GIFREAD_ERR_READERROR This call is made when the .Fn read_input callback returns a negative value. Fatal. Args: one .Li const\ char\ * , which points to a human-readable string indicating what the library was trying to read when it got the error. .It GIFREAD_ERR_UNXEOF This call is made when the .Fn read_input callback returns a non-negative value less than the requsted byte count. Fatal. Args: one .Li const\ char\ * , which points to a human-readable string indicating what the library was trying to read when it got the error. .It GIFREAD_ERR_BADSIG The beginning-of-file signature was wrong. Fatal. Args: none. If the application wants to see the actual signature, it should request .Dv GIFREAD_DETAIL_SIGNATURE (qv); such a call, with a version of .Dv GIFREAD_VERS_BAD , will be made before the .Dv GIFREAD_ERR_BADSIG call. .It GIFREAD_ERR_87a_RESERVED The screen descriptor in a GIF87a file contained nonzero values in reserved bits. Recovery: ignore the unexpected bits. Args: two ints; the first is nonzero iff the reserved 0x08 bit is set in the fifth byte of the screen descriptor; the second is nonzero iff the seventh byte is not zero. .It GIFREAD_ERR_TEXTEXT_HDRSIZE A .Sq plain text extension had a wrong-sized header block. Recovery: ignore the extension. Arg: one int, which holds the incorrect header size. The ignored extension data blocks, starting with the wrong-sized first block, can be obtained via .Dv GIFREAD_DETAIL_BROKEN_EXT . .It GIFREAD_ERR_GFXCTLEXT_HDRSIZE A .Sq graphic control extension had a wrong-sized header block. Recovery: ignore the extension. Arg: one int, which holds the incorrect header size. The ignored extension data blocks, starting with the wrong-sized first block, can be obtained via .Dv GIFREAD_DETAIL_BROKEN_EXT . .It GIFREAD_ERR_GFXCTLEXT_MBZ A .Sq graphic control extension had nonzero values in must-be-zero 0xe0 bits of the first byte of its header block. Recovery: ignore the extension. Arg: one int, which holds the incorrect first byte. The ignored extension data blocks, starting with the wrong-sized first block, can be obtained via .Dv GIFREAD_DETAIL_BROKEN_EXT . .It GIFREAD_ERR_GFXCTLEXT_BADTERM A .Sq graphic control extension had a second data block (ie, the first block after the header block was not the expected zero-length extension terminator block). Recovery: ignore the extra blocks. Arg: one int, which holds the length of the first erroneous block. The ignored extension data blocks, starting with the incorrectly nonempty block, can be obtained via .Dv GIFREAD_DETAIL_BROKEN_EXT . .It GIFREAD_ERR_GFXCTLEXT_BADDISP A .Sq graphic control extension specified an invalid disposition value. Recovery: use .Sq none specified isntead. Arg: one int, holding the unrecognized disposition value. .It GIFREAD_ERR_APPEXT_HDRSIZE An .Sq application extension had a wrong-sized header block. Recovery: ignore the extension. Arg: one int, which holds the incorrect header size. The ignored extension data blocks, starting with the wrong-sized first block, can be obtained via .Dv GIFREAD_DETAIL_BROKEN_EXT . .It GIFREAD_ERR_IMGDESC_RESERVED An image descriptor had a nonzero value in the reserved ninth byte. Recovery: ignore the unexpected value. Arg: one int, which holds the offending nonzero value. .It GIFREAD_ERR_IMGDESC_CODESIZE An image descriptor specifies a codesize value which is unexpected for the image's bits-per-pixel value. Recovery: use it anyway, even if it's unexpected. (This error call exists so applications can be aware that the file may be a bit broken.) .It GIFREAD_ERR_LZW_OVERFLOW The LZW code table overflowed. Recovery: pretend a clear code occurred and carry on. Args: none. .It GIFREAD_ERR_LZW_BAD_KWKWK The LZW KwKwK special case occurred without a previous code. Recovery: ignore the invalid codeword an carry on. Args: none. .It GIFREAD_ERR_LZW_BAD_CODE An .Sq impossible LZW code occurred (one above the current highest code). Recovery: ignore the invalid code and carry on. Args: one int, holding the invalid code. .It GIFREAD_ERR_SKIPJUNK When expecting a block start, the library encountered an octet that cannot begin a block. Recovery: skip, reading and discarding octets until a valid one is found. Args: none. .It GIFREAD_ERR_TRAILJUNK After the entire image was processed, more input was present. Recovery: read and discard the extra input. Args: none. .El .Pp .Fn detail is called to pass back non-erroneous information which the application may be interested in. Like all callbacks, its first argument is the opaque cookie passed to .Fn gifreader_open . The second argument is one of the .Dv GIFREAD_DETAIL_ bits listed below. The further arguments, if any, and their semantics depend on which detail bit is used and are documented below with the bits. Each call is made only if the corresponding bit was set in the .Fa detail argument when .Fn gifreader_open was called. .Pp .Bl -tag -width indent .It GIFREAD_DETAIL_DATAREAD Information: raw data read from the GIF data stream. Args: .Fa const unsigned char *data , .Fa int len , .Fa const char *what . .Fa data and .Fa len are pointer-and-length describing the data read; .Fa what points to a human-readable string describing what the data in questino represents (such as would have been passed to .Dv GIFREAD_ERR_READERROR or .Dv GIFREAD_ERR_UNXEOF if they had occured on this read). .It GIFREAD_DETAIL_SIGNATURE Information: file header signature. Args: .Fa const unsigned char *sig , .Fa int vers . sig is the signature itself (it always points to exactly six octets); vers is one of .Bl -tag -width indent -compact .Li GIFREAD_VERS_GIF87a The signature for GIF87a files. .Li GIFREAD_VERS_GIF89a The signature for GIF89a files. .Li GIFREAD_VERS_OTHER The .Sq GIF signature was present, but the version-number bytes after it were not recognized. .Li GIFREAD_VERS_BAD Not even the .Sq GIF signature was recognized. In this case, a .Dv GIFREAD_ERR_BADSIG error call will be made as soon as the detail call returns, and reading will be aborted. .El .It GIFREAD_DETAIL_SCRDESC Information: screen descriptor. Args: .Fa int w , .Fa int h , .Fa int m , .Fa int cr , .Fa int bp , .Fa int bg , .Fa int ar . .Ar w and .Ar h are the width and height of the screen, in pixels. .Ar m is the global colourmap type, one of .Bl -tag -width indent -compact .It GIFREAD_CMAP_NONE No colourmap is present. .It GIFREAD_CMAP_UNSORTED A colourmap is present, but it may not be sorted. .It GIFREAD_CMAP_SORTED A colourmap is present, with the colours sorted by importance, most important first. .El .Ar bp is the bits-per-pixel value (the lg of the number of the colourmap entries, if a colourmap is present). If a colourmap is present (ie, if .Ar m is not .Dv GIFREAD_CMAP_NONE ) , .Ar bg is the background colourmap entry number; ottherwise, .Ar bg Ap s value is meaningless. .Ar ar is the aspect ratio; if its value is .Dv AR , the W:H aspect ratio is .Li (AR+15):64 . .It GIFREAD_DETAIL_UNKEXT Information: unrecognized extensino number. An unknown extension was encountered. Arg: .Fa int exttype . .Fa exttype is the unrecognized one-byte extension code. See .Dv GIFREAD_DETAIL_UNKEXT_DATA for the data blocks. .It GIFREAD_DETAIL_UNKEXT_DATA Information: unrecognized extension's data block. After a .Dv GIFREAD_DETAIL_UNKEXT call, one or more GIFREAD_DETAIL_UNKEXT_DATA calls are made, carrying the data blocks for the extension. Args: .Fa const unsigned char *data , .Fa int len . .Fa data and .Fa len are of course pointer-and-length describing the data block. The list of calls is terminated with a call having .Fa data nil and .Fa len zero; one such last call is always made for each .Dv GIFREAD_DETAIL_UNKEXT call (unless a fatal error aborts the file read earlier). .It GIFREAD_DETAIL_BROKEN_EXT Information: a broken extension data block. Args: .Fa const unsigned char *data , .Fa int len . .Fa data and .Fa len are of course pointer-and-length describing the data block. This call is used to pass back the data blocks from a variety of extensions which are recognized but in some way broken; see the references to .Dv GIFREAD_DETAIL_BROKEN_EXT in the .Dv GIFREAD_ERR_ list. .It GIFREAD_DETAIL_TEXTEXT A .Sq plain text extension was encountered. Args: .Fa int gridx , .Fa int gridy , .Fa int gridw , .Fa int gridh , .Fa int ccw , .Fa int cch , .Fa int fg , .Fa int bg . .Fa gridx , .Fa gridy , .Fa gridw , and .Fa gridh are the text grid area geometry in pixels. .Fa ccw and .Fa cch are the width and height of each character cell. .Pf ( Fa ccw is expected to divide .Fa gridw and .Fa cch is expected to divide .Fa gridh ; it is up to the application to decide what to do if not.) .Fa fg and .Fa bg are the foreground and background colourmap indices (or pixel values, if no colourmap is present) for the text. The text itself is carried in data blocks; see .Dv GIFREAD_DETAIL_TEXTEXT_DATA for them. .It GIFREAD_DETAIL_TEXTEXT_DATA Information: one data block for a .Sq plain text extension. Args: .Fa const unsigned char *data , .Fa int len . .Fa data and .Fa len are of course pointer-and-length describing the data block. This call is used to pass back the data blocks containing text. The string of data blocks is terminated with one with .Fa data nil and .Fa len zero. .It GIFREAD_DETAIL_GFXCTLEXT Information: a graphic control extension. Args: .Fa int disp , .Fa int input , .Fa int delay , .Fa int transparent . .Fa disp is the desired disposition of each image after it is displayed; it can be .Bl -tag -width indent -compact .It GIFREAD_GX_DISP_NONE None specified. .It GIFREAD_GX_DISP_LEAVE Leave in place. .It GIFREAD_GX_DISP_BG Clear to the background colour. .It GIFREAD_GX_DISP_PREV Reinstate the previous image. (This option is not widely implemented.) .El .Fa input is 0 or 1. If 0, no user input is expected; if 1, user input of some sort (keystroke, mouse click, etc) should be accepted to move to the next image. (See also .Fa delay . ) .Fa delay A time delay, in milliseconds, after which the next image in the file should be delayed. If this is zero, the timeout is effectively infinity. If .Fa input is nonzero, either user input or a timeout, whichever happens first, should trigger advancing to the next image. .Fa transparent This is a colourmap index which should be interpreted as .Sq transparent , that is, pixels which would otherwise be displayed using this colourmap index should instead be left at their current colours. If no transparency is indicated by the file, this value is -1. .It GIFREAD_DETAIL_COMMEXT Information: a comment extension begins. Args: none. The actual comment data is carried in data blocks; see .Dv GIFREAD_DETAIL_COMMEXT_DATA for that. .It GIFREAD_DETAIL_COMMEXT_DATA Information: one data block for a comment extension. Args: .Fa const unsigned char *data , .Fa int len . .Fa data and .Fa len are of course pointer-and-length describing the data block. This call is used to pass back the data blocks containing whatever commentary the creating application chose to put in them. The string of data blocks is terminated with one call with .Fa data nil and .Fa len zero. .It GIFREAD_DETAIL_APPEXT Information: an .Sq application extension begins. Args: .Fa const char *app . .Fa app points to 11 bytes, the first 8 of which are the application identifier and the last 3 are the authentication code. The actual data blocks themselves are available via .Dv GIFREAD_DETAIL_APPEXT_DATA . .It GIFREAD_DETAIL_APPEXT_DATA Information: one block of data for an .Sq application extension begins. Args: .Fa const unsigned char *data , .Fa int len . .Fa data and .Fa len are of course pointer-and-length describing the data block. The string of data blocks is terminated with one call with .Fa data nil and .Fa len zero. .It GIFREAD_DETAIL_IMGDESC An image descriptor was encountered. Args: .Fa int x , .Fa int y , .Fa int w , .Fa int h , .Fa int m , .Fa int i , .Fa int b . .Fa x , .Fa y , .Fa w , and .Fa h , describe the subrectangle of the screen covered by this image. (It is an error for this rectangle to not be wholly contained within the screen; it is up to the application to decide what to do if this happens.) .Fa m describes the image-local colourmap, if any, using the same .Dv GIF_READ_CMAP_ values as for global colourmaps in the screen descriptor (above). .Fa i is 1 if the image is interlaced and 0 if not. If .Fa m is .Dv GIFREAD_CMAP_NONE , .Fa b is -1 and the image uses the global bits-per-pixel value; otherwise, .Fa b is the image's bits-per-pixel value. .It GIFREAD_DETAIL_LZW_DATA Information: a block of LZW compressed data. Args: .Fa const unsigned char *data , .Fa int len . .Fa data and .Fa len are of course pointer-and-length describing the data block. At the end of the LZW data stream, one call is made with .Fa data nil and .Fa len zero. .It GIFREAD_DETAIL_LZW_BYTES Information: one byte of data being fed into the LZW decompressor. Arg: .Fa int v . v is the data byte value. .It GIFREAD_DETAIL_LZW_CODES Information: one codeword being fed into the LZW decompressor. Arg: .Fa int c . c is the codeword. .It GIFREAD_DETAIL_PIXELS Information: one pixel output from the LZW decompressor. Arg: .Fa int p . p is the pixel value. It is up to the application to map this to an RGB triple if desired (see .Dv GIFREAD_DETAIL_CMAP ) . .It GIFREAD_DETAIL_BACKGROUND Information: background. Arg: .Fa int b . b is the background pixel value. This repeats information available from .Dv GIFREAD_DETAIL_SCRDESC and .Dv GIFREAD_DETAIL_CMAP , but more conveniently: this call is made only when there is a colourmap (because only then is the background pixel field defined to have meaning) and it is made just after the .Dv GIFREAD_DETAIL_CMAP call, when the colourmap is available to the application. This is the appropriate place to clear the screen if the application is interested in the images the file contains. .It GIFREAD_DETAIL_CMAP Information: a colourmap. Args: .Fa int gbl , .Fa int lgents , .Fa unsigned char *ents . .Fa gbl is 1 for a file-global colourmap, 0 for an image-local colourmap. .Fa lgents is the lg of the number of entries in the colourmap. .Fa ents points to the entries themselves; it points to .Po .Fa lgents Ns No \&*3 .Pc unsigned chars, organized as .Fa lgents RGB triples. .El .Pp As a convenience, there is a macro, .Dv GIFREAD_DETAIL_ALL , which expands to a bitmask including all the .Dv GIFREAD_DETAIL_ bits. .Sh BUGS The library blindly assumes .Sq byte and .Sq octet are the same thing. .Sh AUTHOR der Mouse, .Aq mouse@rodents.montreal.qc.ca .