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
00030
00031
00032
00033
00034
#ifndef DCRLEDEC_H
00035
#define DCRLEDEC_H
00036
00037
#include "osconfig.h"
00038
#include "dcerror.h"
00039
00043 class DcmRLEDecoder
00044 {
00045
public:
00046
00051 DcmRLEDecoder(size_t outputBufferSize)
00052 :
fail_(0)
00053 ,
outputBufferSize_(outputBufferSize)
00054 ,
outputBuffer_(NULL)
00055 ,
offset_(0)
00056 ,
suspendInfo_(128)
00057 {
00058
if (
outputBufferSize_ == 0)
fail_ = 1;
00059
else
00060 {
00061
outputBuffer_ =
new unsigned char[
outputBufferSize_];
00062
if (
outputBuffer_ == NULL)
fail_ = 1;
00063 }
00064 }
00065
00067 ~DcmRLEDecoder()
00068 {
00069
delete[]
outputBuffer_;
00070 }
00071
00075 inline void clear()
00076 {
00077
offset_ = 0;
00078
suspendInfo_ = 128;
00079
if (
outputBuffer_)
fail_ = 0;
00080 }
00081
00082
00083
inline OFCondition decompress(
void *compressedData, size_t compressedSize)
00084 {
00085
00086
if (compressedSize == 0)
return EC_Normal;
00087
00088
OFCondition result = EC_IllegalCall;
00089
00090
00091
if (compressedData == NULL) fail_ = 1;
00092
00093
if (! fail_)
00094 {
00095 result = EC_Normal;
00096
unsigned char ch;
00097
unsigned char nbytes;
00098
unsigned char *cp = OFstatic_cast(
unsigned char *, compressedData);
00099
00100
00101
if (suspendInfo_ > 128)
00102 {
00103
00104 nbytes = OFstatic_cast(
unsigned char, 257 - suspendInfo_);
00105
00106
00107 suspendInfo_ = 128;
00108
00109 ch = *cp++;
00110 --compressedSize;
00111
replicate(ch, nbytes);
00112 }
00113
else if (
suspendInfo_ < 128)
00114 {
00115
00116 nbytes = OFstatic_cast(
unsigned char, (suspendInfo_ & 0x7f) + 1);
00117
suspendInfo_ = 128;
00118
if (compressedSize < nbytes)
00119 {
00120
00121
suspendInfo_ = OFstatic_cast(
unsigned char, nbytes - compressedSize - 1);
00122 nbytes = OFstatic_cast(
unsigned char, compressedSize);
00123 result = EC_StreamNotifyClient;
00124 }
00125
00126
literal(cp, nbytes);
00127 compressedSize -= nbytes;
00128 cp += nbytes;
00129 }
00130
00131
00132
while (compressedSize && (!
fail_))
00133 {
00134 ch = *cp++;
00135 --compressedSize;
00136
00137
if (ch & 0x80)
00138 {
00139
00140
if (compressedSize)
00141 {
00142
00143 nbytes = OFstatic_cast(
unsigned char, 257 - ch);
00144 ch = *cp++;
00145 --compressedSize;
00146
replicate(ch, nbytes);
00147 }
00148
else
00149 {
00150
00151
suspendInfo_ = ch;
00152 result = EC_StreamNotifyClient;
00153 }
00154 }
00155
else
00156 {
00157
00158 nbytes = OFstatic_cast(
unsigned char, (ch & 0x7f) + 1);
00159
if (compressedSize < nbytes)
00160 {
00161
00162
suspendInfo_ = OFstatic_cast(
unsigned char, nbytes - compressedSize - 1);
00163 nbytes = OFstatic_cast(
unsigned char, compressedSize);
00164 result = EC_StreamNotifyClient;
00165 }
00166
00167
literal(cp, nbytes);
00168 compressedSize -= nbytes;
00169 cp += nbytes;
00170 }
00171 }
00172
00173
00174
if (
fail_) result = EC_CorruptedData;
00175 }
00176
00177
return result;
00178 }
00179
00180
00184 inline size_t
size()
const
00185
{
00186
return offset_;
00187 }
00188
00191 inline void *
getOutputBuffer()
const
00192
{
00193
return outputBuffer_;
00194 }
00195
00198 inline OFBool
fail()
const
00199
{
00200
if (
fail_)
return OFTrue;
else return OFFalse;
00201 }
00202
00203
private:
00204
00206
DcmRLEDecoder(
const DcmRLEDecoder&);
00207
00209
DcmRLEDecoder&
operator=(
const DcmRLEDecoder&);
00210
00211
00216 inline void replicate(
unsigned char ch,
unsigned char nbytes)
00217 {
00218
if (
offset_ + nbytes >
outputBufferSize_)
00219 {
00220
00221
fail_ = 1;
00222 nbytes = OFstatic_cast(
unsigned char,
outputBufferSize_ -
offset_);
00223 }
00224
00225
while (nbytes--)
outputBuffer_[
offset_++] = ch;
00226 }
00227
00228
00233 inline void literal(
unsigned char *cp,
unsigned char nbytes)
00234 {
00235
if (
offset_ + nbytes >
outputBufferSize_)
00236 {
00237
00238
fail_ = 1;
00239 nbytes = OFstatic_cast(
unsigned char,
outputBufferSize_ -
offset_);
00240 }
00241
00242
while (nbytes--)
outputBuffer_[
offset_++] = *cp++;
00243 }
00244
00245
00246
00251 int fail_;
00252
00255 size_t
outputBufferSize_;
00256
00261 unsigned char *
outputBuffer_;
00262
00266 size_t
offset_;
00267
00273 unsigned char suspendInfo_;
00274 };
00275
00276
#endif
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292