xref: /haiku/src/add-ons/print/drivers/pcl6/DeltaRowCompression.h (revision be9a70562e3c6552efb0caa53bd26965e7e1bed7)
1 /*
2 ** DeltaRowCompression.h
3 ** Copyright 2005, Michael Pfeiffer, laplace@users.sourceforge.net.
4 ** All rights reserved.
5 ** Distributed under the terms of the MIT License.
6 */
7 #ifndef _DELTA_ROW_COMPRESSION_H
8 #define _DELTA_ROW_COMPRESSION_H
9 
10 
11 #include <Debug.h>
12 
13 
14 class AbstractDeltaRowCompressor {
15 public:
16 						AbstractDeltaRowCompressor(int rowSize,
17 							uchar initialSeed);
18 	virtual				~AbstractDeltaRowCompressor();
19 
20 	// InitCheck returns B_OK on successful construction of this object or
21 	// B_NO_MEMORY if the buffer for the seed row could not be allocated.
22 			status_t	InitCheck();
23 
24 	// Clears the seed row to the initial seed specified in the constructor
25 			void		Reset();
26 
27 	// Returns the size of the delta row.
28 	// The size is 0 if the row is equal to the seed row (previous row).
29 	// The seed row is updated only if updateSeedRow is true.
30 			int			CalculateSize(const uchar* row,
31 							bool updateSeedRow = false);
32 
33 	// Compresses the row using the delta row compression algorithm.
34 	// The seed row is updated.
35 			void		Compress(const uchar* row);
36 
37 protected:
38 	// append byte to delta row
39 	virtual	void		AppendByteToDeltaRow(uchar byte) = 0;
40 
41 	// returns the current size of the delta row
42 	inline	int			CurrentDeltaRowSize()
43 						{
44 							return fDeltaRowIndex;
45 						}
46 
47 private:
48 	// Returns the index where seed row and row differ
49 	// or -1 if both arrays are equal.
50 	inline	int			DiffersIndex(const uchar* row, int index)
51 						{
52 							while (index < fSize) {
53 								if (fSeedRow[index] != row[index])
54 									return index;
55 								index ++;
56 							}
57 							return -1;
58 						}
59 
60 	// Returns the number of bytes that row differs from seed row
61 	// starting at the specified index.
62 	inline	int			DiffersLength(const uchar* row, int index)
63 						{
64 							int startIndex = index;
65 							while (index < fSize) {
66 								if (fSeedRow[index] == row[index])
67 									break;
68 								index ++;
69 							}
70 							return index - startIndex;
71 						}
72 
73 	// Compresses row with delta row compression algorithm.
74 	// The seed row is updated only if updateSeedRow is true.
75 	// If updateDeltaRow is true the method AppendByteToDeltaRow is called.
76 			int 		CompressRaw(const uchar* row, bool updateSeedRow,
77 							bool updateDeltaRow);
78 
79 	// write byte to delta row and calculate size of delta row
80 			void		Put(uchar byte)
81 						{
82 							if (fUpdateDeltaRow)
83 								AppendByteToDeltaRow(byte);
84 							fDeltaRowIndex ++;
85 						}
86 
87 			uchar*		fSeedRow; // the seed row
88 			int			fSize; // the size of the seed row in bytes
89 			uchar		fInitialSeed;
90 							// the value to initialize the seed row with
91 
92 			int			fDeltaRowIndex;
93 							// the index of the next byte to be written into
94 							// the delta row
95 			bool		fUpdateDeltaRow; // write delta row
96 };
97 
98 
99 class DeltaRowCompressor : public AbstractDeltaRowCompressor
100 {
101 public:
102 						DeltaRowCompressor(int rowSize, uchar initialSeed)
103 						:
104 						AbstractDeltaRowCompressor(rowSize, initialSeed)
105 						{}
106 
107 	// The delta row to be written to.
108 			void		SetDeltaRow(uchar* deltaRow)
109 						{
110 							fDeltaRow = deltaRow;
111 						}
112 
113 protected:
114 	virtual	void		AppendByteToDeltaRow(uchar byte)
115 						{
116 							fDeltaRow[CurrentDeltaRowSize()] = byte;
117 						}
118 
119 private:
120 			uchar*		fDeltaRow; // the delta row
121 };
122 
123 #endif
124