XmHTML Programmers Manual: XmHTMLGIFStream Structure
Author: Koen D'Hondt

### Name

> XmHTMLGIFStream structure - XmHTML External GIF Decoder Interface Definition.

### Description

> The XmHTMLGIFStream structure is the sole argument to any function installed on the XmNdecodeGIFProc resource of a XmHTML Widget or the gif_proc field of the XmImage structure.

> This interface definition allows one to override the default GIF decoder employed by a XmHTML Widget.

> You might ask yourself: Why is this beast even present? The answer is that the image data in a GIF image is stored using the LZW (Lev-Zempel-Welch) compression method, the patent of which is owned by Unisys Corp. In order to use this algorithm (for either compression or decompression of compressed data), Unisys Corp. requires one to obtain a (costly) license. The default GIF decoded used by a XmHTML widget employs a work-around method (which involves the use of `compress(1)` or `gzip(1)`) that is a tad slower when compared with a real LZW decoder.

> The XmHTMLGIFStream structure and XmImageGifProc prototype allow holders of a LZW patent and authors of free software to surpass this workaround and hence achieve a (small to considerable) performance increase.

### Structures

    	/* Prototype for the XmNdecodeGIFProc resource */
    	typedef int (*XmImageGifProc)(XmHTMLGIFStream*);

    	/*
    	 * Possible return values for the XmNdecodeGIFProc resource and
    	 * values for the XmHTMLGIFStream state field.
    	 */

    	#define GIF_STREAM_OK		 2
    	#define GIF_STREAM_END		 1
    	#define GIF_STREAM_ERR		 0
    	#define GIF_STREAM_INIT		-1
    	#define GIF_STREAM_FINAL	-2

    	/* XmHTMLGIFStream definition */

    	typedef struct _XmHTMLGIFStream{
    	    /* read-only fields */
    	    int state;                  /* decoder state                        */
    	    int codesize;               /* initial LZW codesize                 */
    	    Boolean is_progressive;     /* when used by a progressive loader    */
    	    unsigned char *next_in;     /* next input byte                      */
    	    Cardinal avail_in;          /* number of bytes available at next_in */
    	    Cardinal total_in;          /* total nb of input bytes read so far  */

    	    /* fields to be updated by caller */
    	    unsigned char *next_out;    /* next output byte should be put here  */
    	    Cardinal avail_out;         /* remaining free space at next_out     */
    	    Cardinal total_out;         /* total nb of bytes outputted so far   */

    	    String msg;                 /* last error message, or NULL          */
    	    XtPointer external_state;   /* room for decoder-specific data       */
    	}XmHTMLGIFStream;

### Examples

> Shown below is a typical example of a custom GIF decoder that demonstrates the proper use of the XmHTMLGIFStream structure.

    	int decodeGIF(XmHTMLGIFStream *gstream)
    	{
    	    int v;
    	    unsigned char *dp;

    	    /* XmHTML is initializing itself */
    	    if(gstream->state == GIF_STREAM_INIT )
    	    {
    	        gstream->external_state = some_LZW_init_func(gstream->codesize);
    	        /* and return OK */
    	        return(GIF_STREAM_OK);
    	    }

    	    /* end-of-data ? */
    	    if(gstream->state == GIF_STREAM_FINAL ||
    	        gstream->state == GIF_STREAM_END )
    	    {
    	        some_LZW_cleanup_func(gstream->external_state);
    	        return(GIF_STREAM_END);
    	    }

    	    /* current position in decoded output buffer */
    	    dp = gstream->next_out;

    	    for( ; gstream->avail_out ; gstream->total_out++,
    	        gstream->avail_out-- )
    	    {
    	        if((v = some_LZW_decoder_func(gstream->external_state))
    	            < some_valid_value)
    	        {
    	            if(v == some_end_of_data_signal)
    	                return(GIF_STREAM_END);
    	            /* processed all current data */
    	            return(GIF_STREAM_OK);
    	        }
    	        *dp++ = v;
    	    }
    	    /* end if we run out of data */
    	    return(gstream->avail_out ? GIF_STREAM_OK : GIF_STREAM_END);
    	}

### Disclaimer

> `THIS INFORMATION IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND. THE AUTHOR SHALL HAVE NO LIABILITY WITH RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE OR ANY PART THEREOF. IN NO EVENT WILL THE AUTHOR BE LIABLE FOR ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL DAMAGES.`

> `IF YOU DECIDE TO USE THE INFORMATION CONTAINED IN THIS FILE TO CONSTRUCT AND USE THE LZW ALGORITHM YOU AGREE TO ACCEPT FULL RESPONSIBILITY WITH RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRECTS OR ANY PATENTS. IN NO EVENT WILL THE AUTHOR BE LIABLE FOR ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL DAMAGES, INCLUDING BUT NOT LIMITED TO ANY DAMAGES RESULTING FROM ANY ACTIONS IN A COURT OF LAW.`

> `YOU ARE HEREBY WARNED THAT USE OF THE LZW ALGORITHM WITHOUT HAVING OBTAINED A PROPER LICENSE FROM UNISYS CONSTITUTES A VIOLATION OF APPLICABLE PATENT LAW. AS SUCH YOU WILL BE HELD LEGALLY RESPONSIBLE FOR ANY INFRINGEMENT OF THE UNISYS LZW PATENT.`

> `UNISYS REQUIRES YOU TO HAVE A LZW LICENSE FOR EVERY TASK IN WHICH THE LZW ALGORITHM IS BEING USED (WHICH INCLUDES DECODING THE LZW COMPRESSED RASTER DATA AS FOUND IN GIF IMAGES). THE FACT THAT YOUR APPLICATION MAY OR MAY NOT BE DISTRIBUTED AS SHAREWARE IS OF NO CONCERN TO UNISYS.`

> `IF YOU RESIDE IN A COUNTRY WHERE SOFTWARE PATENT LAWS DO NOT APPLY, PLEASE BE WARNED THAT EXPORTING SOFTWARE CONTAINING THE LZW ALGORITHM TO COUNTRIES WHERE SOFTWARE PATENT LAW *DOES* APPLY WITHOUT A VALID LICENSE ALSO CONSTITUTES A VIOLATION OF PATENT LAW IN THE COUNTRY OF DESTINATION.`

> The Unisys Corporation Licensing Department can be contacted at lzw_info@unisys.com.

### See Also

> XmHTML(3X), XmImage(3X), U.S. Patent 4,558,302

XmHTML, October 7, 1997