# GetJPEGSamplePrecision.cxx

    /*=========================================================================

      Program: GDCM (Grassroots DICOM). A DICOM library
      Module:  $URL$

      Copyright (c) 2006-2010 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 <iostream>
    #include <fstream>

    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);
      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;
    }