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