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 "osconfig.h"
00037 #include "oflist.h"
00038
00039 #define INCLUDE_CSTRING
00040 #include "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 };
00058
00059
00063 class DcmRLEEncoder
00064 {
00065 public:
00066
00070 DcmRLEEncoder(int doPad)
00071 : fail_(0)
00072 , pad_(doPad)
00073 , currentBlock_(new unsigned char[DcmRLEEncoder_BLOCKSIZE])
00074 , offset_(0)
00075 , blockList_()
00076 , RLE_buff_(new unsigned char[132])
00077 , RLE_prev_(-1)
00078 , RLE_pcount_(0)
00079 , RLE_bindex_(1)
00080 {
00081 if ((! RLE_buff_)||(! currentBlock_)) fail_ = 1;
00082 else RLE_buff_[0] = 0;
00083 }
00084
00086 ~DcmRLEEncoder()
00087 {
00088 delete[] currentBlock_;
00089 delete[] RLE_buff_;
00090 OFListIterator(unsigned char *) first = blockList_.begin();
00091 OFListIterator(unsigned char *) last = blockList_.end();
00092 while (first != last)
00093 {
00094 delete[] *first;
00095 first = blockList_.erase(first);
00096 }
00097 }
00098
00103 inline void add(unsigned char ch)
00104 {
00105 if (! fail_)
00106 {
00107
00108
00109
00110 if (OFstatic_cast(int, ch) == RLE_prev_) RLE_pcount_++;
00111 else
00112 {
00113
00114
00115 switch (RLE_pcount_)
00116 {
00117 case 0:
00118
00119 break;
00120 case 2:
00121
00122 RLE_buff_[RLE_bindex_++] = OFstatic_cast(unsigned char, RLE_prev_);
00123
00124 case 1:
00125
00126 RLE_buff_[RLE_bindex_++] = OFstatic_cast(unsigned char, RLE_prev_);
00127 break;
00128 default:
00129
00130 if (RLE_bindex_ > 1)
00131 {
00132
00133
00134 RLE_buff_[0] = OFstatic_cast(unsigned char, RLE_bindex_-2);
00135 move(RLE_bindex_);
00136 }
00137
00138 RLE_buff_[1] = OFstatic_cast(unsigned char, RLE_prev_);
00139
00140 for (; RLE_pcount_>0; RLE_pcount_-=128)
00141 {
00142
00143
00144
00145
00146 if (RLE_pcount_ > 128) RLE_buff_[0] = 0x81;
00147 else RLE_buff_[0] = OFstatic_cast(unsigned char, 257 - RLE_pcount_);
00148 move(2);
00149 }
00150
00151 RLE_buff_[0] = 0;
00152 RLE_bindex_ = 1;
00153 break;
00154 }
00155
00156
00157 if (RLE_bindex_ > 129)
00158 {
00159 RLE_buff_[0] = 127;
00160 move(129);
00161 RLE_bindex_ -= 128;
00162 if (RLE_bindex_ > 1)
00163 RLE_buff_[1] = RLE_buff_[129];
00164 if (RLE_bindex_ > 2)
00165 RLE_buff_[2] = RLE_buff_[130];
00166 }
00167
00168
00169 RLE_prev_ = ch;
00170 RLE_pcount_ = 1;
00171 }
00172 }
00173 }
00174
00180 inline void add(const unsigned char *buf, size_t bufcount)
00181 {
00182 if (buf)
00183 {
00184 while (bufcount--) add(*buf++);
00185 }
00186 }
00187
00194 inline void flush()
00195 {
00196 if (! fail_)
00197 {
00198
00199 if (RLE_pcount_ < 2)
00200 {
00201 for (; RLE_pcount_>0; --RLE_pcount_) RLE_buff_[RLE_bindex_++] = OFstatic_cast(unsigned char, RLE_prev_);
00202 }
00203
00204
00205 if (RLE_bindex_ > 129)
00206 {
00207 RLE_buff_[0] = 127;
00208 move(129);
00209 RLE_bindex_ -= 128;
00210 if (RLE_bindex_ > 1)
00211 RLE_buff_[1] = RLE_buff_[129];
00212 if (RLE_bindex_ > 2)
00213 RLE_buff_[2] = RLE_buff_[130];
00214 }
00215
00216
00217 if (RLE_bindex_ > 1)
00218 {
00219 RLE_buff_[0] = OFstatic_cast(unsigned char, RLE_bindex_-2);
00220 move(RLE_bindex_);
00221 }
00222
00223
00224 if (RLE_pcount_ >= 2)
00225 {
00226 RLE_buff_[1] = OFstatic_cast(unsigned char, RLE_prev_);
00227
00228 for (; RLE_pcount_>0; RLE_pcount_-=128)
00229 {
00230
00231
00232
00233
00234 if (RLE_pcount_ > 128) RLE_buff_[0] = 0x81;
00235 else RLE_buff_[0] = OFstatic_cast(unsigned char, 257 - RLE_pcount_);
00236 move(2);
00237 }
00238 }
00239
00240
00241 RLE_buff_[0] = 0;
00242 RLE_prev_ = -1;
00243 RLE_pcount_ = 0;
00244 RLE_bindex_ = 1;
00245 }
00246 }
00247
00255 inline size_t size() const
00256 {
00257 size_t result = blockList_.size() * DcmRLEEncoder_BLOCKSIZE + offset_;
00258 if (pad_ && (result & 1)) result++;
00259 return result;
00260 }
00261
00265 inline OFBool fail() const
00266 {
00267 if (fail_) return OFTrue; else return OFFalse;
00268 }
00269
00274 inline void write(void *target) const
00275 {
00276 if ((!fail_) && target)
00277 {
00278 unsigned char *current = NULL;
00279 unsigned char *target8 = OFstatic_cast(unsigned char *, target);
00280 OFListConstIterator(unsigned char *) first = blockList_.begin();
00281 OFListConstIterator(unsigned char *) last = blockList_.end();
00282 while (first != last)
00283 {
00284 current = *first;
00285 memcpy(target8, current, DcmRLEEncoder_BLOCKSIZE);
00286 target8 += DcmRLEEncoder_BLOCKSIZE;
00287 ++first;
00288 }
00289 if (offset_ > 0)
00290 {
00291 memcpy(target8, currentBlock_, offset_);
00292 }
00293
00294
00295 if (pad_ && ((blockList_.size() * DcmRLEEncoder_BLOCKSIZE + offset_) & 1))
00296 {
00297 target8 += offset_;
00298 *target8 = 0;
00299 }
00300 }
00301 }
00302
00307 inline void write(DcmEncoderOutputStream& os) const
00308 {
00309 if (!fail_)
00310 {
00311 OFListConstIterator(unsigned char *) first = blockList_.begin();
00312 OFListConstIterator(unsigned char *) last = blockList_.end();
00313 while (first != last)
00314 {
00315 os.write(*first, DcmRLEEncoder_BLOCKSIZE);
00316 ++first;
00317 }
00318 if (offset_ > 0)
00319 {
00320 os.write(currentBlock_, offset_);
00321 }
00322
00323
00324 if (pad_ && ((blockList_.size() * DcmRLEEncoder_BLOCKSIZE + offset_) & 1))
00325 {
00326 unsigned char c = 0;
00327 os.write(&c, 1);
00328 }
00329 }
00330 }
00331
00332 private:
00333
00335 DcmRLEEncoder(const DcmRLEEncoder&);
00336
00338 DcmRLEEncoder& operator=(const DcmRLEEncoder&);
00339
00345 inline void move(size_t numberOfBytes)
00346 {
00347 size_t i=0;
00348 while (i < numberOfBytes)
00349 {
00350 if (offset_ == DcmRLEEncoder_BLOCKSIZE)
00351 {
00352 blockList_.push_back(currentBlock_);
00353 currentBlock_ = new unsigned char[DcmRLEEncoder_BLOCKSIZE];
00354 offset_ = 0;
00355 if (! currentBlock_)
00356 {
00357 fail_ = 1;
00358 break;
00359 }
00360 }
00361 currentBlock_[offset_++] = RLE_buff_[i++];
00362 }
00363 }
00364
00365
00366
00372 int fail_;
00373
00378 int pad_;
00379
00384 unsigned char *currentBlock_;
00385
00390 size_t offset_;
00391
00396 OFList<unsigned char *> blockList_;
00397
00401 unsigned char *RLE_buff_;
00402
00407 int RLE_prev_;
00408
00412 int RLE_pcount_;
00413
00416 unsigned int RLE_bindex_;
00417
00418 };
00419
00420 #endif
00421
00422
00423
00424
00425
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