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