/* * convert.c -- uncompressed GIF image data encoder * * Copyright (c) 1995-1997 by nir@mxa.meshnet.or.jp * * This file is part of npc.cgi source tree. * npc.cgi is free software; you can redistribute it and/or modify it * for any purpose. * * @(#)$Id: convert.c,v 1.4 1997/12/11 14:03:48 nir Rel $ */ /* * $Log: convert.c,v $ * Revision 1.4 1997/12/11 14:03:48 nir * To avoid infringement of the LZW Unisys patent, dispose compression * routine and use uncompressed data encoder. * * Revision 1.3 1997/11/05 11:45:38 nir * Add Copyright, Id and Log. * */ #include "npc.h" #define BITS 12 #define MAXCODE(n_bits) (1 << (n_bits)) #define MAXMAXCODE MAXCODE(BITS) INTERN void put_code(unsigned int w); INTERN void write_code_buf(unsigned int bits_len); INTERN void put_clear(void); INTERN short clear, eoinf, first; INTERN unsigned char buf[258]; INTERN unsigned char *code_buf_base; INTERN unsigned char *code_buf; INTERN unsigned int bit_offset; INTERN unsigned int n_bits; INTERN unsigned int min_n_bits; INTERN short maxcode; INTERN short next_w; int convert(unsigned int min_code_size, unsigned char *pixel, unsigned int len) { if (len <= 0) return(BAD); code_buf_base = buf; code_buf = buf + 1; clear = 1 << min_code_size; eoinf = clear + 1; first = clear + 2; n_bits = min_n_bits = min_code_size + 1; bit_offset = 0; code_buf[0] = 0; put_clear(); while (len-- > 0) { put_code(*(pixel++)); if (next_w >= MAXMAXCODE) { put_clear(); } else if (++next_w > maxcode) { maxcode = MAXCODE(++n_bits); } } put_code(eoinf); write_code_buf(bit_offset); gputc(0); /* end of sub-block */ return(0); } INTERN void put_code(unsigned int w) { unsigned int r_pos, r_off; r_pos = bit_offset / 8; r_off = bit_offset % 8; code_buf[r_pos] |= (unsigned char)(w << r_off); code_buf[r_pos + 1] = (unsigned char)(w >> (8 - r_off)); code_buf[r_pos + 2] = (unsigned char)0; bit_offset += n_bits; if (bit_offset < 255 * 8) return; write_code_buf(255 * 8); code_buf[0] = code_buf[255]; code_buf[1] = code_buf[256]; bit_offset -= 255 * 8; } INTERN void write_code_buf(unsigned int bits_len) { unsigned int len; if ((len = (bits_len + 7) / 8) == 0) return; *code_buf_base = (unsigned char)len; gwrite(code_buf_base, len + 1); } INTERN void put_clear(void) { put_code(clear); maxcode = MAXCODE(n_bits = min_n_bits); next_w = first; }