00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "gdcmDebug.h"
00020 #include "gdcmPixelWriteConvert.h"
00021 #include "gdcmFile.h"
00022 #include "gdcmUtil.h"
00023
00024 #include <vector>
00025
00026 #define WITHOFFSETTABLE 1
00027
00028 namespace GDCM_NAME_SPACE
00029 {
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00043 PixelWriteConvert::PixelWriteConvert()
00044 {
00045 ReadData = 0;
00046 ReadDataSize = 0;
00047
00048 UserData = 0;
00049 UserDataSize = 0;
00050 Compressed = false;
00051 }
00052
00056 PixelWriteConvert::~PixelWriteConvert()
00057 {
00058 gdcmDebugMacro("PixelWriteConvert::~PixelWriteConvert()" );
00059 if( Compressed )
00060 {
00061 delete[] UserData;
00062 }
00063 }
00064
00071 void PixelWriteConvert::SetReadData(uint8_t *data, size_t size)
00072 {
00073 ReadData = data;
00074 ReadDataSize = size;
00075 }
00076
00089 void PixelWriteConvert::SetUserData(uint8_t *data, size_t size)
00090 {
00091 UserData = data;
00092 UserDataSize = size;
00093 }
00094
00100 uint8_t *PixelWriteConvert::GetData()
00101 {
00102 if ( UserData )
00103 {
00104 return UserData;
00105 }
00106 else
00107 {
00108 return ReadData;
00109 }
00110 }
00111
00116 size_t PixelWriteConvert::GetDataSize()
00117 {
00118 if ( UserData )
00119 {
00120 return UserDataSize;
00121 }
00122 else
00123 {
00124 return ReadDataSize;
00125 }
00126 }
00127
00128
00129 typedef std::pair<size_t, uint32_t> JpegPair;
00130 typedef std::vector<JpegPair> JpegVector;
00131
00132 bool gdcm_write_JPEG2000_file (std::ostream *of, char *inputdata, size_t inputlength,
00133 int image_width, int image_height, int numZ, int sample_pixel, int bitsallocated,
00134 int sign, int quality);
00135
00136
00137 void WriteDICOMItems(std::ostream *fp, JpegVector &v)
00138 {
00139
00140 uint16_t group = 0xfffe;
00141 uint16_t elem = 0xe000;
00142 GDCM_NAME_SPACE::binary_write(*fp, group);
00143 GDCM_NAME_SPACE::binary_write(*fp, elem);
00144
00145 uint32_t dummy = 0x12345678;
00146 size_t offset = fp->tellp();
00147 JpegPair jp;
00148 jp.first = offset;
00149 v.push_back(jp);
00150 GDCM_NAME_SPACE::binary_write(*fp, dummy);
00151 }
00152
00153
00154 void EncodeWithoutBasicOffsetTable(std::ostream *fp, int numFrag)
00155 {
00156 assert( numFrag == 1);
00157
00158
00159 uint16_t group = 0xfffe;
00160 uint16_t elem = 0xe000;
00161 GDCM_NAME_SPACE::binary_write(*fp, group);
00162 GDCM_NAME_SPACE::binary_write(*fp, elem);
00163
00164 uint32_t item_length = 0x0000;
00165 GDCM_NAME_SPACE::binary_write(*fp, item_length);
00166
00167 }
00168
00169
00170 void EncodeWithBasicOffsetTable(std::ostream *fp, int numFrag, size_t &start)
00171 {
00172
00173 uint16_t group = 0xfffe;
00174 uint16_t elem = 0xe000;
00175 GDCM_NAME_SPACE::binary_write(*fp, group);
00176 GDCM_NAME_SPACE::binary_write(*fp, elem);
00177
00178 uint32_t item_length = numFrag*4;
00179 GDCM_NAME_SPACE::binary_write(*fp, item_length);
00180
00181
00182 start = fp->tellp();
00183 for(int i=0; i<numFrag;++i)
00184 {
00185 uint32_t dummy = 0x0000;
00186 GDCM_NAME_SPACE::binary_write(*fp, dummy);
00187 }
00188 }
00189
00190 void UpdateBasicOffsetTable(std::ostream *fp, JpegVector const &v, size_t pos)
00191 {
00192 JpegVector::const_iterator i;
00193 fp->seekp( pos );
00194 const JpegPair &first = v[0];
00195 for(i=v.begin(); i!=v.end(); ++i)
00196 {
00197 const JpegPair &jp = *i;
00198 if(i == v.begin() ){ assert( jp.first - first.first == 0); }
00199 uint32_t offset = (uint32_t)(jp.first - first.first);
00200 GDCM_NAME_SPACE::binary_write(*fp, offset);
00201
00202 }
00203 }
00204
00205 void UpdateJpegFragmentSize(std::ostream *fp, JpegVector const &v)
00206 {
00207 JpegVector::const_iterator i;
00208 for(i= v.begin(); i!=v.end(); ++i)
00209 {
00210 const JpegPair &jp = *i;
00211 fp->seekp( jp.first );
00212 uint32_t length = jp.second;
00213 GDCM_NAME_SPACE::binary_write(*fp, length);
00214
00215 }
00216 }
00217
00218 void CloseJpeg(std::ostream *fp, JpegVector &v)
00219 {
00220
00221 uint16_t group = 0xfffe;
00222 uint16_t elem = 0xe0dd;
00223 GDCM_NAME_SPACE::binary_write(*fp, group);
00224 GDCM_NAME_SPACE::binary_write(*fp, elem);
00225
00226 uint32_t length = 0x0;
00227 GDCM_NAME_SPACE::binary_write(*fp, length);
00228
00229
00230 UpdateJpegFragmentSize(fp, v);
00231 }
00232
00233
00234
00235
00236 void PixelWriteConvert::SetCompressJPEG2000UserData(uint8_t *data, size_t size, File *image)
00237 {
00238 Compressed = true;
00239
00240
00241 std::ostringstream *of = new std::ostringstream();
00242 int xsize = image->GetXSize();
00243 int ysize = image->GetYSize();
00244 int zsize = image->GetZSize();
00245 int samplesPerPixel = image->GetSamplesPerPixel();
00246
00247
00248
00249 int bitsallocated = image->GetBitsAllocated();
00250 int sign = image->IsSignedPixelData();
00251 unsigned int fragment_size = xsize*ysize*samplesPerPixel * (bitsallocated / 8);
00252 assert( fragment_size*zsize == size );
00253
00254 JpegVector JpegFragmentSize;
00255 #if WITHOFFSETTABLE
00256 size_t bots;
00257 EncodeWithBasicOffsetTable(of, zsize, bots);
00258 #else
00259 EncodeWithoutBasicOffsetTable(of, 1);
00260 #endif
00261 uint8_t *pImageData = data;
00262 for(int i=0; i<zsize;i++)
00263 {
00264 WriteDICOMItems(of, JpegFragmentSize);
00265 size_t beg = of->tellp();
00266 gdcm_write_JPEG2000_file(of, (char*)pImageData,size,
00267 image->GetXSize(), image->GetYSize(), image->GetZSize(), image->GetSamplesPerPixel(),
00268 image->GetBitsAllocated(), sign, 100);
00269
00270
00271
00272
00273
00274 size_t end = of->tellp();
00275
00276 JpegPair &jp = JpegFragmentSize[i];
00277 jp.second = (uint32_t)(end-beg);
00278 if( ((end-beg) % 2) )
00279 {
00280 of->put( '\0' );
00281 jp.second += 1;
00282 }
00283 assert( !(jp.second % 2) );
00284
00285
00286 pImageData += fragment_size;
00287 }
00288 CloseJpeg(of, JpegFragmentSize);
00289 #if WITHOFFSETTABLE
00290 UpdateBasicOffsetTable(of, JpegFragmentSize, bots);
00291 #endif
00292
00293
00294 size_t of_size = of->str().size();
00295 UserData = new uint8_t[of_size];
00296 memcpy(UserData, of->str().c_str(), of_size);
00297 UserDataSize = of_size;
00298 delete of;
00299 }
00300
00301 bool gdcm_write_JPEG_file8 (std::ostream *fp, char *inputdata, size_t inputlength,
00302 int image_width, int image_height, int numZ,
00303 int sample_pixel, int bitsallocated, int quality);
00304 bool gdcm_write_JPEG_file12 (std::ostream *fp, char *inputdata, size_t inputlength,
00305 int image_width, int image_height, int numZ,
00306 int sample_pixel, int bitsallocated, int quality);
00307 bool gdcm_write_JPEG_file16 (std::ostream *fp, char *inputdata, size_t inputlength,
00308 int image_width, int image_height, int numZ,
00309 int sample_pixel, int bitsallocated, int quality);
00310
00311 void PixelWriteConvert::SetCompressJPEGUserData(uint8_t *data, size_t size, File *image)
00312 {
00313 (void)data;
00314 (void)size;
00315 (void)image;
00316 Compressed = true;
00317
00318
00319 std::ostringstream *of = new std::ostringstream();
00320 int xsize = image->GetXSize();
00321 int ysize = image->GetYSize();
00322 int zsize = image->GetZSize();
00323 int samplesPerPixel = image->GetSamplesPerPixel();
00324
00325
00326
00327 int bitsallocated = image->GetBitsAllocated();
00328 unsigned int fragment_size = xsize*ysize*samplesPerPixel * (bitsallocated / 8);
00329 assert( fragment_size*zsize == size );
00330
00331 JpegVector JpegFragmentSize;
00332 #if WITHOFFSETTABLE
00333 size_t bots;
00334 EncodeWithBasicOffsetTable(of, zsize, bots);
00335 #else
00336 EncodeWithoutBasicOffsetTable(of, 1);
00337 #endif
00338 uint8_t *pImageData = data;
00339 for(int i=0; i<zsize;i++)
00340 {
00341 WriteDICOMItems(of, JpegFragmentSize);
00342 size_t beg = of->tellp();
00343 if( bitsallocated == 8 )
00344 {
00345 gdcm_write_JPEG_file8(of, (char*)pImageData,size,
00346 image->GetXSize(), image->GetYSize(), image->GetZSize(), image->GetSamplesPerPixel(),
00347 image->GetBitsAllocated(), 100 );
00348 }
00349 else if (bitsallocated <= 12)
00350 {
00351 assert( bitsallocated >= 8 );
00352 gdcm_write_JPEG_file12(of, (char*)pImageData,size,
00353 image->GetXSize(), image->GetYSize(), image->GetZSize(), image->GetSamplesPerPixel(),
00354 image->GetBitsAllocated(), 100);
00355 }
00356 else if (bitsallocated <= 16)
00357 {
00358 assert( bitsallocated >= 12 );
00359 gdcm_write_JPEG_file16(of, (char*)pImageData,size,
00360 image->GetXSize(), image->GetYSize(), image->GetZSize(), image->GetSamplesPerPixel(),
00361 image->GetBitsAllocated(), 100);
00362 }
00363 else
00364 {
00365 abort();
00366 }
00367 size_t end = of->tellp();
00368
00369 JpegPair &jp = JpegFragmentSize[i];
00370 jp.second = (uint32_t)(end-beg);
00371 if( ((end-beg) % 2) )
00372 {
00373 of->put( '\0' );
00374 jp.second += 1;
00375 }
00376 assert( !(jp.second % 2) );
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 pImageData += fragment_size;
00389 }
00390 CloseJpeg(of, JpegFragmentSize);
00391 #if WITHOFFSETTABLE
00392 UpdateBasicOffsetTable(of, JpegFragmentSize, bots);
00393 #endif
00394
00395
00396 size_t of_size = of->str().size();
00397 UserData = new uint8_t[of_size];
00398 memcpy(UserData, of->str().c_str(), of_size);
00399 UserDataSize = of_size;
00400 delete of;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 }