00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef DCRLEDEC_H
00030 #define DCRLEDEC_H
00031
00032 #include "dcmtk/config/osconfig.h"
00033 #include "dcmtk/dcmdata/dcerror.h"
00034
00038 class DcmRLEDecoder
00039 {
00040 public:
00041
00046 DcmRLEDecoder(size_t outputBufferSize)
00047 : fail_(0)
00048 , outputBufferSize_(outputBufferSize)
00049 , outputBuffer_(NULL)
00050 , offset_(0)
00051 , suspendInfo_(128)
00052 {
00053 if (outputBufferSize_ == 0) fail_ = 1;
00054 else
00055 {
00056 outputBuffer_ = new unsigned char[outputBufferSize_];
00057 if (outputBuffer_ == NULL) fail_ = 1;
00058 }
00059 }
00060
00062 ~DcmRLEDecoder()
00063 {
00064 delete[] outputBuffer_;
00065 }
00066
00070 inline void clear()
00071 {
00072 offset_ = 0;
00073 suspendInfo_ = 128;
00074 if (outputBuffer_) fail_ = 0;
00075 }
00076
00077
00078 inline OFCondition decompress(void *compressedData, size_t compressedSize)
00079 {
00080
00081 if (compressedSize == 0) return EC_Normal;
00082
00083 OFCondition result = EC_IllegalCall;
00084
00085
00086 if (compressedData == NULL) fail_ = 1;
00087
00088 if (! fail_)
00089 {
00090 result = EC_Normal;
00091 unsigned char ch;
00092 unsigned char nbytes;
00093 unsigned char *cp = OFstatic_cast(unsigned char *, compressedData);
00094
00095
00096 if (suspendInfo_ > 128)
00097 {
00098
00099 nbytes = OFstatic_cast(unsigned char, 257 - suspendInfo_);
00100
00101
00102 suspendInfo_ = 128;
00103
00104 ch = *cp++;
00105 --compressedSize;
00106 replicate(ch, nbytes);
00107 }
00108 else if (suspendInfo_ < 128)
00109 {
00110
00111 nbytes = OFstatic_cast(unsigned char, (suspendInfo_ & 0x7f) + 1);
00112 suspendInfo_ = 128;
00113 if (compressedSize < nbytes)
00114 {
00115
00116 suspendInfo_ = OFstatic_cast(unsigned char, nbytes - compressedSize - 1);
00117 nbytes = OFstatic_cast(unsigned char, compressedSize);
00118 result = EC_StreamNotifyClient;
00119 }
00120
00121 literal(cp, nbytes);
00122 compressedSize -= nbytes;
00123 cp += nbytes;
00124 }
00125
00126
00127 while (compressedSize && (! fail_))
00128 {
00129 ch = *cp++;
00130 --compressedSize;
00131
00132 if (ch & 0x80)
00133 {
00134
00135 if (compressedSize)
00136 {
00137
00138 nbytes = OFstatic_cast(unsigned char, 257 - ch);
00139 ch = *cp++;
00140 --compressedSize;
00141 replicate(ch, nbytes);
00142 }
00143 else
00144 {
00145
00146 suspendInfo_ = ch;
00147 result = EC_StreamNotifyClient;
00148 }
00149 }
00150 else
00151 {
00152
00153 nbytes = OFstatic_cast(unsigned char, (ch & 0x7f) + 1);
00154 if (compressedSize < nbytes)
00155 {
00156
00157 suspendInfo_ = OFstatic_cast(unsigned char, nbytes - compressedSize - 1);
00158 nbytes = OFstatic_cast(unsigned char, compressedSize);
00159 result = EC_StreamNotifyClient;
00160 }
00161
00162 literal(cp, nbytes);
00163 compressedSize -= nbytes;
00164 cp += nbytes;
00165 }
00166 }
00167
00168
00169 if (fail_) result = EC_CorruptedData;
00170 }
00171
00172 return result;
00173 }
00174
00175
00179 inline size_t size() const
00180 {
00181 return offset_;
00182 }
00183
00186 inline void *getOutputBuffer() const
00187 {
00188 return outputBuffer_;
00189 }
00190
00193 inline OFBool fail() const
00194 {
00195 if (fail_) return OFTrue; else return OFFalse;
00196 }
00197
00198 private:
00199
00201 DcmRLEDecoder(const DcmRLEDecoder&);
00202
00204 DcmRLEDecoder& operator=(const DcmRLEDecoder&);
00205
00206
00211 inline void replicate(unsigned char ch, unsigned char nbytes)
00212 {
00213 if (offset_ + nbytes > outputBufferSize_)
00214 {
00215
00216 fail_ = 1;
00217 nbytes = OFstatic_cast(unsigned char, outputBufferSize_ - offset_);
00218 }
00219
00220 while (nbytes--) outputBuffer_[offset_++] = ch;
00221 }
00222
00223
00228 inline void literal(unsigned char *cp, unsigned char nbytes)
00229 {
00230 if (offset_ + nbytes > outputBufferSize_)
00231 {
00232
00233 fail_ = 1;
00234 nbytes = OFstatic_cast(unsigned char, outputBufferSize_ - offset_);
00235 }
00236
00237 while (nbytes--) outputBuffer_[offset_++] = *cp++;
00238 }
00239
00240
00241
00246 int fail_;
00247
00250 size_t outputBufferSize_;
00251
00256 unsigned char *outputBuffer_;
00257
00261 size_t offset_;
00262
00268 unsigned char suspendInfo_;
00269 };
00270
00271 #endif
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296