00001
00002
00003
00004
00005 #ifndef CHARLS_ENCODERSTRATEGY
00006 #define CHARLS_ENCODERSTRATEGY
00007
00008 #include "dcmtk/ofstd/ofaptr.h"
00009 #include "procline.h"
00010 #include "decodstr.h"
00011
00012
00013
00014 class EncoderStrategy
00015 {
00016
00017 public:
00018 explicit EncoderStrategy(const JlsParameters& info) :
00019 _qdecoder(0),
00020 _info(info),
00021 _processLine(0),
00022 valcurrent(0),
00023 bitpos(0),
00024 _isFFWritten(false),
00025 _bytesWritten(0)
00026
00027 {
00028 }
00029
00030 virtual ~EncoderStrategy()
00031 {
00032 }
00033
00034 LONG PeekByte();
00035
00036 void OnLineBegin(LONG cpixel, void* ptypeBuffer, LONG pixelStride)
00037 {
00038 _processLine->NewLineRequested(ptypeBuffer, cpixel, pixelStride);
00039 }
00040
00041 void OnLineEnd(LONG , void* , LONG ) { }
00042
00043 virtual void SetPresets(const JlsCustomParameters& presets) = 0;
00044
00045 virtual size_t EncodeScan(const void* pvoid, void* pvoidOut, size_t byteCount, void* pvoidCompare) = 0;
00046
00047 protected:
00048
00049 void Init(BYTE* compressedBytes, size_t byteCount)
00050 {
00051 bitpos = 32;
00052 valcurrent = 0;
00053 _position = compressedBytes;
00054 _compressedLength = byteCount;
00055 }
00056
00057
00058 void AppendToBitStream(LONG value, LONG length)
00059 {
00060 ASSERT(length < 32 && length >= 0);
00061
00062 ASSERT((_qdecoder.get() == NULL) || (length == 0 && value == 0) ||( _qdecoder->ReadLongValue(length) == value));
00063
00064 #ifndef NDEBUG
00065 if (length < 32)
00066 {
00067 int mask = (1 << (length)) - 1;
00068 ASSERT((value | mask) == mask);
00069 }
00070 #endif
00071
00072 bitpos -= length;
00073 if (bitpos >= 0)
00074 {
00075 valcurrent = valcurrent | (value << bitpos);
00076 return;
00077 }
00078 valcurrent |= value >> -bitpos;
00079
00080 Flush();
00081
00082 ASSERT(bitpos >=0);
00083 valcurrent |= value << bitpos;
00084
00085 }
00086
00087 void EndScan()
00088 {
00089 Flush();
00090
00091
00092 if (_isFFWritten)
00093 AppendToBitStream(0, (bitpos - 1) % 8);
00094 else
00095 AppendToBitStream(0, bitpos % 8);
00096
00097 Flush();
00098 ASSERT(bitpos == 0x20);
00099 }
00100
00101 void Flush()
00102 {
00103 for (LONG i = 0; i < 4; ++i)
00104 {
00105 if (bitpos >= 32)
00106 break;
00107
00108 if (_isFFWritten)
00109 {
00110
00111 *_position = BYTE(valcurrent >> 25);
00112 valcurrent = valcurrent << 7;
00113 bitpos += 7;
00114 _isFFWritten = false;
00115 }
00116 else
00117 {
00118 *_position = BYTE(valcurrent >> 24);
00119 valcurrent = valcurrent << 8;
00120 bitpos += 8;
00121 _isFFWritten = *_position == 0xFF;
00122 }
00123
00124 _position++;
00125 _compressedLength--;
00126 _bytesWritten++;
00127
00128 }
00129
00130 }
00131
00132 size_t GetLength()
00133 {
00134 return _bytesWritten - (bitpos -32)/8;
00135 }
00136
00137
00138 inlinehint void AppendOnesToBitStream(LONG length)
00139 {
00140 AppendToBitStream((1 << length) - 1, length);
00141 }
00142
00143
00144 OFauto_ptr<DecoderStrategy> _qdecoder;
00145
00146 protected:
00147 JlsParameters _info;
00148 OFauto_ptr<ProcessLine> _processLine;
00149 private:
00150
00151 unsigned int valcurrent;
00152 LONG bitpos;
00153 size_t _compressedLength;
00154
00155
00156 BYTE* _position;
00157 bool _isFFWritten;
00158 size_t _bytesWritten;
00159
00160 };
00161
00162 #endif