Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

src/huffman.c

Go to the documentation of this file.
00001 /* {{{
00002  * CalcRogue, a roguelike game for PCs, calculators and PDAs
00003  * Copyright (C) 2003 Jim Babcock
00004  * 
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018  * }}} */
00019 // huffman.c
00024 
00025 #ifdef TARGET // Compiling CalcRogue (not a tool)
00026 #include "crogue.h"
00027 #endif
00028 
00029 #include "hufftable.h"
00030 #include "huffman.h"
00031 #include "substdio.h"
00032 
00033 #ifdef DISABLE_COMPRESSION
00034 #define DISABLE_HUFFMAN
00035 #endif
00036 
00037 static unsigned long _hp_pending=0;
00038 static unsigned short _hp_pending_length=0;
00039 
00040 void fhuffmaninit_write(void)
00041 {
00042     _hp_pending = 0;
00043     _hp_pending_length = 0;
00044 }
00045 
00046 void fhuffmanputc(unsigned char c, FILE *f)
00047 {
00048 #ifdef DISABLE_HUFFMAN
00049     fputc(c, f);
00050 #else
00051     
00052     _hp_pending_length += huff_compress.replen[c];
00053     _hp_pending |= (long)huff_compress.rep[c] << (32L - _hp_pending_length);
00054     if(_hp_pending_length >= 16)
00055         fhuffmanflush(f);
00056 #endif
00057 }
00058 
00059 void fhuffmanflush(FILE *f)
00060 {
00061 #ifndef DISABLE_HUFFMAN
00062     fputc((char)(_hp_pending>>24L), f);
00063     fputc((char)(_hp_pending>>16L), f);
00064     _hp_pending <<= 16;
00065     if(_hp_pending_length >= 16)
00066         _hp_pending_length -= 16;
00067     else
00068         _hp_pending_length = 0;
00069 #endif
00070 }
00071 
00072 static unsigned long _hg_pending=0;
00073 static unsigned short _hg_pending_length=0;
00074 
00075 void fhuffmaninit_read(void)
00076 {
00077     _hg_pending = 0;
00078     _hg_pending_length = 0;
00079 }
00080 
00081 char fhuffmangetc(FILE *f)
00082 {
00083 #ifdef DISABLE_HUFFMAN
00084     return fgetc(f);
00085 #else
00086     short high, low, mid;
00087     unsigned short searchtarget;
00088     
00089     while(_hg_pending_length < 24)
00090     {
00091         _hg_pending <<= 8;
00092         _hg_pending_length += 8;
00093         if(!feof(f))
00094             _hg_pending |= fgetc(f);
00095     }
00096     searchtarget = _hg_pending >> (_hg_pending_length - 16UL);
00097     low = 0;
00098     high = 255;
00099     
00100     do
00101     {
00102         mid = (low+high+1)/2;
00103         if(huff_decompress.entries[mid].binrep > searchtarget)
00104             high = mid-1;
00105         else
00106             low = mid;
00107     } while(high>low);
00108     
00109     
00110     _hg_pending <<= (32L + huff_decompress.entries[low].binreplen - _hg_pending_length);
00111     _hg_pending_length -= huff_decompress.entries[low].binreplen;
00112     _hg_pending >>= (32L - _hg_pending_length);
00113     
00114     return huff_decompress.entries[low].byterep;
00115 #endif
00116 }
00117 
00118 

Generated on Thu May 20 13:12:09 2004 for CalcRogue by doxygen 1.3.6