StreamImageReaderTest.cxx
/*=========================================================================
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 work was realised during the GSOC 2011 by Manoj Alwani
#include "gdcmStreamImageReader.h"
#include "gdcmFileMetaInformation.h"
#include "gdcmSystem.h"
#include "gdcmFilename.h"
#include "gdcmByteSwap.h"
#include "gdcmTrace.h"
#include "gdcmTesting.h"
#include "gdcmImageHelper.h"
#include "gdcmImageReader.h"
#include "gdcmImage.h"
#include "gdcmMediaStorage.h"
#include "gdcmRAWCodec.h"
#include "gdcmJPEGLSCodec.h"
#include "gdcmUIDGenerator.h"
#include "gdcmStreamImageWriter.h"
#include "gdcmAttribute.h"
#include "gdcmFile.h"
#include "gdcmTag.h"
bool StreamImageRead(gdcm::StreamImageWriter & theStreamWriter,
const char* filename, const char* outfilename, int resolution)
{
gdcm::StreamImageReader reader;
reader.SetFileName( filename );
if (!reader.ReadImageInformation())
{
std::cerr << "unable to read image information" << std::endl;
return 1; //unable to read tags as expected.
}
//let's be tricky; each image will be read in portions, first the top half, then the bottom
//that way, we can test how the stream handles fragmentation of the data
//we could also loop this to get various different size combinations, but I'm not sure
//that's useful, yet.
std::vector<unsigned int> extent =
gdcm::ImageHelper::GetDimensionsValue(reader.GetFile());
// std::cout << extent[0];
//at this point, these values aren't used, but may be in the future
//unsigned short xmin = 0;
//unsigned short xmax = extent[0];
//unsigned short ymin = 0;
//unsigned short ymax = extent[1];
//unsigned short zmin = 0;
//unsigned short zmax = extent[2];
std::cout<< "\n Row: "<<extent[0] <<"\n Col :"<< extent[1]<< "\n Resolution :"<< extent[2] << std::endl;
int a =1;
for (int i=1; i<=(extent[2]-resolution);++i)
a = a*2;
reader.DefinePixelExtent(0, extent[0]/a, 0, extent[1]/a, resolution-1, resolution);
unsigned long len = reader.DefineProperBufferLength();
char* finalBuffer = new char[len];
memset(finalBuffer, 0, sizeof(char)*len);
if (reader.CanReadImage())
{
bool result = reader.Read(finalBuffer, len);
if( !result )
{
std::cout << "res2 failure:" << filename << std::endl;
delete [] finalBuffer;
return 1;
}
else
{
std::cout<< "Able to read";
}
}
else
{
std::cerr<< "Not able to put in buffer"<< std::endl;
}
/*
//now, read in smaller buffer extents
reader.DefinePixelExtent(xmin, xmax, ymin, ymax);
len = reader.DefineProperBufferLength();
char* buffer = new char[len];
bool res2 = reader.Read(buffer, len);
if( !res2 ){
std::cerr << "res2 failure:" << filename << std::endl;
return 1;
}
//copy the result into finalBuffer
memcpy(finalBuffer, buffer, len);
//now read the next half of the image
ymin = ymax;
ymax = extent[1];
reader.DefinePixelExtent(xmin, xmax, ymin, ymax);
//std::cerr << "Success to read image from file: " << filename << std::endl;
unsigned long len2 = reader.DefineProperBufferLength();
char* buffer2 = new char[len2];
bool res3 = reader.Read(buffer2, len2);
if( !res3 ){
std::cerr << "res3 failure:" << filename << std::endl;
return 1;
}
//copy the result into finalBuffer
memcpy(&(finalBuffer[len]), buffer2, len2);
delete [] buffer;
delete [] buffer2;
*/
gdcm::Writer w;
gdcm::File &file = w.GetFile();
gdcm::DataSet &ds = file.GetDataSet();
file.GetHeader().SetDataSetTransferSyntax( gdcm::TransferSyntax::ExplicitVRLittleEndian );
gdcm::UIDGenerator uid;
gdcm::DataElement de( gdcm::Tag(0x8,0x18) ); // SOP Instance UID
de.SetVR( gdcm::VR::UI );
const char *u = uid.Generate();
de.SetByteValue( u, strlen(u) );
ds.Insert( de );
gdcm::DataElement de1( gdcm::Tag(0x8,0x16) );
de1.SetVR( gdcm::VR::UI );
gdcm::MediaStorage ms( gdcm::MediaStorage::VLWholeSlideMicroscopyImageStorage );
de1.SetByteValue( ms.GetString(), strlen(ms.GetString()));
ds.Insert( de1 );
const char mystr[] = "MONOCHROME2 ";
gdcm::DataElement de2( gdcm::Tag(0x28,0x04) );
//de.SetTag(gdcm::Tag(0x28,0x04));
de2.SetVR( gdcm::VR::CS );
de2.SetByteValue(mystr, strlen(mystr));
ds.Insert( de2 );
gdcm::Attribute<0x0028,0x0008> Number_Of_Frames = {1};
ds.Insert( Number_Of_Frames.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0010> row = {extent[0]/a};//
ds.Insert( row.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0011> col = {extent[1]/a};//
ds.Insert( col.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0100> at = {8};
ds.Insert( at.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0002> at1 = {1};//
ds.Insert( at1.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0101> at2 = {8};
ds.Insert( at2.GetAsDataElement() );
gdcm::Attribute<0x0028,0x0102> at3 = {7};
ds.Insert( at3.GetAsDataElement() );
/*
ds1.Remove( gdcm::Tag(0x0028,0x0008) );
gdcm::Attribute<0x0028,0x0008> Number_Of_Frames = {1};
ds1.Insert( Number_Of_Frames.GetAsDataElement() );
*/
theStreamWriter.SetFile(file);
if (!theStreamWriter.WriteImageInformation())
{
std::cerr << "unable to write image information" << std::endl;
return 1; //the CanWrite function should prevent getting here, else,
//that's a test failure
}
std::vector<unsigned int> extent1 = gdcm::ImageHelper::GetDimensionsValue(file);
unsigned short xmax = extent1[0];
unsigned short ymax = extent1[1];
unsigned short theChunkSize = 1;
unsigned short ychunk = extent1[1]/theChunkSize; //go in chunk sizes of theChunkSize
unsigned short zmax = 1;
std::cout<< "\n Row: "<<extent1[0] <<"\n Col :"<< extent1[1]<< "\n Resolution :"<< extent1[2] << std::endl;
if (xmax == 0 || ymax == 0)
{
std::cerr << "Image has no size, unable to write zero-sized image." << std::endl;
return 0;
}
int z, y, nexty;
unsigned long prevLen = 0; //when going through the char buffer, make sure to grab
//the bytes sequentially. So, store how far you got in the buffer with each iteration.
for (z = 0; z < zmax; ++z){
for (y = 0; y < ymax; y += ychunk){
nexty = y + ychunk;
if (nexty > ymax) nexty = ymax;
theStreamWriter.DefinePixelExtent(0, xmax, y, nexty, z, z+1);
unsigned long len = theStreamWriter.DefineProperBufferLength();
std::cout << "\n" <<len;
char* finalBuffer1 = new char[len];
memcpy(finalBuffer1, &(finalBuffer[prevLen]), len);
std::cout << "\nable to write";
if (!theStreamWriter.Write(finalBuffer1, len)){
std::cerr << "writing failure:" << "output.dcm" << " at y = " << y << " and z= " << z << std::endl;
delete [] finalBuffer1;
delete [] finalBuffer;
return 1;
}
delete [] finalBuffer1;
prevLen += len;
}
}
delete [] finalBuffer;
std::cout << "all is set";
return true;
}
int main(int argc, char *argv[])
{
if( argc < 3 )
{
std::cerr << argv[0] << " input.dcm output.dcm Resolution" << std::endl;
return 1;
}
const char *filename = argv[1];
const char *outfilename = argv[2];
char *res = argv[3];
int resolution = atoi(res);
gdcm::StreamImageWriter theStreamWriter;
std::ofstream of;
of.open( outfilename, std::ios::out | std::ios::binary );
theStreamWriter.SetStream(of);
// else
// First of get rid of warning/debug message
gdcm::Trace::DebugOn();
gdcm::Trace::WarningOn();
if(!StreamImageRead( theStreamWriter, filename, outfilename, resolution))
return 1;
uint16_t firstTag1 = 0xfffe;
uint16_t secondTag1 = 0xe0dd;
uint32_t thirdTag1 = 0x00000000;
//uint16_t fourthTag1 = 0xffff;
const int theBufferSize1 = 2*sizeof(uint16_t)+sizeof(uint32_t);
char* tmpBuffer2 = new char[theBufferSize1];
memcpy(&(tmpBuffer2[0]), &firstTag1, sizeof(uint16_t));
memcpy(&(tmpBuffer2[sizeof(uint16_t)]), &secondTag1, sizeof(uint16_t));
memcpy(&(tmpBuffer2[2*sizeof(uint16_t)]), &thirdTag1, sizeof(uint32_t));
//memcpy(&(tmpBuffer2[3*sizeof(uint16_t)]), &fourthTag1, sizeof(uint16_t));
assert( of && !of.eof() && of.good() );
of.write(tmpBuffer2, theBufferSize1);
of.flush();
assert( of );
return 0;
}
gdcm::Attribute
Attribute class This class use template metaprograming tricks to let the user know when the template ...
Definition gdcmAttribute.h:86
gdcm::Attribute::GetAsDataElement
DataElement GetAsDataElement() const
Definition gdcmAttribute.h:183
gdcm::DataElement
Class to represent a Data Element either Implicit or Explicit.
Definition gdcmDataElement.h:59
gdcm::DataElement::SetByteValue
void SetByteValue(const char *array, VL length)
Definition gdcmDataElement.h:126
gdcm::DataElement::SetVR
void SetVR(VR const &vr)
Definition gdcmDataElement.h:88
gdcm::DataSet
Class to represent a Data Set (which contains Data Elements).
Definition gdcmDataSet.h:56
gdcm::DataSet::Insert
void Insert(const DataElement &de)
Definition gdcmDataSet.h:128
gdcm::FileMetaInformation::SetDataSetTransferSyntax
void SetDataSetTransferSyntax(const TransferSyntax &ts)
gdcm::File
a DICOM File
Definition gdcmFile.h:34
gdcm::File::GetDataSet
const DataSet & GetDataSet() const
Get Data Set.
Definition gdcmFile.h:57
gdcm::File::GetHeader
const FileMetaInformation & GetHeader() const
Get File Meta Information.
Definition gdcmFile.h:48
gdcm::ImageHelper::GetDimensionsValue
static std::vector< unsigned int > GetDimensionsValue(const File &f)
gdcm::MediaStorage
MediaStorage.
Definition gdcmMediaStorage.h:44
gdcm::MediaStorage::VLWholeSlideMicroscopyImageStorage
@ VLWholeSlideMicroscopyImageStorage
Definition gdcmMediaStorage.h:121
gdcm::MediaStorage::GetString
const char * GetString() const
Return the Media String of the object.
gdcm::StreamImageReader
StreamImageReader.
Definition gdcmStreamImageReader.h:39
gdcm::StreamImageReader::DefinePixelExtent
void DefinePixelExtent(uint16_t inXMin, uint16_t inXMax, uint16_t inYMin, uint16_t inYMax, uint16_t inZMin=0, uint16_t inZMax=1)
gdcm::StreamImageReader::ReadImageInformation
virtual bool ReadImageInformation()
gdcm::StreamImageReader::Read
bool Read(char *inReadBuffer, const std::size_t &inBufferLength)
gdcm::StreamImageReader::CanReadImage
bool CanReadImage() const
gdcm::StreamImageReader::SetFileName
void SetFileName(const char *inFileName)
gdcm::StreamImageReader::GetFile
File const & GetFile() const
gdcm::StreamImageReader::DefineProperBufferLength
uint32_t DefineProperBufferLength() const
gdcm::StreamImageWriter
StreamImageReader.
Definition gdcmStreamImageWriter.h:43
gdcm::StreamImageWriter::SetFile
void SetFile(const File &inFile)
gdcm::StreamImageWriter::DefinePixelExtent
void DefinePixelExtent(uint16_t inXMin, uint16_t inXMax, uint16_t inYMin, uint16_t inYMax, uint16_t inZMin=0, uint16_t inZMax=1)
gdcm::StreamImageWriter::DefineProperBufferLength
uint32_t DefineProperBufferLength()
gdcm::StreamImageWriter::SetStream
void SetStream(std::ostream &inStream)
gdcm::StreamImageWriter::Write
bool Write(void *inWriteBuffer, const std::size_t &inBufferLength)
gdcm::StreamImageWriter::WriteImageInformation
virtual bool WriteImageInformation()
gdcm::Tag
Class to represent a DICOM Data Element (Attribute) Tag (Group, Element).
Definition gdcmTag.h:39
gdcm::Trace::WarningOn
static void WarningOn()
gdcm::Trace::DebugOn
static void DebugOn()
gdcm::TransferSyntax::ExplicitVRLittleEndian
@ ExplicitVRLittleEndian
Definition gdcmTransferSyntax.h:64
gdcm::UIDGenerator
Class for generating unique UID.
Definition gdcmUIDGenerator.h:28
gdcm::UIDGenerator::Generate
const char * Generate()
gdcm::VR::UI
@ UI
Definition gdcmVR.h:87
gdcm::VR::CS
@ CS
Definition gdcmVR.h:63
gdcm::Writer
Writer ala DOM (Document Object Model).
Definition gdcmWriter.h:49
gdcm::Writer::GetFile
File & GetFile()
Definition gdcmWriter.h:67
gdcmAttribute.h
gdcmByteSwap.h
gdcmFileMetaInformation.h
gdcmFile.h
gdcmFilename.h
gdcmImageHelper.h
gdcmImageReader.h
gdcmImage.h
gdcmJPEGLSCodec.h
gdcmMediaStorage.h
gdcmRAWCodec.h
gdcmStreamImageReader.h
gdcmStreamImageWriter.h
gdcmSystem.h
gdcmTag.h
gdcmTesting.h
gdcmTrace.h
gdcmUIDGenerator.h