#include <gdcmFile.h>
Public Member Functions | |
| gdcmFile (gdcmHeader *header) | |
| Constructor dedicated to writing a new DICOMV3 part10 compliant file (see SetFileName, SetDcmTag and Write) Opens (in read only and when possible) an existing file and checks for DICOM compliance. Returns NULL on failure. | |
| gdcmFile (std::string &filename) | |
| Constructor dedicated to writing a new DICOMV3 part10 compliant file (see SetFileName, SetDcmTag and Write) Opens (in read only and when possible) an existing file and checks for DICOM compliance. Returns NULL on failure. | |
| gdcmFile (const char *filename) | |
| Constructor dedicated to writing a new DICOMV3 part10 compliant file (see SetFileName, SetDcmTag and Write) Opens (in read only and when possible) an existing file and checks for DICOM compliance. Returns NULL on failure. | |
| virtual | ~gdcmFile (void) |
| canonical destructor If the gdcmHeader is created by the gdcmFile, it is destroyed by the gdcmFile | |
| gdcmHeader * | GetHeader (void) |
| void | SetPixelDataSizeFromHeader (void) |
| computes the length (in bytes) to ALLOCATE to receive the image(s) pixels (multiframes taken into account) | |
| size_t | GetImageDataSize () |
| Returns the size (in bytes) of required memory to hold the pixel data represented in this file. | |
| size_t | GetImageDataSizeRaw () |
| Returns the size (in bytes) of required memory to hold the pixel data represented in this file, when user DOESN'T want to get RGB pixels image when it's stored as a PALETTE COLOR image -the (vtk) user is supposed to know how deal with LUTs-. | |
| void * | GetImageData () |
| Allocates necessary memory, copies the pixel data (image[s]/volume[s]) to newly allocated zone. Transforms YBR pixels into RGB pixels if any Transforms 3 planes R, G, B into a single RGB Plane Transforms single Grey plane + 3 Palettes into a RGB Plane. | |
| size_t | GetImageDataIntoVector (void *destination, size_t MaxSize) |
| Copies at most MaxSize bytes of pixel data to caller's memory space. | |
| void * | GetImageDataRaw () |
| Allocates necessary memory, copies the pixel data (image[s]/volume[s]) to newly allocated zone. Transforms YBR pixels into RGB pixels if any Transforms 3 planes R, G, B into a single RGB Plane DOES NOT transform Grey plane + 3 Palettes into a RGB Plane. | |
| size_t | GetImageDataIntoVectorRaw (void *destination, size_t MaxSize) |
| Copies at most MaxSize bytes of pixel data to caller's memory space. | |
| bool | SetImageData (void *Data, size_t ExpectedSize) |
| TODO JPR. | |
| bool | WriteRawData (std::string fileName) |
| Writes on disk A SINGLE Dicom file NO test is performed on processor "Endiannity". It's up to the user to call his Reader properly. | |
| bool | WriteDcmImplVR (std::string fileName) |
| Writes on disk A SINGLE Dicom file NO test is performed on processor "Endiannity". | |
| bool | WriteDcmImplVR (const char *fileName) |
| bool | WriteDcmExplVR (std::string fileName) |
| bool | WriteAcr (std::string fileName) |
| Ecrit au format ACR-NEMA sur disque l'entete et les pixels (a l'attention des logiciels cliniques qui ne prennent en entrée QUE des images ACR ... | |
| bool | ParsePixelData (void) |
| Parse pixel data from disk and *prints* the result \ For multi-fragment Jpeg/Rle files checking purpose *only* \ Allows to 'see' if the file *does* conform \ (some of them do not) \ with Dicom Part 3, Annex A (PS 3.5-2003, page 58, page 85). | |
Protected Member Functions | |
| bool | WriteBase (std::string FileName, FileType type) |
Private Member Functions | |
| void | SwapZone (void *im, int swap, int lgr, int nb) |
| Swap the bytes, according to swap code. | |
| bool | ReadPixelData (void *destination) |
| Read pixel data from disk (optionaly decompressing) into the caller specified memory location. | |
| bool | gdcm_read_JPEG_file (FILE *fp, void *image_buffer) |
| bool | gdcm_read_JPEG_file12 (FILE *fp, void *image_buffer) |
| bool | gdcm_read_JPEG2000_file (FILE *fp, void *image_buffer) |
| bool | gdcm_read_RLE_file (FILE *fp, void *image_buffer) |
| Reads a 'Run Length Encoded' Dicom encapsulated file. | |
Static Private Member Functions | |
| int | gdcm_read_RLE_fragment (char **areaToRead, long lengthToDecode, long uncompressedSegmentSize, FILE *fp) |
Private Attributes | |
| gdcmHeader * | Header |
| bool | SelfHeader |
| void * | PixelData |
| size_t | lgrTotaleRaw |
| size_t | lgrTotale |
| int | PixelRead |
| int | Parsed |
| std::string | OrigFileName |
|
|
Constructor dedicated to writing a new DICOMV3 part10 compliant file (see SetFileName, SetDcmTag and Write) Opens (in read only and when possible) an existing file and checks for DICOM compliance. Returns NULL on failure.
Definition at line 26 of file gdcmFile.cxx. References Header, gdcmHeader::IsReadable(), PixelRead, SelfHeader, and SetPixelDataSizeFromHeader().
00026 {
00027 Header=header;
00028 SelfHeader=false;
00029 PixelRead=-1; // no ImageData read yet.
00030
00031 if (Header->IsReadable())
00032 SetPixelDataSizeFromHeader();
00033 }
|
|
|
Constructor dedicated to writing a new DICOMV3 part10 compliant file (see SetFileName, SetDcmTag and Write) Opens (in read only and when possible) an existing file and checks for DICOM compliance. Returns NULL on failure.
Definition at line 48 of file gdcmFile.cxx. References Header, gdcmHeader::IsReadable(), PixelRead, SelfHeader, and SetPixelDataSizeFromHeader().
00048 {
00049 Header=new gdcmHeader(filename.c_str());
00050 SelfHeader=true;
00051 PixelRead=-1; // no ImageData read yet.
00052
00053 if (Header->IsReadable())
00054 SetPixelDataSizeFromHeader();
00055 }
|
|
|
Constructor dedicated to writing a new DICOMV3 part10 compliant file (see SetFileName, SetDcmTag and Write) Opens (in read only and when possible) an existing file and checks for DICOM compliance. Returns NULL on failure.
Definition at line 70 of file gdcmFile.cxx. References Header, gdcmHeader::IsReadable(), PixelRead, SelfHeader, and SetPixelDataSizeFromHeader().
00070 {
00071 Header=new gdcmHeader(filename);
00072 SelfHeader=true;
00073 PixelRead=-1; // no ImageData read yet.
00074
00075 if (Header->IsReadable())
00076 SetPixelDataSizeFromHeader();
00077 }
|
|
|
canonical destructor If the gdcmHeader is created by the gdcmFile, it is destroyed by the gdcmFile
Definition at line 85 of file gdcmFile.cxx. References Header, and SelfHeader.
00085 {
00086 if(SelfHeader)
00087 delete Header;
00088 Header=NULL;
00089 }
|
|
||||||||||||
|
Definition at line 7 of file gdcmJpeg2000.cxx. Referenced by ReadPixelData().
00007 {
00008 printf("Sorry JPEG 2000 File not yet taken into account\n");
00009 return false;
00010 }
|
|
||||||||||||
|
Referenced by ReadPixelData(). |
|
||||||||||||
|
Definition at line 164 of file gdcmJpeg12.cxx. References BITS_IN_JSAMPLE, DEBUG, jpeg_create_decompress, jpeg_destroy_decompress, jpeg_finish_decompress, jpeg_read_header, jpeg_read_scanlines, jpeg_start_decompress, jpeg_std_error, jpeg_stdio_src, my_error_exit, my_error_mgr::pub, and my_error_mgr::setjmp_buffer. Referenced by ReadPixelData().
00164 {
00165 char *pimage;
00166
00167 /* This struct contains the JPEG decompression parameters and pointers to
00168 * working space (which is allocated as needed by the JPEG library).
00169 */
00170
00171 struct jpeg_decompress_struct cinfo;
00172
00173 /* -------------- inside, we found :
00174 * JDIMENSION image_width; // input image width
00175 * JDIMENSION image_height; // input image height
00176 * int input_components; // nb of color components in input image
00177 * J_COLOR_SPACE in_color_space; // colorspace of input image
00178 * double input_gamma; // image gamma of input image
00179 * -------------- */
00180
00181 /* We use our private extension JPEG error handler.
00182 * Note that this struct must live as long as the main JPEG parameter
00183 * struct, to avoid dangling-pointer problems.
00184 */
00185 struct my_error_mgr jerr;
00186 /* More stuff */
00187
00188 JSAMPARRAY buffer; /* Output row buffer */
00189
00190 // rappel :
00191 // ------
00192 // typedef unsigned char JSAMPLE;
00193 // typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */
00194 // typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */
00195 // typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
00196
00197
00198 int row_stride; /* physical row width in output buffer */
00199
00200 if (DEBUG) printf("entree dans gdcmFile::gdcm_read_JPEG_file12, depuis gdcmJpeg\n");
00201
00202
00203 /* In this example we want to open the input file before doing anything else,
00204 * so that the setjmp() error recovery below can assume the file is open.
00205 * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
00206 * requires it in order to read binary files.
00207 */
00208
00209 /* Step 1: allocate and initialize JPEG decompression object */
00210 if (DEBUG)printf("Entree Step 1\n");
00211
00212 /* We set up the normal JPEG error routines, then override error_exit. */
00213
00214 cinfo.err = jpeg_std_error(&jerr.pub);
00215 jerr.pub.error_exit = my_error_exit;
00216
00217 /* Establish the setjmp return context for my_error_exit to use. */
00218 if (setjmp(jerr.setjmp_buffer)) {
00219 /* If we get here, the JPEG code has signaled an error.
00220 * We need to clean up the JPEG object, close the input file, and return.
00221 */
00222 jpeg_destroy_decompress(&cinfo);
00223 return(false);
00224 }
00225
00226 /* Now we can initialize the JPEG decompression object. */
00227 jpeg_create_decompress(&cinfo);
00228
00229 /* Step 2: specify data source (eg, a file) */
00230 if (DEBUG) printf("Entree Step 2\n");
00231 jpeg_stdio_src(&cinfo, fp);
00232
00233 /* Step 3: read file parameters with jpeg_read_header() */
00234 if (DEBUG) printf("Entree Step 3\n");
00235 (void) jpeg_read_header(&cinfo, TRUE);
00236
00237 /* We can ignore the return value from jpeg_read_header since
00238 * (a) suspension is not possible with the stdio data source, and
00239 * (b) we passed TRUE to reject a tables-only JPEG file as an error.
00240 * See libjpeg.doc for more info.
00241 */
00242
00243 if (DEBUG) {
00244 printf("--------------Header contents :----------------\n");
00245 printf("image_width %d image_height %d\n",
00246 cinfo.image_width , cinfo.image_height);
00247 printf("bits of precision in image data %d \n",
00248 cinfo.output_components);
00249 printf("nb of color components returned %d \n",
00250 cinfo.data_precision);
00251 }
00252
00253
00254 /*
00255 * JDIMENSION image_width; // input image width
00256 * JDIMENSION image_height; // input image height
00257 * int output_components; // # of color components returned
00258 * J_COLOR_SPACE in_color_space; // colorspace of input image
00259 * double input_gamma; // image gamma of input image
00260 * int data_precision; // bits of precision in image data
00261 */
00262
00263 /* Step 4: set parameters for decompression */
00264 if (DEBUG) printf("Entree Step 4\n");
00265
00266 /* In this example, we don't need to change any of the defaults set by
00267 * jpeg_read_header(), so we do nothing here.
00268 */
00269
00270 /* Step 5: Start decompressor */
00271 if (DEBUG) printf("Entree Step 5\n");
00272
00273 (void) jpeg_start_decompress(&cinfo);
00274 /* We can ignore the return value since suspension is not possible
00275 * with the stdio data source.
00276 */
00277
00278 /* We may need to do some setup of our own at this point before reading
00279 * the data. After jpeg_start_decompress() we have the correct scaled
00280 * output image dimensions available, as well as the output colormap
00281 * if we asked for color quantization.
00282 * In this example, we need to make an output work buffer of the right size.
00283 */
00284
00285 /* JSAMPLEs per row in output buffer */
00286 row_stride = cinfo.output_width * cinfo.output_components;
00287
00288 if (DEBUG)
00289 printf ("cinfo.output_width %d cinfo.output_components %d row_stride %d\n",
00290 cinfo.output_width, cinfo.output_components,row_stride);
00291
00292 /* Make a one-row-high sample array that will go away when done with image */
00293 buffer = (*cinfo.mem->alloc_sarray)
00294 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
00295
00296 /* Step 6: while (scan lines remain to be read) */
00297 if (DEBUG) printf("Entree Step 6\n");
00298
00299 /* jpeg_read_scanlines(...); */
00300
00301 /* Here we use the library's state variable cinfo.output_scanline as the
00302 * loop counter, so that we don't have to keep track ourselves.
00303 */
00304
00305 if (DEBUG) printf ("cinfo.output_height %d cinfo.output_width %d\n",
00306 cinfo.output_height,cinfo.output_width);
00307
00308 pimage=(char *)image_buffer;
00309
00310 while (cinfo.output_scanline < cinfo.output_height) {
00311 /* jpeg_read_scanlines expects an array of pointers to scanlines.
00312 * Here the array is only one element long, but you could ask for
00313 * more than one scanline at a time if that's more convenient.
00314 */
00315
00316 (void) jpeg_read_scanlines(&cinfo, buffer, 1);
00317
00318 if ( BITS_IN_JSAMPLE == 8) {
00319 memcpy( pimage, buffer[0],row_stride);
00320 pimage+=row_stride;
00321 } else {
00322 memcpy( pimage, buffer[0],row_stride*2 ); // FIXME : *2 car 16 bits?!?
00323 pimage+=row_stride*2; // FIXME : *2 car 16 bits?!?
00324 }
00325 }
00326
00327 /* Step 7: Finish decompression */
00328 if (DEBUG) printf("Entree Step 7\n");
00329 (void) jpeg_finish_decompress(&cinfo);
00330 /* We can ignore the return value since suspension is not possible
00331 * with the stdio data source.
00332 */
00333
00334 /* Step 8: Release JPEG decompression object */
00335 if (DEBUG) printf("Entree Step 8\n");
00336
00337 /* This is an important step since it will release a good deal of memory. */
00338 jpeg_destroy_decompress(&cinfo);
00339
00340 /* After finish_decompress, we can close the input file.
00341 * Here we postpone it until after no more JPEG errors are possible,
00342 * so as to simplify the setjmp error logic above. (Actually, I don't
00343 * think that jpeg_destroy can do an error exit, but why assume anything...)
00344 */
00345
00346 /* At this point you may want to check to see whether any corrupt-data
00347 * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
00348 */
00349
00350 /* And we're done! */
00351
00352 return(true);
00353 }
|
|
||||||||||||
|
Reads a 'Run Length Encoded' Dicom encapsulated file.
Definition at line 19 of file gdcmRLE.cxx. References gdcm_read_RLE_fragment(), gdcmHeader::GetBitsAllocated(), gdcmParser::GetSwapCode(), gdcmHeader::GetXSize(), gdcmHeader::GetYSize(), gdcmHeader::GetZSize(), Header, lgrTotale, str2num, gdcmParser::SwapLong(), and gdcmParser::SwapShort(). Referenced by ReadPixelData().
00019 {
00020 long fragmentBegining; // for ftell, fseek
00021 char * im = (char *)image_buffer;
00022
00023 long RleSegmentLength[15],fragmentLength,uncompressedSegmentSize;;
00024 long ftellRes, ln;
00025 guint32 nbRleSegments;
00026 guint32 RleSegmentOffsetTable[15];
00027 guint16 ItemTagGr,ItemTagEl;
00028 uncompressedSegmentSize=Header->GetXSize()*Header->GetYSize();
00029 ftellRes=ftell(fp);
00030 // Basic Offset Table with Item Value
00031 // Item Tag
00032 fread(&ItemTagGr,2,1,fp); // Reading (fffe):Basic Offset Table Item Tag Gr
00033 fread(&ItemTagEl,2,1,fp); // Reading (e000):Basic Offset Table Item Tag El
00034 if(Header->GetSwapCode()) {
00035 ItemTagGr=Header->SwapShort(ItemTagGr);
00036 ItemTagEl=Header->SwapShort(ItemTagEl);
00037 }
00038 // Item Length
00039 ftellRes=ftell(fp);
00040 fread(&ln,4,1,fp);
00041 if(Header->GetSwapCode())
00042 ln=Header->SwapLong(ln); // Basic Offset Table Item Lentgh
00043 if (ln != 0) {
00044 // What is it used for ??
00045 char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
00046 fread(BasicOffsetTableItemValue,ln,1,fp);
00047 guint32 a;
00048 for (int i=0;i<ln;i+=4){
00049 a=str2num(&BasicOffsetTableItemValue[i],guint32);
00050 }
00051 }
00052
00053 ftellRes=ftell(fp);
00054 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
00055 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
00056 if(Header->GetSwapCode()) {
00057 ItemTagGr=Header->SwapShort(ItemTagGr);
00058 ItemTagEl=Header->SwapShort(ItemTagEl);
00059 }
00060
00061 // while 'Sequence Delimiter Item' (fffe,e0dd) not found
00062 while ( ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) {
00063 // Parse fragments of the current Fragment (Frame)
00064 ftellRes=ftell(fp);
00065 fread(&fragmentLength,4,1,fp);
00066 if(Header->GetSwapCode())
00067 fragmentLength=Header->SwapLong(fragmentLength); // length
00068
00069 //------------------ scanning (not reading) fragment pixels
00070
00071 fread(&nbRleSegments,4,1,fp); // Reading : Number of RLE Segments
00072 if(Header->GetSwapCode())
00073 nbRleSegments=Header->SwapLong(nbRleSegments);
00074
00075 for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
00076 ftellRes=ftell(fp);
00077 fread(&RleSegmentOffsetTable[k],4,1,fp);
00078 if(Header->GetSwapCode())
00079 RleSegmentOffsetTable[k]=Header->SwapLong(RleSegmentOffsetTable[k]);
00080 }
00081
00082 if (nbRleSegments>1) {
00083 for(int k=1; k<=nbRleSegments-1; k++) { // reading RLE Segments
00084 RleSegmentLength[k]=RleSegmentOffsetTable[k+1]-RleSegmentOffsetTable[k];
00085 ftellRes=ftell(fp);
00086 fragmentBegining=ftell(fp);
00087 gdcm_read_RLE_fragment (&im, RleSegmentLength[k],uncompressedSegmentSize,fp);
00088 fseek(fp,fragmentBegining,SEEK_SET);
00089 fseek(fp,RleSegmentLength[k],SEEK_CUR);
00090 }
00091 }
00092 RleSegmentLength[nbRleSegments] = fragmentLength - RleSegmentOffsetTable[nbRleSegments];
00093 ftellRes=ftell(fp);
00094 fragmentBegining=ftell(fp);
00095 gdcm_read_RLE_fragment (&im, RleSegmentLength[nbRleSegments],uncompressedSegmentSize, fp);
00096 fseek(fp,fragmentBegining,SEEK_SET);
00097 fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR);
00098
00099 // end of scanning fragment pixels
00100
00101 ftellRes=ftell(fp);
00102 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
00103 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
00104 if(Header->GetSwapCode()) {
00105 ItemTagGr=Header->SwapShort(ItemTagGr);
00106 ItemTagEl=Header->SwapShort(ItemTagEl);
00107 }
00108 }
00109
00110 if (Header->GetBitsAllocated()==16) { // try to deal with RLE 16 Bits
00111
00112 im = (char *)image_buffer;
00113 // need to make 16 Bits Pixels from Low Byte and Hight Byte 'Planes'
00114
00115 int l = Header->GetXSize()*Header->GetYSize();
00116 int nbFrames = Header->GetZSize();
00117
00118 char * newDest = (char*) malloc(l*nbFrames*2);
00119 char *x = newDest;
00120 char * a = (char *)image_buffer;
00121 char * b = a + l;
00122
00123 for (int i=0;i<nbFrames;i++) {
00124 for (int j=0;j<l; j++) {
00125 *(x++) = *(a++);
00126 *(x++) = *(b++);
00127 }
00128 }
00129 memmove(image_buffer,newDest,lgrTotale);
00130 free(newDest);
00131 }
00132
00133 return(true);
00134 }
|
|
||||||||||||||||||||
|
Definition at line 139 of file gdcmRLE.cxx. Referenced by gdcm_read_RLE_file().
00140 {
00141 long ftellRes;
00142 int count;
00143 long numberOfOutputBytes=0;
00144 char n, car;
00145 ftellRes =ftell(fp);
00146
00147 while(numberOfOutputBytes<uncompressedSegmentSize) {
00148 ftellRes =ftell(fp);
00149 fread(&n,sizeof(char),1,fp);
00150 count=n;
00151 if (count >= 0 && count <= 127) {
00152 fread(*areaToRead,(count+1)*sizeof(char),1,fp);
00153 *areaToRead+=count+1;
00154 numberOfOutputBytes+=count+1;
00155 } else {
00156 if (count <= -1 && count >= -127) {
00157 fread(&car,sizeof(char),1,fp);
00158 for(int i=0; i<-count+1; i++) {
00159 (*areaToRead)[i]=car;
00160 }
00161 *areaToRead+=(-count+1);
00162 numberOfOutputBytes+=(-count+1);
00163 }
00164 }
00165 // if count = 128 output nothing (See : PS 3.5-2003 Page 86)
00166 }
00167 return 1;
00168 }
|
|
|
Definition at line 101 of file gdcmFile.cxx. References Header.
00101 {
00102 return(Header);
00103 }
|
|
|
Allocates necessary memory, copies the pixel data (image[s]/volume[s]) to newly allocated zone. Transforms YBR pixels into RGB pixels if any Transforms 3 planes R, G, B into a single RGB Plane Transforms single Grey plane + 3 Palettes into a RGB Plane.
Definition at line 195 of file gdcmFile.cxx. References GetImageDataIntoVector(), lgrTotale, PixelData, and PixelRead.
00195 {
00196 PixelData = (void *) malloc(lgrTotale);
00197 if (PixelData)
00198 GetImageDataIntoVector(PixelData, lgrTotale);
00199 PixelRead=0; // no PixelRaw
00200 return(PixelData);
00201 }
|
|
||||||||||||
|
Copies at most MaxSize bytes of pixel data to caller's memory space.
Definition at line 224 of file gdcmFile.cxx. References GetImageDataIntoVectorRaw(), gdcmHeader::GetLUTRGBA(), gdcmHeader::HasLUT(), Header, lgrTotale, lgrTotaleRaw, PixelRead, and gdcmHeader::SetEntryByNumber(). Referenced by GetImageData().
00224 {
00225 size_t l = GetImageDataIntoVectorRaw (destination, MaxSize);
00226 PixelRead=0 ; // no PixelRaw
00227 if (!Header->HasLUT())
00228 return lgrTotale;
00229
00230 // from Lut R + Lut G + Lut B
00231 unsigned char * newDest = (unsigned char *)malloc(lgrTotale);
00232 unsigned char * a = (unsigned char *)destination;
00233 unsigned char * lutRGBA = Header->GetLUTRGBA();
00234 if (lutRGBA) {
00235 int l = lgrTotaleRaw;
00236 memmove(newDest, destination, l);// move Gray pixels to temp area
00237 int j;
00238 for (int i=0;i<l; i++) { // Build RGB Pixels
00239 j=newDest[i]*4;
00240 *a++ = lutRGBA[j];
00241 *a++ = lutRGBA[j+1];
00242 *a++ = lutRGBA[j+2];
00243 }
00244 free(newDest);
00245
00246 // now, it's an RGB image
00247 // Lets's write it in the Header
00248
00249 // CreateOrReplaceIfExist ?
00250
00251 std::string spp = "3"; // Samples Per Pixel
00252 Header->SetEntryByNumber(spp,0x0028,0x0002);
00253 std::string rgb= "RGB "; // Photometric Interpretation
00254 Header->SetEntryByNumber(rgb,0x0028,0x0004);
00255 std::string planConfig = "0"; // Planar Configuration
00256 Header->SetEntryByNumber(planConfig,0x0028,0x0006);
00257
00258 } else {
00259 // need to make RGB Pixels (?)
00260 // from grey Pixels (?!)
00261 // and Gray Lut (!?!)
00262 // or Segmented xxx Palette Color Lookup Table Data and so on
00263
00264 // Oops! I get one (gdcm-US-ALOKA-16.dcm)
00265 // No idea how to manage such an image
00266 // It seems that *no Dicom Viewer* has any idea :-(
00267 // Segmented xxx Palette Color are *more* than 65535 long ?!?
00268
00269 std::string rgb= "MONOCHROME1 "; // Photometric Interpretation
00270 Header->SetEntryByNumber(rgb,0x0028,0x0004);
00271 }
00272 // TODO : Drop Palette Color out of the Header?
00273 return lgrTotale;
00274 }
|
|
||||||||||||
|
Copies at most MaxSize bytes of pixel data to caller's memory space.
Definition at line 322 of file gdcmFile.cxx. References dbg, GDCM_UNFOUND, gdcmHeader::GetEntryByNumber(), gdcmHeader::GetPlanarConfiguration(), gdcmParser::GetSwapCode(), gdcmHeader::GetXSize(), gdcmHeader::GetYSize(), gdcmHeader::GetZSize(), Header, lgrTotale, PixelRead, ReadPixelData(), gdcmHeader::SetEntryByNumber(), SwapZone(), and gdcmDebug::Verbose(). Referenced by GetImageDataIntoVector(), and GetImageDataRaw().
00322 {
00323
00324 int nb, nbu, highBit, signe;
00325 std::string str_nbFrames, str_nb, str_nbu, str_highBit, str_signe;
00326 PixelRead=1 ; // PixelRaw
00327
00328 if ( lgrTotale > MaxSize ) {
00329 dbg.Verbose(0, "gdcmFile::GetImageDataIntoVector: pixel data bigger"
00330 "than caller's expected MaxSize");
00331 return (size_t)0;
00332 }
00333
00334 (void)ReadPixelData(destination);
00335
00336 // Number of Bits Allocated for storing a Pixel
00337 str_nb = Header->GetEntryByNumber(0x0028,0x0100);
00338 if (str_nb == GDCM_UNFOUND ) {
00339 nb = 16;
00340 } else {
00341 nb = atoi(str_nb.c_str() );
00342 }
00343 // Number of Bits actually used
00344 str_nbu=Header->GetEntryByNumber(0x0028,0x0101);
00345 if (str_nbu == GDCM_UNFOUND ) {
00346 nbu = nb;
00347 } else {
00348 nbu = atoi(str_nbu.c_str() );
00349 }
00350 // High Bit Position
00351 str_highBit=Header->GetEntryByNumber(0x0028,0x0102);
00352 if (str_highBit == GDCM_UNFOUND ) {
00353 highBit = nb - 1;
00354 } else {
00355 highBit = atoi(str_highBit.c_str() );
00356 }
00357 // Pixel sign
00358 // 0 = Unsigned
00359 // 1 = Signed
00360 str_signe=Header->GetEntryByNumber(0x0028,0x0103);
00361 if (str_signe == GDCM_UNFOUND ) {
00362 signe = 0; // default is unsigned
00363 } else {
00364 signe = atoi(str_signe.c_str() );
00365 }
00366
00367 // re arange bytes inside the integer (processor endianity)
00368 if (nb != 8)
00369 SwapZone(destination, Header->GetSwapCode(), lgrTotale, nb);
00370
00371 // to avoid pb with some xmedcon breakers images
00372 if (nb==16 && nbu<nb && signe==0) {
00373 int l = (int)lgrTotale / (nb/8);
00374 guint16 *deb = (guint16 *)destination;
00375 for(int i = 0; i<l; i++) {
00376 if(*deb == 0xffff)
00377 *deb=0;
00378 deb++;
00379 }
00380 }
00381
00382 // re arange bits inside the bytes
00383 if (nbu != nb){
00384 int l = (int)lgrTotale / (nb/8);
00385 if (nb == 16) {
00386 guint16 mask = 0xffff;
00387 mask = mask >> (nb-nbu);
00388 guint16 *deb = (guint16 *)destination;
00389 for(int i = 0; i<l; i++) {
00390 *deb = (*deb >> (nbu-highBit-1)) & mask;
00391 deb ++;
00392 }
00393 } else if (nb == 32 ) {
00394 guint32 mask = 0xffffffff;
00395 mask = mask >> (nb-nbu);
00396 guint32 *deb = (guint32 *)destination;
00397 for(int i = 0; i<l; i++) {
00398 *deb = (*deb >> (nbu-highBit-1)) & mask;
00399 deb ++;
00400 }
00401 } else {
00402 dbg.Verbose(0, "gdcmFile::GetImageDataIntoVector: wierd image");
00403 return (size_t)0;
00404 }
00405 }
00406 // DO NOT remove this code commented out.
00407 // Nobody knows what's expecting you ...
00408 // Just to 'see' what was actually read on disk :-(
00409
00410 // FILE * f2;
00411 // f2 = fopen("SpuriousFile.RAW","wb");
00412 // fwrite(destination,lgrTotale,1,f2);
00413 // fclose(f2);
00414
00415 // Deal with the color
00416 // -------------------
00417
00418 std::string str_PhotometricInterpretation =
00419 Header->GetEntryByNumber(0x0028,0x0004);
00420
00421 if ( (str_PhotometricInterpretation == "MONOCHROME1 ")
00422 || (str_PhotometricInterpretation == "MONOCHROME2 ") ) {
00423 return lgrTotale;
00424 }
00425
00426 // Planar configuration = 0 : Pixels are already RGB
00427 // Planar configuration = 1 : 3 planes : R, G, B
00428 // Planar configuration = 2 : 1 gray Plane + 3 LUT
00429
00430 // Well ... supposed to be !
00431 // See US-PAL-8-10x-echo.dcm: PlanarConfiguration=0,
00432 // PhotometricInterpretation=PALETTE COLOR
00433 // and heuristic has to be found :-(
00434
00435 int planConf=Header->GetPlanarConfiguration(); // 0028,0006
00436
00437 // Whatever Planar Configuration is,
00438 // "PALETTE COLOR " implies that we deal with the palette.
00439 if (str_PhotometricInterpretation == "PALETTE COLOR ")
00440 planConf=2;
00441
00442 switch (planConf) {
00443 case 0:
00444 // Pixels are already RGB
00445 break;
00446
00447 case 1:
00448
00449 {
00450 if (str_PhotometricInterpretation == "YBR_FULL") {
00451
00452 // Warning : YBR_FULL_422 acts as RGB
00453 // : we need to make RGB Pixels from Planes Y,cB,cR
00454
00455 // to see the tricks about YBR_FULL, YBR_FULL_422,
00456 // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at :
00457 // ftp://medical.nema.org/medical/dicom/final/sup61_ft.pdf
00458 // and be *very* affraid
00459 //
00460 int l = Header->GetXSize()*Header->GetYSize();
00461 int nbFrames = Header->GetZSize();
00462
00463 unsigned char * newDest = (unsigned char*) malloc(lgrTotale);
00464 unsigned char *x = newDest;
00465 unsigned char * a = (unsigned char *)destination;
00466 unsigned char * b = a + l;
00467 unsigned char * c = b + l;
00468 double R,G,B;
00469
00470 // TODO : Replace by the 'well known'
00471 // integer computation counterpart
00472 // see http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
00473 // for code optimisation
00474
00475 for (int i=0;i<nbFrames;i++) {
00476 for (int j=0;j<l; j++) {
00477 R= 1.164 *(*a-16) + 1.596 *(*c -128) + 0.5;
00478 G= 1.164 *(*a-16) - 0.813 *(*c -128) - 0.392 *(*b -128) + 0.5;
00479 B= 1.164 *(*a-16) + 2.017 *(*b -128) + 0.5;
00480
00481 if (R<0.0) R=0.0;
00482 if (G<0.0) G=0.0;
00483 if (B<0.0) B=0.0;
00484 if (R>255.0) R=255.0;
00485 if (G>255.0) G=255.0;
00486 if (B>255.0) B=255.0;
00487
00488 *(x++) = (unsigned char)R;
00489 *(x++) = (unsigned char)G;
00490 *(x++) = (unsigned char)B;
00491 a++; b++; c++;
00492 }
00493 }
00494 memmove(destination,newDest,lgrTotale);
00495 free(newDest);
00496
00497 } else {
00498
00499 // need to make RGB Pixels from R,G,B Planes
00500 // (all the Frames at a time)
00501
00502 int l = Header->GetXSize()*Header->GetYSize()*Header->GetZSize();
00503
00504 char * newDest = (char*) malloc(lgrTotale);
00505 char * x = newDest;
00506 char * a = (char *)destination;
00507 char * b = a + l;
00508 char * c = b + l;
00509
00510 for (int j=0;j<l; j++) {
00511 *(x++) = *(a++);
00512 *(x++) = *(b++);
00513 *(x++) = *(c++);
00514 }
00515 memmove(destination,newDest,lgrTotale);
00516 free(newDest);
00517 }
00518 break;
00519 }
00520 case 2:
00521 // Palettes were found
00522 // Let the user deal with them !
00523 return lgrTotale;
00524 }
00525 // now, it's an RGB image
00526 // Lets's write it in the Header
00527
00528 // CreateOrReplaceIfExist ?
00529
00530 std::string spp = "3"; // Samples Per Pixel
00531 Header->SetEntryByNumber(spp,0x0028,0x0002);
00532 std::string rgb="RGB "; // Photometric Interpretation
00533 Header->SetEntryByNumber(rgb,0x0028,0x0004);
00534
00535 std::string planConfig = "0"; // Planar Configuration
00536 Header->SetEntryByNumber(planConfig,0x0028,0x0006);
00537
00538 // TODO : Drop Palette Color out of the Header?
00539 return lgrTotale;
00540 }
|
|
|
Allocates necessary memory, copies the pixel data (image[s]/volume[s]) to newly allocated zone. Transforms YBR pixels into RGB pixels if any Transforms 3 planes R, G, B into a single RGB Plane DOES NOT transform Grey plane + 3 Palettes into a RGB Plane.
Definition at line 286 of file gdcmFile.cxx. References GetImageDataIntoVectorRaw(), gdcmHeader::HasLUT(), Header, lgrTotale, PixelData, and PixelRead.
00286 {
00287 if (Header->HasLUT())
00288 lgrTotale /= 3; // TODO Let gdcmHeadar user a chance
00289 // to get the right value
00290 // Create a member lgrTotaleRaw ???
00291 PixelData = (void *) malloc(lgrTotale);
00292 if (PixelData)
00293 GetImageDataIntoVectorRaw(PixelData, lgrTotale);
00294 PixelRead=1; // PixelRaw
00295 return(PixelData);
00296 }
|
|
|
Returns the size (in bytes) of required memory to hold the pixel data represented in this file.
Definition at line 168 of file gdcmFile.cxx. References lgrTotale.
00168 {
00169 return (lgrTotale);
00170 }
|
|
|
Returns the size (in bytes) of required memory to hold the pixel data represented in this file, when user DOESN'T want to get RGB pixels image when it's stored as a PALETTE COLOR image -the (vtk) user is supposed to know how deal with LUTs-.
Definition at line 181 of file gdcmFile.cxx. References lgrTotaleRaw.
00181 {
00182 return (lgrTotaleRaw);
00183 }
|
|
|
Parse pixel data from disk and *prints* the result \ For multi-fragment Jpeg/Rle files checking purpose *only* \ Allows to 'see' if the file *does* conform \ (some of them do not) \ with Dicom Part 3, Annex A (PS 3.5-2003, page 58, page 85).
Definition at line 30 of file gdcmParsePixels.cxx. References gdcmParser::CloseFile(), GDCM_UNFOUND, gdcmHeader::GetEntryByNumber(), gdcmHeader::GetPixelOffset(), gdcmHeader::GetSamplesPerPixel(), gdcmParser::GetSwapCode(), gdcmHeader::GetXSize(), gdcmHeader::GetYSize(), Header, gdcmParser::IsDeflatedExplicitVRLittleEndianTransferSyntax(), gdcmHeader::IsDicomV3(), gdcmParser::IsExplicitVRBigEndianTransferSyntax(), gdcmParser::IsExplicitVRLittleEndianTransferSyntax(), gdcmParser::IsImplicitVRLittleEndianTransferSyntax(), gdcmHeader::IsRLELossLessTransferSyntax(), gdcmParser::OpenFile(), str2num, gdcmParser::SwapLong(), and gdcmParser::SwapShort().
00030 {
00031 // DO NOT remove the printf s.
00032 // The ONLY purpose of this method is to PRINT the content
00033 FILE *fp;
00034
00035 if ( !(fp=Header->OpenFile()))
00036 return false;
00037
00038 if ( fseek(fp, Header->GetPixelOffset(), SEEK_SET) == -1 ) {
00039 Header->CloseFile();
00040 return false;
00041 }
00042
00043 if ( !Header->IsDicomV3() ||
00044 Header->IsImplicitVRLittleEndianTransferSyntax() ||
00045 Header->IsExplicitVRLittleEndianTransferSyntax() ||
00046 Header->IsExplicitVRBigEndianTransferSyntax() ||
00047 Header->IsDeflatedExplicitVRLittleEndianTransferSyntax() ) {
00048
00049 printf ("gdcmFile::ParsePixelData : non JPEG/RLE File\n");
00050 return false;
00051 }
00052
00053 int nb;
00054 std::string str_nb=Header->GetEntryByNumber(0x0028,0x0100);
00055 if (str_nb == GDCM_UNFOUND ) {
00056 nb = 16;
00057 } else {
00058 nb = atoi(str_nb.c_str() );
00059 if (nb == 12) nb =16;
00060 }
00061 int nBytes= nb/8;
00062
00063 int taille = Header->GetXSize() * Header->GetYSize() * Header->GetSamplesPerPixel();
00064
00065 printf ("Checking the Dicom-encapsulated Jpeg/RLE Pixels\n");
00066
00067 guint16 ItemTagGr,ItemTagEl;
00068 int ln;
00069 long ftellRes;
00070 char * destination = NULL;
00071
00072 // -------------------- for Parsing : Position on begining of Jpeg/RLE Pixels
00073
00074 if( !Header->IsRLELossLessTransferSyntax()) {
00075
00076 // JPEG Image
00077 ftellRes=ftell(fp);
00078 fread(&ItemTagGr,2,1,fp); //Reading (fffe):Basic Offset Table Item Tag Gr
00079 fread(&ItemTagEl,2,1,fp); //Reading (e000):Basic Offset Table Item Tag El
00080 if(Header->GetSwapCode()) {
00081 ItemTagGr=Header->SwapShort(ItemTagGr);
00082 ItemTagEl=Header->SwapShort(ItemTagEl);
00083 }
00084 printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n",
00085 ftellRes,ItemTagGr,ItemTagEl );
00086 ftellRes=ftell(fp);
00087 fread(&ln,4,1,fp);
00088 if(Header->GetSwapCode())
00089 ln=Header->SwapLong(ln); // Basic Offset Table Item Length
00090 printf("at %x : Basic Offset Table Item Length (??) %d x(%08x)\n",
00091 ftellRes,ln,ln);
00092 if (ln != 0) {
00093 // What is it used for ??
00094 char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
00095 fread(BasicOffsetTableItemValue,ln,1,fp);
00096 guint32 a;
00097 for (int i=0;i<ln;i+=4){
00098 a=str2num(&BasicOffsetTableItemValue[i],guint32);
00099 printf(" x(%08x) %d\n",a,a);
00100 }
00101 }
00102
00103 ftellRes=ftell(fp);
00104 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
00105 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
00106 if(Header->GetSwapCode()) {
00107 ItemTagGr=Header->SwapShort(ItemTagGr);
00108 ItemTagEl=Header->SwapShort(ItemTagEl);
00109 }
00110 printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
00111 ftellRes,ItemTagGr,ItemTagEl );
00112
00113 while ( ( ItemTagGr==0xfffe) && (ItemTagEl!=0xe0dd) ) { // Parse fragments
00114
00115 ftellRes=ftell(fp);
00116 fread(&ln,4,1,fp);
00117 if(Header->GetSwapCode())
00118 ln=Header->SwapLong(ln); // length
00119 printf(" at %x : fragment length %d x(%08x)\n",
00120 ftellRes, ln,ln);
00121
00122 // destination += taille * nBytes; // location in user's memory
00123 //printf (" Destination will be x(%x) = %d \n",
00124 // destination,destination );
00125
00126 // ------------------------
00127 fseek(fp,ln,SEEK_CUR); // skipping (not reading) fragment pixels
00128 // ------------------------
00129
00130 ftellRes=ftell(fp);
00131 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
00132 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
00133 if(Header->GetSwapCode()) {
00134 ItemTagGr=Header->SwapShort(ItemTagGr);
00135 ItemTagEl=Header->SwapShort(ItemTagEl);
00136 }
00137 printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
00138 ftellRes,ItemTagGr,ItemTagEl );
00139 }
00140
00141 } else {
00142
00143 // RLE Image
00144 long RleSegmentLength[15],fragmentLength;
00145 guint32 nbRleSegments;
00146 guint32 RleSegmentOffsetTable[15];
00147 ftellRes=ftell(fp);
00148 // Basic Offset Table with Item Value
00149 // Item Tag
00150 fread(&ItemTagGr,2,1,fp); //Reading (fffe):Basic Offset Table Item Tag Gr
00151 fread(&ItemTagEl,2,1,fp); //Reading (e000):Basic Offset Table Item Tag El
00152 if(Header->GetSwapCode()) {
00153 ItemTagGr=Header->SwapShort(ItemTagGr);
00154 ItemTagEl=Header->SwapShort(ItemTagEl);
00155 }
00156 printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n",
00157 ftellRes,ItemTagGr,ItemTagEl );
00158 // Item Length
00159 ftellRes=ftell(fp);
00160 fread(&ln,4,1,fp);
00161 if(Header->GetSwapCode())
00162 ln=Header->SwapLong(ln); // Basic Offset Table Item Length
00163 printf("at %x : Basic Offset Table Item Length (??) %d x(%08x)\n",
00164 ftellRes,ln,ln);
00165 if (ln != 0) {
00166 // What is it used for ??
00167 char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
00168 fread(BasicOffsetTableItemValue,ln,1,fp);
00169 guint32 a;
00170 for (int i=0;i<ln;i+=4){
00171 a=str2num(&BasicOffsetTableItemValue[i],guint32);
00172 printf(" x(%08x) %d\n",a,a);
00173 }
00174 }
00175
00176 ftellRes=ftell(fp);
00177 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
00178 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
00179 if(Header->GetSwapCode()) {
00180 ItemTagGr=Header->SwapShort(ItemTagGr);
00181 ItemTagEl=Header->SwapShort(ItemTagEl);
00182 }
00183 printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
00184 ftellRes,ItemTagGr,ItemTagEl );
00185
00186 // while 'Sequence Delimiter Item' (fffe,e0dd) not found
00187 while ( ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) {
00188 // Parse fragments of the current Fragment (Frame)
00189 ftellRes=ftell(fp);
00190 fread(&fragmentLength,4,1,fp);
00191 if(Header->GetSwapCode())
00192 fragmentLength=Header->SwapLong(fragmentLength); // length
00193 printf(" at %x : 'fragment' length %d x(%08x)\n",
00194 ftellRes, fragmentLength,fragmentLength);
00195
00196 //------------------ scanning (not reading) fragment pixels
00197
00198 fread(&nbRleSegments,4,1,fp); // Reading : Number of RLE Segments
00199 if(Header->GetSwapCode())
00200 nbRleSegments=Header->SwapLong(nbRleSegments);
00201 printf(" Nb of RLE Segments : %d\n",nbRleSegments);
00202
00203 for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
00204 ftellRes=ftell(fp);
00205 fread(&RleSegmentOffsetTable[k],4,1,fp);
00206 if(Header->GetSwapCode())
00207 RleSegmentOffsetTable[k]=Header->SwapLong(RleSegmentOffsetTable[k]);
00208 printf(" at : %x Offset Segment %d : %d (%x)\n",
00209 ftellRes,k,RleSegmentOffsetTable[k],
00210 RleSegmentOffsetTable[k]);
00211 }
00212
00213 if (nbRleSegments>1) { // skipping (not reading) RLE Segments
00214 for(int k=1; k<=nbRleSegments-1; k++) {
00215 RleSegmentLength[k]= RleSegmentOffsetTable[k+1]
00216 - RleSegmentOffsetTable[k];
00217 ftellRes=ftell(fp);
00218 printf (" Segment %d : Length = %d x(%x) Start at %x\n",
00219 k,RleSegmentLength[k],RleSegmentLength[k], ftellRes);
00220 fseek(fp,RleSegmentLength[k],SEEK_CUR);
00221 }
00222 }
00223 RleSegmentLength[nbRleSegments]= fragmentLength
00224 - RleSegmentOffsetTable[nbRleSegments];
00225 ftellRes=ftell(fp);
00226 printf (" Segment %d : Length = %d x(%x) Start at %x\n",
00227 nbRleSegments,RleSegmentLength[nbRleSegments],
00228 RleSegmentLength[nbRleSegments],ftellRes);
00229
00230 fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR);
00231
00232 // ------------------ end of scanning fragment pixels
00233
00234 ftellRes=ftell(fp);
00235 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
00236 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
00237 if(Header->GetSwapCode()) {
00238 ItemTagGr=Header->SwapShort(ItemTagGr);
00239 ItemTagEl=Header->SwapShort(ItemTagEl);
00240 }
00241 printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
00242 ftellRes,ItemTagGr,ItemTagEl );
00243 }
00244 }
00245 return true;
00246 }
|
|
|
Read pixel data from disk (optionaly decompressing) into the caller specified memory location.
Definition at line 830 of file gdcmFile.cxx. References gdcmParser::CloseFile(), gdcm_read_JPEG2000_file(), gdcm_read_JPEG_file(), gdcm_read_JPEG_file12(), gdcm_read_RLE_file(), GDCM_UNFOUND, gdcmHeader::GetBitsAllocated(), gdcmHeader::GetBitsStored(), gdcmHeader::GetEntryByNumber(), gdcmHeader::GetPixelAreaLength(), gdcmHeader::GetPixelOffset(), gdcmHeader::GetPixelSize(), gdcmHeader::GetSamplesPerPixel(), gdcmParser::GetSwapCode(), gdcmHeader::GetXSize(), gdcmHeader::GetYSize(), Header, gdcmParser::IsDeflatedExplicitVRLittleEndianTransferSyntax(), gdcmHeader::IsDicomV3(), gdcmParser::IsExplicitVRBigEndianTransferSyntax(), gdcmParser::IsExplicitVRLittleEndianTransferSyntax(), gdcmParser::IsImplicitVRLittleEndianTransferSyntax(), gdcmHeader::IsJPEG2000(), gdcmHeader::IsJPEGLossless(), gdcmHeader::IsRLELossLessTransferSyntax(), gdcmParser::OpenFile(), gdcmParser::SwapLong(), and gdcmParser::SwapShort(). Referenced by GetImageDataIntoVectorRaw().
00830 {
00831
00832 FILE *fp;
00833
00834 if ( !(fp=Header->OpenFile()))
00835 return false;
00836 if ( fseek(fp, Header->GetPixelOffset(), SEEK_SET) == -1 ) {
00837 Header->CloseFile();
00838 return false;
00839 }
00840 // ---------------------- Compacted File (12 Bits Per Pixel)
00841 /* unpack 12 Bits pixels into 16 Bits pixels */
00842 /* 2 pixels 12bit = [0xABCDEF] */
00843 /* 2 pixels 16bit = [0x0ABD] + [0x0FCE] */
00844
00845 if (Header->GetBitsAllocated()==12) {
00846 int nbPixels = Header->GetXSize() * Header->GetYSize();
00847 unsigned char b0, b1, b2;
00848
00849 unsigned short int* pdestination = (unsigned short int*)destination;
00850 for(int p=0;p<nbPixels;p+=2) {
00851 fread(&b0,1,1,fp);
00852 fread(&b1,1,1,fp);
00853 fread(&b2,1,1,fp);
00854 //Two steps is necessary to please VC++
00855 *pdestination++ = ((b0 >> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
00856 /* A */ /* B */ /* D */
00857 *pdestination++ = ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4);
00858 /* F */ /* C */ /* E */
00859
00860 // Troubles expected on Big-Endian processors ?
00861 }
00862
00863 Header->CloseFile();
00864 return(true);
00865 }
00866
00867 // ---------------------- Uncompressed File
00868 if ( !Header->IsDicomV3() ||
00869 Header->IsImplicitVRLittleEndianTransferSyntax() ||
00870 Header->IsExplicitVRLittleEndianTransferSyntax() ||
00871 Header->IsExplicitVRBigEndianTransferSyntax() ||
00872 Header->IsDeflatedExplicitVRLittleEndianTransferSyntax() ) {
00873
00874 size_t ItemRead = fread(destination, Header->GetPixelAreaLength(), 1, fp);
00875 if ( ItemRead != 1 ) {
00876 Header->CloseFile();
00877 return false;
00878 } else {
00879 Header->CloseFile();
00880 return true;
00881 }
00882 }
00883
00884 // ---------------------- Run Length Encoding
00885 if (Header->IsRLELossLessTransferSyntax()) {
00886 bool res = (bool)gdcm_read_RLE_file (fp,destination);
00887 Header->CloseFile();
00888 return res;
00889 }
00890
00891 // --------------- SingleFrame/Multiframe JPEG Lossless/Lossy/2000
00892 int nb;
00893 std::string str_nb=Header->GetEntryByNumber(0x0028,0x0100);
00894 if (str_nb == GDCM_UNFOUND ) {
00895 nb = 16;
00896 } else {
00897 nb = atoi(str_nb.c_str() );
00898 if (nb == 12) nb =16; // ?? 12 should be ACR-NEMA only ?
00899 }
00900
00901 int nBytes= nb/8;
00902
00903 int taille = Header->GetXSize() * Header->GetYSize()
00904 * Header->GetSamplesPerPixel();
00905 long fragmentBegining; // for ftell, fseek
00906
00907 bool jpg2000 = Header->IsJPEG2000();
00908 bool jpgLossless = Header->IsJPEGLossless();
00909
00910 bool res = true;
00911 guint16 ItemTagGr,ItemTagEl;
00912 int ln;
00913
00914 // Position on begining of Jpeg Pixels
00915
00916 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
00917 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
00918 if(Header->GetSwapCode()) {
00919 ItemTagGr=Header->SwapShort(ItemTagGr);
00920 ItemTagEl=Header->SwapShort(ItemTagEl);
00921 }
00922 fread(&ln,4,1,fp);
00923 if(Header->GetSwapCode())
00924 ln=Header->SwapLong(ln); // Basic Offset Table Item length
00925
00926 if (ln != 0) {
00927 // What is it used for ?!?
00928 char *BasicOffsetTableItemValue = (char *)malloc(ln+1);
00929 fread(BasicOffsetTableItemValue,ln,1,fp);
00930 }
00931
00932 // first Fragment initialisation
00933 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
00934 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
00935 if(Header->GetSwapCode()) {
00936 ItemTagGr=Header->SwapShort(ItemTagGr);
00937 ItemTagEl=Header->SwapShort(ItemTagEl);
00938 }
00939
00940 // parsing fragments until Sequence Delim. Tag found
00941 while ( ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) {
00942 // --- for each Fragment
00943
00944 fread(&ln,4,1,fp);
00945 if(Header->GetSwapCode())
00946 ln=Header->SwapLong(ln); // Fragment Item length
00947
00948 fragmentBegining=ftell(fp);
00949
00950 if (jpg2000) { // JPEG 2000 : call to ???
00951
00952 res = (bool)gdcm_read_JPEG2000_file (fp,destination); // Not Yet written
00953
00954 } // ------------------------------------- endif (JPEG2000)
00955
00956 else if (jpgLossless) { // JPEG LossLess : call to xmedcom JPEG
00957
00958 JPEGLosslessDecodeImage (fp, // Reading Fragment pixels
00959 (unsigned short *)destination,
00960 Header->GetPixelSize()*8* Header->GetSamplesPerPixel(),
00961 ln);
00962 res=1; // in order not to break the loop
00963
00964 } // ------------------------------------- endif (JPEGLossless)
00965
00966 else { // JPEG Lossy : call to IJG 6b
00967
00968 if (Header->GetBitsStored() == 8) {
00969 res = (bool)gdcm_read_JPEG_file (fp,destination); // Reading Fragment pixels
00970 } else {
00971 res = (bool)gdcm_read_JPEG_file12 (fp,destination);// Reading Fragment pixels
00972 }
00973 } // ------------------------------------- endif (JPEGLossy)
00974
00975 if (!res) break;
00976
00977 destination = (char *)destination + taille * nBytes; // location in user's memory
00978 // for next fragment (if any)
00979
00980 fseek(fp,fragmentBegining,SEEK_SET); // To be sure we start
00981 fseek(fp,ln,SEEK_CUR); // at the begining of next fragment
00982
00983 ItemTagGr = ItemTagEl =0;
00984 fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
00985 fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
00986 if(Header->GetSwapCode()) {
00987 ItemTagGr=Header->SwapShort(ItemTagGr);
00988 ItemTagEl=Header->SwapShort(ItemTagEl);
00989 }
00990
00991 } // endWhile parsing fragments until Sequence Delim. Tag found
00992
00993 Header->CloseFile();
00994 return res;
00995 }
|
|
||||||||||||
|
TODO JPR.
Definition at line 553 of file gdcmFile.cxx. References Header, lgrTotale, PixelData, and gdcmHeader::SetImageDataSize().
00553 {
00554 Header->SetImageDataSize(ExpectedSize);
00555 PixelData = inData;
00556 lgrTotale = ExpectedSize;
00557 return(true);
00558 }
|
|
|
computes the length (in bytes) to ALLOCATE to receive the image(s) pixels (multiframes taken into account)
Definition at line 113 of file gdcmFile.cxx. References GDCM_UNFOUND, gdcmHeader::GetEntryByNumber(), gdcmHeader::GetSamplesPerPixel(), gdcmHeader::GetXSize(), gdcmHeader::GetYSize(), gdcmHeader::GetZSize(), gdcmHeader::HasLUT(), Header, lgrTotale, and lgrTotaleRaw. Referenced by gdcmFile().
00113 {
00114 // see PS 3.3-2003 : C.7.6.3.2.1
00115 //
00116 // MONOCHROME1
00117 // MONOCHROME2
00118 // PALETTE COLOR
00119 // RGB
00120 // HSV (Retired)
00121 // ARGB (Retired)
00122 // CMYK (Retired)
00123 // YBR_FULL
00124 // YBR_FULL_422 (no LUT, no Palette)
00125 // YBR_PARTIAL_422
00126 // YBR_ICT
00127 // YBR_RCT
00128
00129 // LUT's
00130 // ex : gdcm-US-ALOKA-16.dcm
00131 // 0028|1221 [OW] [Segmented Red Palette Color Lookup Table Data]
00132 // 0028|1222 [OW] [Segmented Green Palette Color Lookup Table Data]
00133 // 0028|1223 [OW] [Segmented Blue Palette Color Lookup Table Data]
00134
00135 // ex : OT-PAL-8-face.dcm
00136 // 0028|1201 [US] [Red Palette Color Lookup Table Data]
00137 // 0028|1202 [US] [Green Palette Color Lookup Table Data]
00138 // 0028|1203 [US] [Blue Palette Color Lookup Table Data]
00139
00140 int nb;
00141 std::string str_nb;
00142 str_nb=Header->GetEntryByNumber(0x0028,0x0100);
00143 if (str_nb == GDCM_UNFOUND ) {
00144 nb = 16;
00145 } else {
00146 nb = atoi(str_nb.c_str() );
00147 if (nb == 12) nb =16;
00148 }
00149 lgrTotale = lgrTotaleRaw = Header->GetXSize() * Header->GetYSize()
00150 * Header->GetZSize() * (nb/8)* Header->GetSamplesPerPixel();
00151 std::string str_PhotometricInterpretation =
00152 Header->GetEntryByNumber(0x0028,0x0004);
00153
00154 /*if ( str_PhotometricInterpretation == "PALETTE COLOR " )*/
00155 // pb when undealt Segmented Palette Color
00156
00157 if (Header->HasLUT()) {
00158 lgrTotale*=3;
00159 }
00160 }
|
|
||||||||||||||||||||
|
Swap the bytes, according to swap code.
Definition at line 754 of file gdcmFile.cxx. Referenced by GetImageDataIntoVectorRaw().
00754 {
00755 guint32 s32;
00756 guint16 fort,faible;
00757 int i;
00758
00759 if(nb == 16)
00760 switch(swap) {
00761 case 0:
00762 case 12:
00763 case 1234:
00764 break;
00765
00766 case 21:
00767 case 3412:
00768 case 2143:
00769 case 4321:
00770
00771 for(i=0;i<lgr;i++)
00772 ((unsigned short int*)im)[i]= ((((unsigned short int*)im)[i])>>8)
00773 | ((((unsigned short int*)im)[i])<<8);
00774 break;
00775
00776 default:
00777 printf("SWAP value (16 bits) not allowed : %d\n", swap);
00778 }
00779
00780 if( nb == 32 )
00781 switch (swap) {
00782 case 0:
00783 case 1234:
00784 break;
00785
00786 case 4321:
00787 for(i=0;i<lgr;i++) {
00788 faible= ((unsigned long int*)im)[i]&0x0000ffff; /* 4321 */
00789 fort =((unsigned long int*)im)[i]>>16;
00790 fort= (fort>>8) | (fort<<8);
00791 faible=(faible>>8) | (faible<<8);
00792 s32=faible;
00793 ((unsigned long int*)im)[i]=(s32<<16)|fort;
00794 }
00795 break;
00796
00797 case 2143:
00798 for(i=0;i<lgr;i++) {
00799 faible= ((unsigned long int*)im)[i]&0x0000ffff; /* 2143 */
00800 fort=((unsigned long int*)im)[i]>>16;
00801 fort= (fort>>8) | (fort<<8);
00802 faible=(faible>>8) | (faible<<8);
00803 s32=fort;
00804 ((unsigned long int*)im)[i]=(s32<<16)|faible;
00805 }
00806 break;
00807
00808 case 3412:
00809 for(i=0;i<lgr;i++) {
00810 faible= ((unsigned long int*)im)[i]&0x0000ffff; /* 3412 */
00811 fort=((unsigned long int*)im)[i]>>16;
00812 s32=faible;
00813 ((unsigned long int*)im)[i]=(s32<<16)|fort;
00814 }
00815 break;
00816
00817 default:
00818 printf("SWAP value (32 bits) not allowed : %d\n", swap);
00819 }
00820 return;
00821 }
|
|
|
Ecrit au format ACR-NEMA sur disque l'entete et les pixels (a l'attention des logiciels cliniques qui ne prennent en entrée QUE des images ACR ...
Definition at line 635 of file gdcmFile.cxx. References ACR, and WriteBase().
00635 {
00636 return WriteBase(fileName, ACR);
00637 }
|
|
||||||||||||
|
Definition at line 649 of file gdcmFile.cxx. References ACR_LIBIDO, DICOMDIR, ExplicitVR, gdcmParser::GetEntry(), gdcmHeader::GetEntryByNumber(), gdcmParser::GetFileType(), gdcmParser::GetGrPixel(), gdcmParser::GetNumPixel(), Header, IterHT, lgrTotale, lgrTotaleRaw, PixelData, PixelRead, gdcmHeader::SetEntryByNumber(), gdcmHeaderEntry::SetLength(), TagKey, gdcmDictEntry::TranslateToKey(), and gdcmParser::Write(). Referenced by WriteAcr(), WriteDcmExplVR(), and WriteDcmImplVR().
00649 {
00650
00651 FILE * fp1;
00652
00653 if (PixelRead==-1 && type != DICOMDIR) {
00654 /* std::cout << "U never Read the pixels; U cannot write the file"
00655 << std::endl;*/
00656 return false;
00657 }
00658
00659 fp1 = fopen(fileName.c_str(),"wb");
00660 if (fp1 == NULL) {
00661 printf("Failed to open (write) File [%s] \n",fileName.c_str());
00662 return (false);
00663 }
00664
00665 if ( (type == ImplicitVR) || (type == ExplicitVR) ) {
00666 char * filePreamble;
00667 // writing Dicom File Preamble
00668 filePreamble=(char*)calloc(128,1);
00669 fwrite(filePreamble,128,1,fp1);
00670 fwrite("DICM",4,1,fp1);
00671 free (filePreamble);
00672 }
00673
00674 // --------------------------------------------------------------
00675 // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
00676 //
00677 // if recognition code tells us we dealt with a LibIDO image
00678 // we reproduce on disk the switch between lineNumber and columnNumber
00679 // just before writting ...
00680
00681 // TODO : the best trick would be *change* the recognition code
00682 // but pb expected if user deals with, e.g. COMPLEX images
00683
00684 std::string rows, columns;
00685 if ( Header->GetFileType() == ACR_LIBIDO){
00686 rows = Header->GetEntryByNumber(0x0028, 0x0010);
00687 columns = Header->GetEntryByNumber(0x0028, 0x0011);
00688 Header->SetEntryByNumber(columns, 0x0028, 0x0010);
00689 Header->SetEntryByNumber(rows , 0x0028, 0x0011);
00690 }
00691 // ----------------- End of Special Patch ----------------
00692
00693 // TODO : get the grPixel, numPixel values (for some ACR-NEMA images only)
00694
00695 guint16 grPixel =Header->GetGrPixel();
00696 guint16 numPixel=Header->GetNumPixel();;
00697
00698 // Update Pixel Data Length
00699 // the *last* of the (GrPixel, NumPixel), if many.
00700
00701 TagKey key = gdcmDictEntry::TranslateToKey(grPixel, numPixel);
00702 TagHeaderEntryHT::iterator p2;
00703 gdcmHeaderEntry * PixelElement;
00704
00705 IterHT it= Header->GetEntry().equal_range(key); // get a pair of iterators first-last synonym
00706
00707 if (Header->GetEntry().count(key) == 1) // only the first is significant
00708 p2=it.first; // iterator on the first (unique) synonym
00709 else
00710 p2=it.second;// iterator on the last synonym
00711
00712 PixelElement=p2->second; // H Table target column (2-nd col)
00713 // PixelElement->SetPrintLevel(2);
00714 // PixelElement->Print();
00715
00716 if (PixelRead==1)
00717 PixelElement->SetLength(lgrTotaleRaw);
00718 else if (PixelRead==0)
00719 PixelElement->SetLength(lgrTotale);
00720
00721 //PixelElement->SetPrintLevel(2);
00722 //PixelElement->Print();
00723
00724 Header->Write(fp1, type);
00725
00726 // --------------------------------------------------------------
00727 // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
00728 //
00729 // ...and we restore the Header to be Dicom Compliant again
00730 // just after writting
00731
00732 if (Header->GetFileType() == ACR_LIBIDO){
00733 Header->SetEntryByNumber(rows , 0x0028, 0x0010);
00734 Header->SetEntryByNumber(columns, 0x0028, 0x0011);
00735 }
00736 // ----------------- End of Special Patch ----------------
00737
00738 fwrite(PixelData, lgrTotale, 1, fp1);
00739 fclose (fp1);
00740 return(true);
00741 }
|
|
|
Definition at line 615 of file gdcmFile.cxx. References ExplicitVR, and WriteBase().
00615 {
00616 return WriteBase(fileName, ExplicitVR);
00617 }
|
|
|
Definition at line 603 of file gdcmFile.cxx. References WriteDcmImplVR().
00603 {
00604 return WriteDcmImplVR (std::string (fileName));
00605 }
|
|
|
Writes on disk A SINGLE Dicom file NO test is performed on processor "Endiannity".
Definition at line 591 of file gdcmFile.cxx. References WriteBase(). Referenced by WriteDcmImplVR().
00591 {
00592 return WriteBase(fileName, ImplicitVR);
00593 }
|
|
|
Writes on disk A SINGLE Dicom file NO test is performed on processor "Endiannity". It's up to the user to call his Reader properly.
Definition at line 570 of file gdcmFile.cxx. References lgrTotale, and PixelData.
00570 {
00571 FILE * fp1;
00572 fp1 = fopen(fileName.c_str(),"wb");
00573 if (fp1 == NULL) {
00574 printf("Fail to open (write) file [%s] \n",fileName.c_str());
00575 return (false);
00576 }
00577 fwrite (PixelData,lgrTotale, 1, fp1);
00578 fclose (fp1);
00579 return(true);
00580 }
|
|
|
Definition at line 92 of file gdcmFile.h. Referenced by gdcm_read_RLE_file(), gdcmFile(), GetHeader(), GetImageDataIntoVector(), GetImageDataIntoVectorRaw(), GetImageDataRaw(), ParsePixelData(), ReadPixelData(), SetImageData(), SetPixelDataSizeFromHeader(), WriteBase(), and ~gdcmFile(). |
|
|
Definition at line 97 of file gdcmFile.h. Referenced by gdcm_read_RLE_file(), GetImageData(), GetImageDataIntoVector(), GetImageDataIntoVectorRaw(), GetImageDataRaw(), GetImageDataSize(), SetImageData(), SetPixelDataSizeFromHeader(), WriteBase(), and WriteRawData(). |
|
|
Definition at line 96 of file gdcmFile.h. Referenced by GetImageDataIntoVector(), GetImageDataSizeRaw(), SetPixelDataSizeFromHeader(), and WriteBase(). |
|
|
Definition at line 104 of file gdcmFile.h. |
|
|
Definition at line 103 of file gdcmFile.h. |
|
|
Definition at line 95 of file gdcmFile.h. Referenced by GetImageData(), GetImageDataRaw(), SetImageData(), WriteBase(), and WriteRawData(). |
|
|
Definition at line 99 of file gdcmFile.h. Referenced by gdcmFile(), GetImageData(), GetImageDataIntoVector(), GetImageDataIntoVectorRaw(), GetImageDataRaw(), and WriteBase(). |
|
|
Definition at line 93 of file gdcmFile.h. Referenced by gdcmFile(), and ~gdcmFile(). |
1.3.6