GDCM 2.2.0

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Directories
- Examples

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