00001
00002
00003
00004
00005 #ifndef CHARLS_DECODERSTATEGY
00006 #define CHARLS_DECODERSTATEGY
00007
00008 #include "streams.h"
00009 #include "procline.h"
00010 #include "config.h"
00011 #include "util.h"
00012
00013
00014
00015
00016
00017 class DecoderStrategy
00018 {
00019 public:
00020 DecoderStrategy(const JlsParameters& info) :
00021 _info(info),
00022 _processLine(0),
00023 _readCache(0),
00024 _validBits(0),
00025 _position(0)
00026 {
00027 }
00028
00029 virtual ~DecoderStrategy()
00030 {
00031 }
00032
00033 virtual void SetPresets(const JlsCustomParameters& presets) = 0;
00034 virtual size_t DecodeScan(void* outputData, const JlsRect& size, const void* compressedData, size_t byteCount, bool bCheck) = 0;
00035
00036 void Init(BYTE* compressedBytes, size_t byteCount)
00037 {
00038 _validBits = 0;
00039 _readCache = 0;
00040 _position = compressedBytes;
00041 _endPosition = compressedBytes + byteCount;
00042 _nextFFPosition = FindNextFF();
00043 MakeValid();
00044 }
00045
00046 inlinehint void Skip(LONG length)
00047 {
00048 _validBits -= length;
00049 _readCache = _readCache << length;
00050 }
00051
00052
00053 void OnLineBegin(LONG , void* , LONG )
00054 {}
00055
00056
00057 void OnLineEnd(LONG pixelCount, const void* ptypeBuffer, LONG pixelStride)
00058 {
00059 _processLine->NewLineDecoded(ptypeBuffer, pixelCount, pixelStride);
00060 }
00061
00062 void EndScan()
00063 {
00064 if ((*_position) != 0xFF)
00065 {
00066 ReadBit();
00067
00068 if ((*_position) != 0xFF)
00069 throw JlsException(TooMuchCompressedData);
00070 }
00071
00072 if (_readCache != 0)
00073 throw JlsException(TooMuchCompressedData);
00074 }
00075
00076
00077 inlinehint bool OptimizedRead()
00078 {
00079
00080 if (_position < _nextFFPosition - (sizeof(bufType)-1))
00081 {
00082 _readCache |= FromBigEndian<bufType>::Read(_position) >> _validBits;
00083 int bytesToRead = (bufferbits - _validBits) >> 3;
00084 _position += bytesToRead;
00085 _validBits += bytesToRead * 8;
00086 ASSERT(_validBits >= bufferbits - 8);
00087 return true;
00088 }
00089 return false;
00090 }
00091
00092 typedef size_t bufType;
00093
00094 enum {
00095 bufferbits = sizeof( bufType ) * 8
00096 };
00097
00098 void MakeValid()
00099 {
00100 ASSERT(_validBits <=bufferbits - 8);
00101
00102 if (OptimizedRead())
00103 return;
00104
00105 do
00106 {
00107 if (_position >= _endPosition)
00108 {
00109 if (_validBits <= 0)
00110 throw JlsException(InvalidCompressedData);
00111
00112 return;
00113 }
00114
00115 bufType valnew = _position[0];
00116
00117 if (valnew == 0xFF)
00118 {
00119
00120 if (_position == _endPosition - 1 || (_position[1] & 0x80) != 0)
00121 {
00122 if (_validBits <= 0)
00123 throw JlsException(InvalidCompressedData);
00124
00125 return;
00126 }
00127 }
00128
00129 _readCache |= valnew << (bufferbits - 8 - _validBits);
00130 _position += 1;
00131 _validBits += 8;
00132
00133 if (valnew == 0xFF)
00134 {
00135 _validBits--;
00136 }
00137 }
00138 while (_validBits < bufferbits - 8);
00139
00140 _nextFFPosition = FindNextFF();
00141 return;
00142
00143 }
00144
00145
00146 BYTE* FindNextFF()
00147 {
00148 BYTE* pbyteNextFF = _position;
00149
00150 while (pbyteNextFF < _endPosition)
00151 {
00152 if (*pbyteNextFF == 0xFF)
00153 {
00154 break;
00155 }
00156 pbyteNextFF++;
00157 }
00158
00159
00160 return pbyteNextFF;
00161 }
00162
00163
00164 BYTE* GetCurBytePos() const
00165 {
00166 LONG validBits = _validBits;
00167 BYTE* compressedBytes = _position;
00168
00169 for (;;)
00170 {
00171 LONG cbitLast = compressedBytes[-1] == 0xFF ? 7 : 8;
00172
00173 if (validBits < cbitLast )
00174 return compressedBytes;
00175
00176 validBits -= cbitLast;
00177 compressedBytes--;
00178 }
00179 }
00180
00181
00182 inlinehint LONG ReadValue(LONG length)
00183 {
00184 if (_validBits < length)
00185 {
00186 MakeValid();
00187 if (_validBits < length)
00188 throw JlsException(InvalidCompressedData);
00189 }
00190
00191 ASSERT(length != 0 && length <= _validBits);
00192 ASSERT(length < 32);
00193 LONG result = LONG(_readCache >> (bufferbits - length));
00194 Skip(length);
00195 return result;
00196 }
00197
00198
00199 inlinehint LONG PeekByte()
00200 {
00201 if (_validBits < 8)
00202 {
00203 MakeValid();
00204 }
00205
00206 return _readCache >> (bufferbits - 8);
00207 }
00208
00209
00210
00211 inlinehint bool ReadBit()
00212 {
00213 if (_validBits <= 0)
00214 {
00215 MakeValid();
00216 }
00217
00218 bool bSet = (_readCache & (bufType(1) << (bufferbits - 1))) != 0;
00219 Skip(1);
00220 return bSet;
00221 }
00222
00223
00224
00225 inlinehint LONG Peek0Bits()
00226 {
00227 if (_validBits < 16)
00228 {
00229 MakeValid();
00230 }
00231 bufType valTest = _readCache;
00232
00233 for (LONG count = 0; count < 16; count++)
00234 {
00235 if ((valTest & (bufType(1) << (bufferbits - 1))) != 0)
00236 return count;
00237
00238 valTest <<= 1;
00239 }
00240 return -1;
00241 }
00242
00243
00244
00245 inlinehint LONG ReadHighbits()
00246 {
00247 LONG count = Peek0Bits();
00248 if (count >= 0)
00249 {
00250 Skip(count + 1);
00251 return count;
00252 }
00253 Skip(15);
00254
00255 for (LONG highbits = 15; ; highbits++)
00256 {
00257 if (ReadBit())
00258 return highbits;
00259 }
00260 }
00261
00262
00263 LONG ReadLongValue(LONG length)
00264 {
00265 if (length <= 24)
00266 return ReadValue(length);
00267
00268 return (ReadValue(length - 24) << 24) + ReadValue(24);
00269 }
00270
00271 protected:
00272 JlsParameters _info;
00273 OFauto_ptr<ProcessLine> _processLine;
00274
00275 private:
00276
00277 bufType _readCache;
00278 LONG _validBits;
00279 BYTE* _position;
00280 BYTE* _nextFFPosition;
00281 BYTE* _endPosition;
00282 };
00283
00284
00285 #endif