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 #ifndef DCRLEENC_H
00034 #define DCRLEENC_H
00035
00036 #include "dcmtk/config/osconfig.h"
00037 #include "dcmtk/ofstd/oflist.h"
00038
00039 #define INCLUDE_CSTRING
00040 #include "dcmtk/ofstd/ofstdinc.h"
00041
00042 #define DcmRLEEncoder_BLOCKSIZE 16384
00043
00044
00049 class DcmEncoderOutputStream
00050 {
00051 public:
00056 virtual void write(const unsigned char *buf, size_t bufsize) =0;
00057
00060 virtual ~DcmEncoderOutputStream() {}
00061
00062 };
00063
00064
00068 class DcmRLEEncoder
00069 {
00070 public:
00071
00075 DcmRLEEncoder(int doPad)
00076 : fail_(0)
00077 , pad_(doPad)
00078 , currentBlock_(new unsigned char[DcmRLEEncoder_BLOCKSIZE])
00079 , offset_(0)
00080 , blockList_()
00081 , RLE_buff_(new unsigned char[132])
00082 , RLE_prev_(-1)
00083 , RLE_pcount_(0)
00084 , RLE_bindex_(1)
00085 {
00086 if ((! RLE_buff_)||(! currentBlock_)) fail_ = 1;
00087 else RLE_buff_[0] = 0;
00088 }
00089
00091 ~DcmRLEEncoder()
00092 {
00093 delete[] currentBlock_;
00094 delete[] RLE_buff_;
00095 OFListIterator(unsigned char *) first = blockList_.begin();
00096 OFListIterator(unsigned char *) last = blockList_.end();
00097 while (first != last)
00098 {
00099 delete[] *first;
00100 first = blockList_.erase(first);
00101 }
00102 }
00103
00108 inline void add(unsigned char ch)
00109 {
00110 if (! fail_)
00111 {
00112
00113
00114
00115 if (OFstatic_cast(int, ch) == RLE_prev_) RLE_pcount_++;
00116 else
00117 {
00118
00119
00120 switch (RLE_pcount_)
00121 {
00122 case 0:
00123
00124 break;
00125 case 2:
00126
00127 RLE_buff_[RLE_bindex_++] = OFstatic_cast(unsigned char, RLE_prev_);
00128
00129 case 1:
00130
00131 RLE_buff_[RLE_bindex_++] = OFstatic_cast(unsigned char, RLE_prev_);
00132 break;
00133 default:
00134
00135 if (RLE_bindex_ > 1)
00136 {
00137
00138
00139 RLE_buff_[0] = OFstatic_cast(unsigned char, RLE_bindex_-2);
00140 move(RLE_bindex_);
00141 }
00142
00143 RLE_buff_[1] = OFstatic_cast(unsigned char, RLE_prev_);
00144
00145 for (; RLE_pcount_>0; RLE_pcount_-=128)
00146 {
00147
00148
00149
00150
00151 if (RLE_pcount_ > 128) RLE_buff_[0] = 0x81;
00152 else RLE_buff_[0] = OFstatic_cast(unsigned char, 257 - RLE_pcount_);
00153 move(2);
00154 }
00155
00156 RLE_buff_[0] = 0;
00157 RLE_bindex_ = 1;
00158 break;
00159 }
00160
00161
00162 if (RLE_bindex_ > 129)
00163 {
00164 RLE_buff_[0] = 127;
00165 move(129);
00166 RLE_bindex_ -= 128;
00167 if (RLE_bindex_ > 1)
00168 RLE_buff_[1] = RLE_buff_[129];
00169 if (RLE_bindex_ > 2)
00170 RLE_buff_[2] = RLE_buff_[130];
00171 }
00172
00173
00174 RLE_prev_ = ch;
00175 RLE_pcount_ = 1;
00176 }
00177 }
00178 }
00179
00185 inline void add(const unsigned char *buf, size_t bufcount)
00186 {
00187 if (buf)
00188 {
00189 while (bufcount--) add(*buf++);
00190 }
00191 }
00192
00199 inline void flush()
00200 {
00201 if (! fail_)
00202 {
00203
00204 if (RLE_pcount_ < 2)
00205 {
00206 for (; RLE_pcount_>0; --RLE_pcount_) RLE_buff_[RLE_bindex_++] = OFstatic_cast(unsigned char, RLE_prev_);
00207 }
00208
00209
00210 if (RLE_bindex_ > 129)
00211 {
00212 RLE_buff_[0] = 127;
00213 move(129);
00214 RLE_bindex_ -= 128;
00215 if (RLE_bindex_ > 1)
00216 RLE_buff_[1] = RLE_buff_[129];
00217 if (RLE_bindex_ > 2)
00218 RLE_buff_[2] = RLE_buff_[130];
00219 }
00220
00221
00222 if (RLE_bindex_ > 1)
00223 {
00224 RLE_buff_[0] = OFstatic_cast(unsigned char, RLE_bindex_-2);
00225 move(RLE_bindex_);
00226 }
00227
00228
00229 if (RLE_pcount_ >= 2)
00230 {
00231 RLE_buff_[1] = OFstatic_cast(unsigned char, RLE_prev_);
00232
00233 for (; RLE_pcount_>0; RLE_pcount_-=128)
00234 {
00235
00236
00237
00238
00239 if (RLE_pcount_ > 128) RLE_buff_[0] = 0x81;
00240 else RLE_buff_[0] = OFstatic_cast(unsigned char, 257 - RLE_pcount_);
00241 move(2);
00242 }
00243 }
00244
00245
00246 RLE_buff_[0] = 0;
00247 RLE_prev_ = -1;
00248 RLE_pcount_ = 0;
00249 RLE_bindex_ = 1;
00250 }
00251 }
00252
00260 inline size_t size() const
00261 {
00262 size_t result = blockList_.size() * DcmRLEEncoder_BLOCKSIZE + offset_;
00263 if (pad_ && (result & 1)) result++;
00264 return result;
00265 }
00266
00270 inline OFBool fail() const
00271 {
00272 if (fail_) return OFTrue; else return OFFalse;
00273 }
00274
00279 inline void write(void *target) const
00280 {
00281 if ((!fail_) && target)
00282 {
00283 unsigned char *current = NULL;
00284 unsigned char *target8 = OFstatic_cast(unsigned char *, target);
00285 OFListConstIterator(unsigned char *) first = blockList_.begin();
00286 OFListConstIterator(unsigned char *) last = blockList_.end();
00287 while (first != last)
00288 {
00289 current = *first;
00290 memcpy(target8, current, DcmRLEEncoder_BLOCKSIZE);
00291 target8 += DcmRLEEncoder_BLOCKSIZE;
00292 ++first;
00293 }
00294 if (offset_ > 0)
00295 {
00296 memcpy(target8, currentBlock_, offset_);
00297 }
00298
00299
00300 if (pad_ && ((blockList_.size() * DcmRLEEncoder_BLOCKSIZE + offset_) & 1))
00301 {
00302 target8 += offset_;
00303 *target8 = 0;
00304 }
00305 }
00306 }
00307
00312 inline void write(DcmEncoderOutputStream& os) const
00313 {
00314 if (!fail_)
00315 {
00316 OFListConstIterator(unsigned char *) first = blockList_.begin();
00317 OFListConstIterator(unsigned char *) last = blockList_.end();
00318 while (first != last)
00319 {
00320 os.write(*first, DcmRLEEncoder_BLOCKSIZE);
00321 ++first;
00322 }
00323 if (offset_ > 0)
00324 {
00325 os.write(currentBlock_, offset_);
00326 }
00327
00328
00329 if (pad_ && ((blockList_.size() * DcmRLEEncoder_BLOCKSIZE + offset_) & 1))
00330 {
00331 unsigned char c = 0;
00332 os.write(&c, 1);
00333 }
00334 }
00335 }
00336
00337 private:
00338
00340 DcmRLEEncoder(const DcmRLEEncoder&);
00341
00343 DcmRLEEncoder& operator=(const DcmRLEEncoder&);
00344
00350 inline void move(size_t numberOfBytes)
00351 {
00352 size_t i=0;
00353 while (i < numberOfBytes)
00354 {
00355 if (offset_ == DcmRLEEncoder_BLOCKSIZE)
00356 {
00357 blockList_.push_back(currentBlock_);
00358 currentBlock_ = new unsigned char[DcmRLEEncoder_BLOCKSIZE];
00359 offset_ = 0;
00360 if (! currentBlock_)
00361 {
00362 fail_ = 1;
00363 break;
00364 }
00365 }
00366 currentBlock_[offset_++] = RLE_buff_[i++];
00367 }
00368 }
00369
00370
00371
00377 int fail_;
00378
00383 int pad_;
00384
00389 unsigned char *currentBlock_;
00390
00395 size_t offset_;
00396
00401 OFList<unsigned char *> blockList_;
00402
00406 unsigned char *RLE_buff_;
00407
00412 int RLE_prev_;
00413
00417 int RLE_pcount_;
00418
00421 unsigned int RLE_bindex_;
00422
00423 };
00424
00425 #endif
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471