#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(). |