GDCM
2.2.0
|
/*========================================================================= 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; }