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