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