X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmFileHelper.cxx;h=997c37a24772dc16733a61a46240930eb1092e2b;hb=6a5de9524996d429cd18c722261421ff4e298681;hp=32f79cb6e55e59fba9026f2684aac1d8027bea88;hpb=8b4006ce9e262e36f32ed56d877bc31de0a748a1;p=gdcm.git diff --git a/src/gdcmFileHelper.cxx b/src/gdcmFileHelper.cxx index 32f79cb6..997c37a2 100644 --- a/src/gdcmFileHelper.cxx +++ b/src/gdcmFileHelper.cxx @@ -4,8 +4,8 @@ Module: $RCSfile: gdcmFileHelper.cxx,v $ Language: C++ - Date: $Date: 2007/07/13 08:17:21 $ - Version: $Revision: 1.117 $ + Date: $Date: 2007/08/24 10:45:18 $ + Version: $Revision: 1.121 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -63,15 +63,17 @@ std::string v = f->GetEntryValue(groupNb,ElementNb); // to get the pixels, user needs a gdcm::FileHelper gdcm::FileHelper *fh = new gdcm::FileHelper(f); + // user may ask not to convert Palette (if any) to RGB uint8_t *pixels = fh->GetImageDataRaw(); int imageLength = fh->GetImageDataRawSize(); + // He can now use the pixels, create a new image, ... uint8_t *userPixels = ... -To re-write the image, user re-uses the gdcm::FileHelper +//To re-write the image, user re-uses the gdcm::FileHelper +gdcm::File *fh = new gdcm::FileHelper(); -fh->SetImageData( userPixels, userPixelsLength); fh->SetTypeToRaw(); // Even if it was possible to convert Palette to RGB // (WriteMode is set) @@ -79,14 +81,20 @@ fh->SetTypeToRaw(); // Even if it was possible to convert Palette to RGB fh->SetPhotometricInterpretationToMonochrome1(); fh->SetWriteTypeToDcmExpl(); // he wants Explicit Value Representation - // Little Endian is the default - // no other value is allowed + // Little Endian is the default, + // bigendian not supported for writting (-->SetWriteType(ExplicitVR);) -->WriteType = ExplicitVR; +fh->SetWriteTypeToJPEG(); // lossless compression +fh->SetWriteTypeToJPEG2000(); // lossless compression + +fh->SetImageData( userPixels, userPixelsLength); +or +fh->SetUserData( userPixels, userPixelsLength); // this one performs compression, when required + fh->Write(newFileName); // overwrites the file, if any -// or : -fh->WriteDcmExplVR(newFileName); + // ----------------------------- WARNING ------------------------- @@ -494,7 +502,7 @@ size_t FileHelper::GetImageDataIntoVector (void *destination, size_t maxSize) * not to deallocate its data before gdcm uses them (e.g. with * the Write() method ) * @param inData user supplied pixel area (uint8_t* is just for the compiler. - * user is allowed to pass any kind of pixelsn since the size is + * user is allowed to pass any kind of pixels since the size is * given in bytes) * @param expectedSize total image size, *in Bytes* */ @@ -706,7 +714,7 @@ bool FileHelper::WriteAcr (std::string const &fileName) * @return false if write fails */ bool FileHelper::Write(std::string const &fileName) -{ +{ CheckMandatoryElements(); //called once, here ! bool flag = false; @@ -728,8 +736,9 @@ bool FileHelper::Write(std::string const &fileName) // Let's just *dream* about it; *never* trust a user ! // We turn to Implicit VR if at least the VR of one element is unknown. - /// \TODO : better we put vr=UN for undocumented Shadow Groups ! - + // Better we let DocEntry::WriteContent to put vr=UN for undocumented Shadow Groups ! + +/* e = FileInternal->GetFirstEntry(); while (e != 0) { @@ -748,8 +757,10 @@ bool FileHelper::Write(std::string const &fileName) SetWriteFileTypeToExplicitVR(); } break; +*/ + + SetWriteFileTypeToExplicitVR(); - SetWriteFileTypeToExplicitVR(); // to see JPRx break; case ACR: case ACR_LIBIDO: @@ -805,9 +816,11 @@ bool FileHelper::Write(std::string const &fileName) break; } - bool check = CheckWriteIntegrity(); // verifies length - if (WriteType == JPEG || WriteType == JPEG2000) + bool check; + if (WriteType == JPEG || WriteType == JPEG2000) check = true; + else + check = CheckWriteIntegrity(); // verifies length if (check) { @@ -906,13 +919,13 @@ void FileHelper::SetWriteToRaw() photInt->SetString("PALETTE COLOR "); } else - { + { if (GetPhotometricInterpretation() == 2) photInt->SetString("MONOCHROME2 "); // 0 = Black else photInt->SetString("MONOCHROME1 "); // 0 = White ! } - + PixelWriteConverter->SetReadData(PixelReadConverter->GetRaw(), PixelReadConverter->GetRawSize()); @@ -926,17 +939,18 @@ void FileHelper::SetWriteToRaw() { vr = "OW"; } - + DataEntry *pixel = CopyDataEntry(GetFile()->GetGrPixel(),GetFile()->GetNumPixel(),vr); pixel->SetFlag(DataEntry::FLAG_PIXELDATA); pixel->SetBinArea(PixelWriteConverter->GetData(),false); - pixel->SetLength(PixelWriteConverter->GetDataSize()); - + pixel->SetLength( + static_cast< uint32_t >(PixelWriteConverter->GetDataSize()) ); + if (!FileInternal->HasLUT() && GetPhotometricInterpretation() == 1) { ConvertFixGreyLevels( pixel->GetBinArea(), pixel->GetLength() ); - } + } Archive->Push(photInt); Archive->Push(pixel); @@ -1171,10 +1185,10 @@ void FileHelper::SetWriteToLibido() if ( oldRow && oldCol ) { std::string rows, columns; - + DataEntry *newRow=DataEntry::New(0x0028, 0x0010, "US"); DataEntry *newCol=DataEntry::New(0x0028, 0x0011, "US"); - + newRow->Copy(oldCol); newCol->Copy(oldRow); @@ -1306,7 +1320,7 @@ We have to deal with 4 *very* different cases : CREATED_IMAGE -4) user modified/added some tags *without processing* the pixels (anonymization...) UNMODIFIED_PIXELS_IMAGE --Probabely some more to be added. +-Probabely some more to be added. gdcm::FileHelper::CheckMandatoryElements() deals automatically with these cases. @@ -1480,10 +1494,10 @@ void FileHelper::CheckMandatoryElements() // 'Media Storage SOP Class UID' --> [Secondary Capture Image Storage] CopyMandatoryEntry(0x0002,0x0002,"1.2.840.10008.5.1.4.1.1.7","UI"); } - - // 'Media Storage SOP Instance UID' + + // 'Media Storage SOP Instance UID' CopyMandatoryEntry(0x0002,0x0003,sop,"UI"); - + // 'Implementation Class UID' // FIXME : in all examples we have, 0x0002,0x0012 is not so long : // seems to be Root UID + 4 digits (?) @@ -1499,9 +1513,9 @@ void FileHelper::CheckMandatoryElements() if ( ContentType != USER_OWN_IMAGE) // when it's not a user made image { - + gdcmDebugMacro( "USER_OWN_IMAGE (1)"); - // If 'SOP Class UID' exists ('true DICOM' image) + // If 'SOP Class UID' exists ('true DICOM' image) // we create the 'Source Image Sequence' SeqEntry // to hold informations about the Source Image @@ -1565,10 +1579,10 @@ void FileHelper::CheckMandatoryElements() Archive->Push(0x0028,0x0017); Archive->Push(0x0028,0x0198); // very old versions Archive->Push(0x0028,0x0199); - + // Replace deprecated 0028 0012 US Planes // by new 0028 0008 IS Number of Frames - + ///\todo : find if there is a rule! DataEntry *e_0028_0012 = FileInternal->GetDataEntry(0x0028, 0x0012); if ( e_0028_0012 ) @@ -1589,8 +1603,8 @@ void FileHelper::CheckMandatoryElements() std::ostringstream s; // check 'Bits Allocated' vs decent values int nbBitsAllocated = FileInternal->GetBitsAllocated(); - if ( nbBitsAllocated == 0 || nbBitsAllocated > 32 - || ( nbBitsAllocated > 8 && nbBitsAllocated <16) ) + if ( (nbBitsAllocated == 0 || nbBitsAllocated > 32) + || ( nbBitsAllocated > 8 && nbBitsAllocated <16) ) { CopyMandatoryEntry(0x0028,0x0100,"16","US"); gdcmWarningMacro("(0028,0100) changed from " @@ -1624,7 +1638,7 @@ void FileHelper::CheckMandatoryElements() } // check Pixel Representation (default it as 0 -unsigned-) - + DataEntry *e_0028_0103 = FileInternal->GetDataEntry(0x0028, 0x0103); if ( !e_0028_0103 ) { @@ -1653,7 +1667,7 @@ void FileHelper::CheckMandatoryElements() // --> This one is the *legal* one ! if ( ContentType != USER_OWN_IMAGE) // we write it only when we are *sure* the image comes from - // an imager (see also 0008,0x0064) + // an imager (see also 0008,0x0064) CheckMandatoryEntry(0x0018,0x1164,pixelSpacing,"DS"); /* @@ -1661,7 +1675,7 @@ void FileHelper::CheckMandatoryElements() // See page 73 of ACR-NEMA_300-1988.pdf ! -// 0020,0020 : Patient Orientation : +// 0020,0020 : Patient Orientation : Patient direction of the first row and column of the images. The first entry id the direction of the raws, given by the direction of the last pixel in the first row from the first pixel in tha row. @@ -1679,11 +1693,11 @@ equipment coordinate axes x,y,z, followed by direction cosines of the C axis of the image system with respect to the same axes //0020,0050 Location -An image location reference, standard for the modality (such as CT bed -position), used to indicate position. Calculation of position for other purposes +An image location reference, standard for the modality (such as CT bed position), +used to indicate position. Calculation of position for other purposes is only from (0020,0030) and (0020,0035) */ - + /* // if imagePositionPatient not found, default it with imagePositionRet, if any // if imageOrientationPatient not found, default it with imageOrientationRet, if any @@ -1692,7 +1706,7 @@ is only from (0020,0030) and (0020,0035) std::string imageOrientationRet = FileInternal->GetEntryString(0x0020,0x0035); std::string imagePositionPatient = FileInternal->GetEntryString(0x0020,0x0032); std::string imageOrientationPatient = FileInternal->GetEntryString(0x0020,0x0037); - + if( imagePositionPatient == GDCM_UNFOUND && imageOrientationPatient == GDCM_UNFOUND && imagePositionRet != GDCM_UNFOUND && imageOrientationRet != GDCM_UNFOUND) { @@ -1703,7 +1717,7 @@ is only from (0020,0030) and (0020,0035) } */ - // Samples Per Pixel (type 1) : default to grayscale + // Samples Per Pixel (type 1) : default to grayscale CheckMandatoryEntry(0x0028,0x0002,"1","US"); // --- Check UID-related Entries --- @@ -1715,11 +1729,11 @@ is only from (0020,0030) and (0020,0035) if ( ContentType == USER_OWN_IMAGE) { - gdcmDebugMacro( "USER_OWN_IMAGE (2)"); + gdcmDebugMacro( "USER_OWN_IMAGE (2)"); // Conversion Type. // Other possible values are : // See PS 3.3, Page 408 - + // DV = Digitized Video // DI = Digital Interface // DF = Digitized Film @@ -1728,7 +1742,7 @@ is only from (0020,0030) and (0020,0035) // SI = Scanned Image // DRW = Drawing // SYN = Synthetic Image - + CheckMandatoryEntry(0x0008,0x0064,"SYN","CS"); // Why not? } /* @@ -1738,7 +1752,7 @@ is only from (0020,0030) and (0020,0035) } */ - + // ---- The user will never have to take any action on the following ---- // new value for 'SOP Instance UID' @@ -1836,7 +1850,7 @@ is only from (0020,0030) and (0020,0035) /* // Deal with element 0x0000 (group length) of each group. // First stage : get all the different Groups - + GroupHT grHT; DocEntry *d = FileInternal->GetFirstEntry(); while(d) @@ -1871,7 +1885,7 @@ void FileHelper::CheckMandatoryEntry(uint16_t group,uint16_t elem,std::string va } } -/// \todo : what is it used for ? (FileHelper::SetMandatoryEntry) +/// \todo : what is it used for ? (FileHelper::SetMandatoryEntry) void FileHelper::SetMandatoryEntry(uint16_t group,uint16_t elem,std::string value,const VRKey &vr) { //DataEntry *entry = DataEntry::New(Global::GetDicts()->GetDefaultPubDict()->GetEntry(group,elem)); @@ -2090,7 +2104,7 @@ void FileHelper::ConvertFixGreyLevels(uint8_t *raw, size_t rawSize) //----------------------------------------------------------------------------- /** - * \brief Prints the common part of DataEntry, SeqEntry + * \brief Prints the FileInternal + info on PixelReadConvertor * @param os ostream we want to print in * @param indent (unused) */