Module: $RCSfile: gdcmFileHelper.cxx,v $
Language: C++
- Date: $Date: 2006/05/30 08:14:50 $
- Version: $Revision: 1.104 $
+ Date: $Date: 2006/08/29 15:50:05 $
+ Version: $Revision: 1.109 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
* @param lgth new value length
* @param group Group number of the Entry
* @param elem Element number of the Entry
+ * @param vr Value Represenation of the DataElement to be inserted
* \return pointer to the modified/created DataEntry (NULL when creation
* failed).
*/
case JPEG:
SetWriteFileTypeToJPEG();
break;
+
+ case JPEG2000:
+ SetWriteFileTypeToJPEG2000();
+ break;
}
-
+
// --------------------------------------------------------------
// Special Patch to allow gdcm to re-write ACR-LibIDO formated images
//
}
bool check = CheckWriteIntegrity(); // verifies length
- if (WriteType == JPEG ) check = true;
+ if (WriteType == JPEG || WriteType == JPEG2000) check = true;
if (check)
{
check = FileInternal->Write(fileName,WriteType);
vr = "OW";
if ( FileInternal->GetBitsAllocated()==24 ) // For RGB ACR files
vr = "OB";
+ // For non RAW data. Mainly JPEG
+ if( WriteType == JPEG || WriteType == JPEG2000)
+ {
+ vr = "OW";
+ }
DataEntry *pixel =
CopyDataEntry(GetFile()->GetGrPixel(),GetFile()->GetNumPixel(),vr);
pixel->SetFlag(DataEntry::FLAG_PIXELDATA);
Archive->Push(0x0002,0x0102);
}
+ /**
+ * \brief Sets in the File the TransferSyntax to 'JPEG2000'
+ */
+void FileHelper::SetWriteFileTypeToJPEG2000()
+{
+ std::string ts = Util::DicomString(
+ Global::GetTS()->GetSpecialTransferSyntax(TS::JPEG2000Lossless) );
+
+ DataEntry *tss = CopyDataEntry(0x0002,0x0010,"UI");
+ tss->SetString(ts);
+
+ Archive->Push(tss);
+ tss->Delete();
+}
+
/**
* \brief Sets in the File the TransferSyntax to 'JPEG'
*/
//0002 0016 AE 1 Source Application Entity Title
//0002 0100 UI 1 Private Information Creator
//0002 0102 OB 1 Private Information
+
+ // Push out 'ACR-NEMA-special' entries, if any
+ Archive->Push(0x0008,0x0001); // Length to End
+ Archive->Push(0x0008,0x0010); // Recognition Code
+ Archive->Push(0x0028,0x0005); // Image Dimension
// Create them if not found
// Always modify the value
std::ostringstream s;
// check 'Bits Allocated' vs decent values
int nbBitsAllocated = FileInternal->GetBitsAllocated();
- if ( nbBitsAllocated == 0 || nbBitsAllocated > 32)
+ if ( nbBitsAllocated == 0 || nbBitsAllocated > 32
+ || ( nbBitsAllocated > 8 && nbBitsAllocated <16) )
{
CopyMandatoryEntry(0x0028,0x0100,"16","US");
gdcmWarningMacro("(0028,0100) changed from "
//-----------------------------------------------------------------------------
} // end namespace gdcm
+
+
+/* Probabely something to be added to use Rescale Slope/Intercept
+Have a look ,at ITK code !
+
+// Internal function to rescale pixel according to Rescale Slope/Intercept
+template<class TBuffer, class TSource>
+void RescaleFunction(TBuffer* buffer, TSource *source,
+ double slope, double intercept, size_t size)
+{
+ size /= sizeof(TSource);
+
+ if (slope != 1.0 && intercept != 0.0)
+ {
+ // Duff's device. Instead of this code:
+ //
+ // for(unsigned int i=0; i<size; i++)
+ // {
+ // buffer[i] = (TBuffer)(source[i]*slope + intercept);
+ // }
+ //
+ // use Duff's device which exploits "fall through"
+ register size_t n = (size + 7) / 8;
+ switch ( size % 8)
+ {
+ case 0: do { *buffer++ = (TBuffer)((*source++)*slope + intercept);
+ case 7: *buffer++ = (TBuffer)((*source++)*slope + intercept);
+ case 6: *buffer++ = (TBuffer)((*source++)*slope + intercept);
+ case 5: *buffer++ = (TBuffer)((*source++)*slope + intercept);
+ case 4: *buffer++ = (TBuffer)((*source++)*slope + intercept);
+ case 3: *buffer++ = (TBuffer)((*source++)*slope + intercept);
+ case 2: *buffer++ = (TBuffer)((*source++)*slope + intercept);
+ case 1: *buffer++ = (TBuffer)((*source++)*slope + intercept);
+ } while (--n > 0);
+ }
+ }
+ else if (slope == 1.0 && intercept != 0.0)
+ {
+ // Duff's device. Instead of this code:
+ //
+ // for(unsigned int i=0; i<size; i++)
+ // {
+ // buffer[i] = (TBuffer)(source[i] + intercept);
+ // }
+ //
+ // use Duff's device which exploits "fall through"
+ register size_t n = (size + 7) / 8;
+ switch ( size % 8)
+ {
+ case 0: do { *buffer++ = (TBuffer)(*source++ + intercept);
+ case 7: *buffer++ = (TBuffer)(*source++ + intercept);
+ case 6: *buffer++ = (TBuffer)(*source++ + intercept);
+ case 5: *buffer++ = (TBuffer)(*source++ + intercept);
+ case 4: *buffer++ = (TBuffer)(*source++ + intercept);
+ case 3: *buffer++ = (TBuffer)(*source++ + intercept);
+ case 2: *buffer++ = (TBuffer)(*source++ + intercept);
+ case 1: *buffer++ = (TBuffer)(*source++ + intercept);
+ } while (--n > 0);
+ }
+ }
+ else if (slope != 1.0 && intercept == 0.0)
+ {
+ // Duff's device. Instead of this code:
+ //
+ // for(unsigned int i=0; i<size; i++)
+ // {
+ // buffer[i] = (TBuffer)(source[i]*slope);
+ // }
+ //
+ // use Duff's device which exploits "fall through"
+ register size_t n = (size + 7) / 8;
+ switch ( size % 8)
+ {
+ case 0: do { *buffer++ = (TBuffer)((*source++)*slope);
+ case 7: *buffer++ = (TBuffer)((*source++)*slope);
+ case 6: *buffer++ = (TBuffer)((*source++)*slope);
+ case 5: *buffer++ = (TBuffer)((*source++)*slope);
+ case 4: *buffer++ = (TBuffer)((*source++)*slope);
+ case 3: *buffer++ = (TBuffer)((*source++)*slope);
+ case 2: *buffer++ = (TBuffer)((*source++)*slope);
+ case 1: *buffer++ = (TBuffer)((*source++)*slope);
+ } while (--n > 0);
+ }
+ }
+ else
+ {
+ // Duff's device. Instead of this code:
+ //
+ // for(unsigned int i=0; i<size; i++)
+ // {
+ // buffer[i] = (TBuffer)(source[i]);
+ // }
+ //
+ // use Duff's device which exploits "fall through"
+ register size_t n = (size + 7) / 8;
+ switch ( size % 8)
+ {
+ case 0: do { *buffer++ = (TBuffer)(*source++);
+ case 7: *buffer++ = (TBuffer)(*source++);
+ case 6: *buffer++ = (TBuffer)(*source++);
+ case 5: *buffer++ = (TBuffer)(*source++);
+ case 4: *buffer++ = (TBuffer)(*source++);
+ case 3: *buffer++ = (TBuffer)(*source++);
+ case 2: *buffer++ = (TBuffer)(*source++);
+ case 1: *buffer++ = (TBuffer)(*source++);
+ } while (--n > 0);
+ }
+ }
+
+
+}
+
+
+template<class TSource>
+void RescaleFunction(ImageIOBase::IOComponentType bufferType,
+ void* buffer, TSource *source,
+ double slope, double intercept, size_t size)
+{
+ switch (bufferType)
+ {
+ case ImageIOBase::UCHAR:
+ RescaleFunction( (unsigned char *)buffer, source, slope, intercept, size);
+ break;
+ case ImageIOBase::CHAR:
+ RescaleFunction( (char *)buffer, source, slope, intercept, size);
+ break;
+ case ImageIOBase::USHORT:
+ RescaleFunction( (unsigned short *)buffer, source, slope, intercept,size);
+ break;
+ case ImageIOBase::SHORT:
+ RescaleFunction( (short *)buffer, source, slope, intercept, size);
+ break;
+ case ImageIOBase::UINT:
+ RescaleFunction( (unsigned int *)buffer, source, slope, intercept, size);
+ break;
+ case ImageIOBase::INT:
+ RescaleFunction( (int *)buffer, source, slope, intercept, size);
+ break;
+ case ImageIOBase::FLOAT:
+ RescaleFunction( (float *)buffer, source, slope, intercept, size);
+ break;
+ case ImageIOBase::DOUBLE:
+ RescaleFunction( (double *)buffer, source, slope, intercept, size);
+ break;
+ default:
+ ::itk::OStringStream message;
+ message << "itk::ERROR: GDCMImageIO: Unknown component type : " << bufferType;
+ ::itk::ExceptionObject e(__FILE__, __LINE__, message.str().c_str(),ITK_LOCATION);
+ throw e;
+ }
+}
+*/