fw4spl
ImageLazyStream.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwDcmtkIO/reader/main/ImageLazyStream.hpp"
8 
9 #include "fwDcmtkIO/reader/main/ImageLazyReader.hpp"
10 
11 #include <boost/filesystem/operations.hpp>
12 #include <boost/filesystem/path.hpp>
13 #include <boost/foreach.hpp>
14 #include <boost/make_shared.hpp>
15 
16 namespace fwDcmtkIO
17 {
18 namespace reader
19 {
20 namespace main
21 {
22 
23 //------------------------------------------------------------------------------
24 
25 ImageLazySource::ImageLazySource( ImageLazyInformation::sptr dcmInfo ) :
26  m_dcmInfo( dcmInfo )
27 {
28  SLM_ASSERT( "ImageLazySource needs at least one dicom file to read an image.",
29  !dcmInfo->m_dicomSeries->getDicomContainer().empty());
30 
31  m_frameSize = m_dcmInfo->m_rows * m_dcmInfo->m_columns * m_dcmInfo->m_imageType.sizeOf();
32  m_currentFrame = 0;
33  m_currentPosition = 0;
34  m_currentDicom = m_dcmInfo->m_dicomSeries->getDicomContainer().begin();
35 
36  m_frame = static_cast<char*>(::fwDcmtkIO::reader::main::ImageLazyReader::createInstanceBuffer(m_dcmInfo->m_rows,
37  m_dcmInfo->m_columns,
38  m_currentDicom->second,
39  m_dcmInfo->
40  m_rescaleSlope,
41  m_dcmInfo->
42  m_rescaleIntercept,
43  m_dcmInfo->
44  m_pixelRepresentation,
45  m_dcmInfo->m_imageType));
46 }
47 
48 //------------------------------------------------------------------------------
49 
50 std::streamsize ImageLazySource::read(char* s, std::streamsize n)
51 {
52  std::streamsize result = -1;
53 
54  // Load new frame
55  if(m_currentPosition + n > m_frameSize)
56  {
57  // Copy remaining bytes
58  const size_t remainingBytes = m_frameSize - m_currentPosition;
59  const size_t extraBytes = n - remainingBytes;
60 
61  if(remainingBytes > 0)
62  {
63  memcpy(s, m_frame + m_currentPosition, remainingBytes);
64  result = remainingBytes;
65  }
66 
67  // Change frame
68  delete m_frame;
69  ++m_currentFrame;
70  ++m_currentDicom;
71  m_currentPosition = 0;
72 
73  // If there is more frame
74  if(m_currentDicom != m_dcmInfo->m_dicomSeries->getDicomContainer().end())
75  {
76  // Copy extra bytes from the new frame
77  if(extraBytes > 0)
78  {
80  m_dcmInfo->m_rows, m_dcmInfo->m_columns, m_currentDicom->second,
81  m_dcmInfo->m_rescaleSlope, m_dcmInfo->m_rescaleIntercept,
82  m_dcmInfo->m_pixelRepresentation, m_dcmInfo->m_imageType));
83 
84  memcpy(s, m_frame + m_currentPosition, extraBytes);
85  m_currentPosition += extraBytes;
86  result = remainingBytes + extraBytes;
87  }
88  }
89  else
90  {
91  OSLM_TRACE("Reading process over.");
92  }
93 
94  }
95  // Copy bytes from the loaded frame
96  else
97  {
98  memcpy(s, m_frame + m_currentPosition, n);
99  m_currentPosition += n;
100  result = n;
101 
102  if(m_currentDicom->second == m_dcmInfo->m_dicomSeries->getDicomContainer().rbegin()->second &&
103  m_currentPosition == m_frameSize)
104  {
105  SLM_TRACE("Reading process over.");
106  delete m_frame;
107  }
108  }
109 
110  return result;
111 }
112 
113 //------------------------------------------------------------------------------
114 
115 ImageLazyStream::ImageLazyStream( ImageLazyInformation::sptr dcmInfo ) :
116  m_dcmInfo( dcmInfo )
117 {
118 }
119 
120 //------------------------------------------------------------------------------
121 
122 SPTR(std::istream) ImageLazyStream::get()
123 {
124  SPTR(::boost::iostreams::stream<ImageLazySource>) is
125  = std::make_shared< ::boost::iostreams::stream<ImageLazySource> >( m_dcmInfo );
126  return is;
127 }
128 
129 //------------------------------------------------------------------------------
130 
131 } //main
132 } //reader
133 } //fwDcmtkIO
#define SPTR(_cls_)
ImageLazyInformation::sptr m_dcmInfo
To conserve dicom information.
std::streamsize read(char *s, std::streamsize n)
Method to read n bytes in dicom buffer and write it in s.
ImageLazyStream(ImageLazyInformation::sptr dcmInfo)
Constructor. Builds the fwMemory::stream::in::IFactory with few dicom information.
#define OSLM_TRACE(message)
Definition: spyLog.hpp:230
ImageLazySource(ImageLazyInformation::sptr dcmInfo)
Constructor.
Class used to perform a lazy reading of dicom images with fw4spl system.
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
fwDcmtkIO contains classes used to pull Dicom images from a pacs using dcmtk library.
Definition: Codec.hpp:12
#define SLM_TRACE(message)
Definition: spyLog.hpp:228
std::shared_ptr< std::istream > get()
Returns the istream on dicom image buffer.
static FWDCMTKIO_API void * createInstanceBuffer(unsigned int rows, unsigned int columns, const ::fwMemory::BufferObject::sptr &instance, double rescaleSlope, double rescaleIntercept, unsigned short pixelRepresentation,::fwTools::Type imageType)
Create an instance buffer according to the image type.