home *** CD-ROM | disk | FTP | other *** search
- /* lzwsrch.c
- * fast search of LZW tables for encoding
- * author: J.F.R. "Frank" Slinkman, 72411,650
- * last update: 10-May-92
- * compiler: Pro-MC
- * released to the public domain
- *=============================================================================
- * lzw_search() is invoked as follows:
- *
- * lzw_search( &bgn_srch, &num_2_srch );
- *
- * where: bgn_srch is the number of the pfx_lsb[] element to search first;
- * num_2_srch is the number of elements to be searched.
- *=============================================================================
- * initially, num_2_srch will be zero, and bgn_srch will be number of root
- * values + 2.
- *
- * if prefix-suffix found in table, function returns slot number where found
- * and updates bgn_srch and num_2_srch for next invocation.
- *
- * if prefix_suffix not found, function returns -1, and updates bgn_srch
- * and num_2_srch for next invocation.
- *
- * if table full, function returns -2, and re-initializes bgn_srch and
- * num_2_srch to zero and the number of root values + 2, respectively.
- *=============================================================================
- * globals */
-
- char pfx_lsb[4096]; /* portion of LZW table holding prefix lsbs */
- char pfx_msb[4096]; /* " " " " " " msbs */
- char sfx_lsb[4096]; /* " " " " " suffix lsbs */
- int prefix, suffix;
- int num_roots; /* init this value to number of root values + 2 */
- /*===========================================================================*/
-
- int lzw_search( bgn_srch, num_2_srch )
- int *bgn_srch, *num_2_srch;
- {
- int next_slot, tst_slot, slot, count;
- char lsb, msb, sfx;
- unsigned int base = &pfx_lsb[0] - 1;
-
- slot = tst_slot = *bgn_srch;
- count = *num_2_srch;
- next_slot = *bgn_srch + *num_2_srch;
-
- lsb = prefix;
- msb = prefix >> 8;
- sfx = suffix;
-
- /* Note: some compilers may require the above three lines to be written:
- *
- * lsb = prefix & 0xff;
- * msb = prefix & 0xff00 >> 8;
- * sfx = suffix & 0xff;
- */
-
- if ( count > 0 )
- { do
- { slot = tst_slot = memchr( &pfx_lsb[tst_slot], lsb, count ) - base;
- count = next_slot - slot;
- --slot;
- }
- while ( ( slot >= 0 )
- && ( pfx_msb[slot] != msb )
- && ( sfx_lsb[slot] != sfx )
- && ( count > 0 ) );
- }
-
- /* string was found if slot >= 0
- * if found, update bgn_srch and num_2_srch and return slot number */
-
- if ( slot >= 0 )
- { *bgn_srch = tst_slot;
- *num_2_srch = count;
- return slot;
- }
-
- /* if num_2_srch was 0 or if tst_slot < 0, see if table full
- * if full, update bgn_srch and num_2_srch and return -2 */
-
- if ( *bgn_srch == 4096 )
- { *bgn_srch = num_roots;
- *num_2_srch = 0;
- return -2;
- }
-
- /* if string not found and table not full, write string to table,
- * update bgn_srch and num_2_srch, and return -1 */
-
- pfx_lsb[next_slot] = lsb;
- pfx_msb[next_slot] = msb;
- sfx_lsb[next_slot] = sfx;
- *bgn_srch = num_roots;
- *num_2_srch = next_slot - num_roots + 1;
- return -1;
- }