#include "gdcmReader.h"
#include "gdcmWriter.h"
#include "gdcmImageReader.h"
#include <fstream>
#include "gdcm_charls.h"
int main(int argc, char *argv[])
{
if( argc < 3 )
{
std::cerr << argv[0] << " input.dcm output.dcm" << std::endl;
return 1;
}
const char *filename = argv[1];
const char *outfilename = argv[2];
gdcm::FileMetaInformation::SetSourceApplicationEntityTitle( "FixJAIBugJPEGLS" );
gdcm::ImageReader reader;
reader.SetFileName( filename );
if( !reader.Read() )
{
return 1;
}
gdcm::Image &image = reader.GetImage();
const gdcm::DataElement & in =
reader.GetFile().GetDataSet().GetDataElement( gdcm::Tag(0x7fe0,0x0010) );
const gdcm::SequenceOfFragments *sf = in.GetSequenceOfFragments();
if( !sf )
{
std::cerr << "No pixel data (or not encapsulated)" << std::endl;
return 1;
}
const unsigned int *dims = image.GetDimensions();
if ( sf->GetNumberOfFragments() != dims[2] )
{
std::cerr << "Unsupported" << std::endl;
return 1;
}
std::vector<BYTE> rgbyteOutall;
for(unsigned int i = 0; i < sf->GetNumberOfFragments(); ++i)
{
const gdcm::Fragment &frag = sf->GetFragment(i);
if( frag.IsEmpty() ) return 1;
const gdcm::ByteValue *bv = frag.GetByteValue();
if( !bv ) return 1;
unsigned long totalLen = bv->GetLength();
std::vector<char> vbuffer;
vbuffer.resize( totalLen );
char *buffer = &vbuffer[0];
bv->GetBuffer(buffer, totalLen);
const BYTE* pbyteCompressed0 = (const BYTE*)buffer;
while( totalLen > 0 && pbyteCompressed0[totalLen-1] != 0xd9 )
{
totalLen--;
}
#ifdef GDCM_USE_SYSTEM_CHARLS
JlsParameters metadata;
#else
JlsParamaters metadata;
#endif
if (JpegLsReadHeader(buffer, totalLen, &metadata) != OK)
{
std::cerr << "Cant parse jpegls" << std::endl;
return false;
}
std::cout << metadata.width << std::endl;
std::cout << metadata.height << std::endl;
std::cout << metadata.bitspersample << std::endl;
gdcm::PixelFormat const & pf = image.GetPixelFormat();
std::cout << pf << std::endl;
unsigned char marker_lse_13[] = {
0xFF, 0xF8, 0x00, 0x0D,
0x01,
0x1F, 0xFF,
0x00, 0x22,
0x00, 0x83,
0x02, 0x24,
0x00, 0x40
};
unsigned char marker_lse_14[] = {
0xFF, 0xF8, 0x00, 0x0D,
0x01,
0x3F, 0xFF,
0x00, 0x42,
0x01, 0x03,
0x04, 0x44,
0x00, 0x40
};
unsigned char marker_lse_15[] = {
0xFF, 0xF8, 0x00, 0x0D,
0x01,
0x7F, 0xFF,
0x00, 0x82,
0x02, 0x03,
0x08, 0x84,
0x00, 0x40
};
unsigned char marker_lse_16[] = {
0xFF, 0xF8, 0x00, 0x0D,
0x01,
0xFF, 0xFF,
0x01, 0x02,
0x04, 0x03,
0x11, 0x04,
0x00, 0x40
};
const unsigned char *marker_lse = NULL;
switch( metadata.bitspersample )
{
case 13:
marker_lse = marker_lse_13;
break;
case 14:
marker_lse = marker_lse_14;
break;
case 15:
marker_lse = marker_lse_15;
break;
case 16:
marker_lse = marker_lse_16;
break;
}
if( !marker_lse )
{
std::cerr << "Cant handle: " << metadata.bitspersample << std::endl;
return 1;
}
vbuffer.insert (vbuffer.begin() + 0x0F, marker_lse, marker_lse+15);
#if 0
std::ofstream of( "/tmp/d.jls" );
of.write( &vbuffer[0], vbuffer.size() );
of.close();
#endif
const char *pbyteCompressed = &vbuffer[0];
size_t cbyteCompressed = vbuffer.size();
#ifdef GDCM_USE_SYSTEM_CHARLS
JlsParameters params;
#else
JlsParamaters params;
#endif
JpegLsReadHeader(pbyteCompressed, cbyteCompressed, ¶ms);
std::vector<BYTE> rgbyteOut;
rgbyteOut.resize(params.height *params.width * ((params.bitspersample + 7)
/ 8) * params.components);
#ifdef GDCM_USE_SYSTEM_CHARLS
JLS_ERROR result =
JpegLsDecode(&rgbyteOut[0], rgbyteOut.size(), pbyteCompressed, cbyteCompressed, ¶ms );
#else
JLS_ERROR result =
JpegLsDecode(&rgbyteOut[0], rgbyteOut.size(), pbyteCompressed, cbyteCompressed );
#endif
if (result != OK)
{
std::cerr << "Could not patch JAI-JPEGLS" << std::endl;
return 1;
}
rgbyteOutall.insert( rgbyteOutall.end(), rgbyteOut.begin(), rgbyteOut.end() );
}
gdcm::DataElement pixeldata( gdcm::Tag(0x7fe0,0x0010) );
pixeldata.SetVR( gdcm::VR::OW );
pixeldata.SetByteValue( (char*)&rgbyteOutall[0], (uint32_t)rgbyteOutall.size() );
reader.GetFile().GetDataSet().Replace( pixeldata );
reader.GetFile().GetHeader().SetDataSetTransferSyntax(
gdcm::TransferSyntax::ExplicitVRLittleEndian);
gdcm::Writer writer;
writer.SetFileName( outfilename );
writer.SetFile( reader.GetFile() );
writer.Write();
std::cout << "Success !" << std::endl;
return 0;
}