source: golgotha/src/i4/compress/rle.hh @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 2.0 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#ifndef I4_RLE_HH
10#define I4_RLE_HH
11
12#include "file/file.hh"
13
14template <class T>
15class i4_rle_class
16{
17  T last_value;
18  T raw[256];
19  int run_count;
20  int raw_count;
21  i4_file_class *fp;
22 
23public:
24  i4_rle_class(i4_file_class *fp) : fp(fp)
25  {
26    run_count=0;
27    raw_count=0;
28  }
29
30  void flush()
31  {
32    if (run_count)
33    {
34      fp->write_8(run_count);
35      *fp << last_value;
36      run_count=0;
37    }
38    else if (raw_count)
39    {
40      fp->write_8(128 | raw_count);
41      for (int i=0; i<raw_count; i++)
42        *fp << raw[i];
43      raw_count=0;
44    }
45  }
46
47  void write(T v)
48  {
49    if (run_count)
50    {
51      if (last_value==v && run_count!=127)
52        run_count++;
53      else
54      {
55        flush();
56        raw_count=1;
57        raw[0]=v;
58      }       
59    }
60    else if (raw_count>1 && raw[raw_count-1]==raw[raw_count-2] && raw[raw_count-1]==v)
61    {
62      raw_count-=2;
63      run_count=0;
64      flush();
65      run_count=3;
66      last_value=v;
67    }
68    else
69    {
70      if (raw_count==127) flush();
71      raw[raw_count++]=v;
72    }   
73  }
74
75  T read()
76  {
77    if (run_count)
78    {
79      run_count--;
80      return last_value;
81    }
82    else if (raw_count)
83    {
84      raw_count--;
85      T ret;
86      *fp >> ret;
87      return ret;
88    }
89    else
90    {
91      int v=fp->read_8();
92      if (v&128)
93      {
94        raw_count=v&(~128);
95      }
96      else
97      {
98        run_count=v;
99        *fp >> last_value;
100      }
101      return read();
102    }
103  }
104
105  ~i4_rle_class() { flush(); }
106};
107
108#endif
Note: See TracBrowser for help on using the repository browser.