/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /* * This example is a little helper to detect the famous SIEMENS JPEG lossless compressed image * where DICOM is declared as: * * (0028,0100) US 16 # 2,1 Bits Allocated * (0028,0101) US 12 # 2,1 Bits Stored * (0028,0102) US 11 # 2,1 High Bit * (0028,0103) US 0 # 2,1 Pixel Representation * * But where JPEG is: * * JPEG_SOF_Parameters: * SamplePrecision = 16 * nLines = 192 * nSamplesPerLine = 192 * nComponentsInFrame = 1 * component 0 * ComponentIdentifier = 1 * HorizontalSamplingFactor = 1 * VerticalSamplingFactor = 1 * QuantizationTableDestinationSelector = 0 * * * This case is valid. One simply has to use the 16bits jpeg decoder to decode the 12bits stored image. * This used to be an issue in GDCM 1.2.x (fixed in GDCM 1.2.5) * * The main return 0 (no error) when the file read is actually a potential problem. At the end of the main * function, the jpeg stream is stored in the filename specified as second argument */ #include "gdcmImageReader.h" #include "gdcmSequenceOfFragments.h" #include "gdcmJPEGCodec.h" #include #include int main(int argc, char *argv[]) { if( argc < 3 ) { std::cerr << argv[0] << " input.dcm output.jpg" << std::endl; return 1; } const char *filename = argv[1]; const char *outfilename = argv[2]; gdcm::ImageReader reader; reader.SetFileName( filename ); if( !reader.Read() ) { std::cerr << "Could not read: " << filename << std::endl; return 1; } // The output of gdcm::Reader is a gdcm::File const gdcm::File &file = reader.GetFile(); const gdcm::Image &image = reader.GetImage(); const gdcm::TransferSyntax &ts = file.GetHeader().GetDataSetTransferSyntax(); if( ts != gdcm::TransferSyntax::JPEGLosslessProcess14 && ts != gdcm::TransferSyntax::JPEGLosslessProcess14_1 ) { std::cerr << "Input is not a lossless JPEG" << std::endl; return 1; } // the dataset is the the set of element we are interested in: const gdcm::DataSet &ds = file.GetDataSet(); const gdcm::Tag rawTag(0x7fe0, 0x0010); // Default to Pixel Data const gdcm::DataElement& pdde = ds.GetDataElement( rawTag ); const gdcm::SequenceOfFragments *sf = pdde.GetSequenceOfFragments(); if( sf ) { std::ofstream output(outfilename, std::ios::binary); sf->WriteBuffer(output); } else { std::cerr << "Error" << std::endl; return 1; } gdcm::JPEGCodec jpeg; std::ifstream is(outfilename, std::ios::binary); gdcm::PixelFormat pf ( gdcm::PixelFormat::UINT8 ); // let's pretend it's a 8bits jpeg jpeg.SetPixelFormat( pf ); gdcm::TransferSyntax ts_jpg; bool b = jpeg.GetHeaderInfo( is, ts_jpg ); if( !b ) { return 1; } //jpeg.Print( std::cout ); if( jpeg.GetPixelFormat().GetBitsAllocated() != image.GetPixelFormat().GetBitsAllocated() || jpeg.GetPixelFormat().GetBitsStored() != image.GetPixelFormat().GetBitsStored() ) { std::cerr << "There is a mismatch in between DICOM declared Pixel Format and Sample Precision used in the JPEG stream" << std::endl; return 0; } std::cout << jpeg.GetPixelFormat() << std::endl; std::cout << image.GetPixelFormat() << std::endl; return 1; }