fw4spl
core/fwDataTools/src/fwDataTools/helper/Image.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
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 "fwDataTools/fieldHelper/Image.hpp"
8 #include "fwDataTools/helper/Image.hpp"
9 
10 #include "fwDataTools/fieldHelper/MedicalImageHelpers.hpp"
11 #include "fwDataTools/helper/Composite.hpp"
12 #include "fwDataTools/helper/Field.hpp"
13 
14 #include <fwCom/Signal.hpp>
15 #include <fwCom/Signal.hxx>
16 #include <fwCom/Signals.hpp>
17 
18 #include <fwData/Composite.hpp>
19 #include <fwData/PointList.hpp>
20 #include <fwData/TransferFunction.hpp>
21 
22 namespace fwDataTools
23 {
24 namespace helper
25 {
26 
27 //-----------------------------------------------------------------------------
28 
29 Image::Image( ::fwData::Image::sptr image ) :
30  m_image(image),
31  m_sliceModified(false)
32 {
33  if ( image )
34  {
35  m_lock = image->getDataArray()->getBufferObject()->lock();
36  }
37 }
38 
39 //-----------------------------------------------------------------------------
40 
42 {
43 }
44 
45 //------------------------------------------------------------------------------
46 
48 {
49  bool fieldIsCreated = false;
50 
51  // Manage image landmarks
52  if ( !m_image->getField( ::fwDataTools::fieldHelper::Image::m_imageLandmarksId ) )
53  {
54  ::fwData::PointList::sptr pl = ::fwData::PointList::New();
55  m_image->setField( ::fwDataTools::fieldHelper::Image::m_imageLandmarksId, pl );
56  fieldIsCreated = true;
57  }
58 
59  return fieldIsCreated;
60 }
61 
62 //------------------------------------------------------------------------------
63 
65 {
66  bool fieldIsCreated = false;
68  ::fwData::Composite::sptr tfPool;
69 
70  tfPool = m_image->getField< ::fwData::Composite >(poolFieldName);
71  // Transfer functions
72  if ( !tfPool )
73  {
74  tfPool = ::fwData::Composite::New();
75 
76  // Set in selected image
77  ::fwDataTools::helper::Field fieldHelper(m_image);
78  fieldHelper.setField(poolFieldName, tfPool);
79  fieldHelper.notify();
80 
81  // TF pool is modified
82  fieldIsCreated = true;
83  }
84 
85  const std::string defaultTFName = ::fwData::TransferFunction::s_DEFAULT_TF_NAME;
86  if(tfPool->find(defaultTFName) == tfPool->end())
87  {
88  ::fwData::TransferFunction::sptr tf = ::fwData::TransferFunction::createDefaultTF();
89  if (m_image->getWindowWidth() != 0 )
90  {
91  tf->setWindow( m_image->getWindowWidth() );
92  tf->setLevel( m_image->getWindowCenter() );
93  }
95  {
96  double min, max;
98  ::fwData::TransferFunction::TFValuePairType wlMinMax(min, max);
99  tf->setWLMinMax(wlMinMax);
100  }
101  // Set in TFPool
102  ::fwDataTools::helper::Composite compositeHelper(tfPool);
103  compositeHelper.add(defaultTFName, tf);
104  compositeHelper.notify();
105  }
106 
107  return fieldIsCreated;
108 }
109 
110 //------------------------------------------------------------------------------
111 
113 {
114  bool fieldIsCreated = false;
115 
116  const ::fwData::Image::SizeType& imageSize = m_image->getSize();
117 
118  ::fwData::Integer::sptr axialIdx = m_image->getField< ::fwData::Integer >(
120  ::fwData::Integer::sptr frontalIdx = m_image->getField< ::fwData::Integer >(
122  ::fwData::Integer::sptr sagittalIdx = m_image->getField< ::fwData::Integer >(
124 
125  // Manage image slice index
126  if ( !(axialIdx && frontalIdx && sagittalIdx) )
127  {
128  // Set value
129  axialIdx = ::fwData::Integer::New(-1);
130  m_image->setField( ::fwDataTools::fieldHelper::Image::m_axialSliceIndexId, axialIdx );
131 
132  frontalIdx = ::fwData::Integer::New(-1);
133  m_image->setField( ::fwDataTools::fieldHelper::Image::m_frontalSliceIndexId, frontalIdx );
134 
135  sagittalIdx = ::fwData::Integer::New(-1);
136  m_image->setField( ::fwDataTools::fieldHelper::Image::m_sagittalSliceIndexId, sagittalIdx );
137 
138  fieldIsCreated = true;
139  }
140 
141  SLM_ASSERT(
142  "Information on image slice index is not correct, miss one of these fields : "
143  "m_axialSliceIndexId, m_frontalSliceIndexId, m_sagittalSliceIndexId.",
144  axialIdx && frontalIdx && sagittalIdx
145  );
146 
147  // Get value
148  if( axialIdx->value() < 0 || static_cast< int>(imageSize[2]) < axialIdx->value() )
149  {
150  axialIdx->value() = static_cast< ::fwData::Integer::ValueType >(imageSize[2] / 2);
151  fieldIsCreated = true;
152  }
153 
154  if( frontalIdx->value() < 0 || static_cast< int>(imageSize[1]) < frontalIdx->value() )
155  {
156  frontalIdx->value() = static_cast< ::fwData::Integer::ValueType >(imageSize[1] / 2);
157  fieldIsCreated = true;
158  }
159 
160  if( sagittalIdx->value() < 0 || static_cast< int>(imageSize[0]) < sagittalIdx->value() )
161  {
162  sagittalIdx->value() = static_cast< ::fwData::Integer::ValueType >(imageSize[0] / 2);
163  fieldIsCreated = true;
164  }
165 
166  m_sliceModified |= fieldIsCreated;
167  return fieldIsCreated;
168 }
169 
170 //-----------------------------------------------------------------------------
171 
173 {
174  if(m_sliceModified)
175  {
176  auto axialIdx = m_image->getField< ::fwData::Integer >(
178  auto frontalIdx = m_image->getField< ::fwData::Integer >(
180  auto sagittalIdx = m_image->getField< ::fwData::Integer >(
182  auto sig = m_image->signal< ::fwData::Image::SliceIndexModifiedSignalType >(
184  sig->asyncEmit(axialIdx->getValue(), frontalIdx->getValue(), sagittalIdx->getValue());
185  }
186 
188  sig->asyncEmit();
189 }
190 
191 //-----------------------------------------------------------------------------
192 
194 {
195  return m_lock.getBuffer();
196 }
197 
198 //------------------------------------------------------------------------------
199 
200 void* Image::getPixelBuffer( SizeType::value_type x, SizeType::value_type y, SizeType::value_type z )
201 {
202  SizeType size = m_image->getSize();
203  IndexType offset = x + size[0]*y + z*size[0]*size[1];
204  return this->getPixelBuffer(offset);
205 }
206 
207 //------------------------------------------------------------------------------
208 
209 void* Image::getPixelBuffer( IndexType index )
210 {
211  std::uint8_t imagePixelSize = m_image->getType().sizeOf() * m_image->getNumberOfComponents();
212  BufferType* buf = static_cast < BufferType* > (this->getBuffer());
213  BufferIndexType bufIndex = index * imagePixelSize;
214  return buf + bufIndex;
215 }
216 
217 //------------------------------------------------------------------------------
218 
219 void Image::setPixelBuffer( IndexType index, Image::BufferType* pixBuf)
220 {
221  std::uint8_t imagePixelSize = m_image->getType().sizeOf() * m_image->getNumberOfComponents();
222  BufferType* buf = static_cast < BufferType* > (this->getPixelBuffer(index));
223 
224  std::copy(pixBuf, pixBuf+imagePixelSize, buf);
225 }
226 
227 //------------------------------------------------------------------------------
228 
229 const std::string Image::getPixelAsString(SizeType::value_type x,
230  SizeType::value_type y,
231  SizeType::value_type z )
232 {
233  return m_image->getType().toString(this->getPixelBuffer(x, y, z));
234 }
235 
236 //------------------------------------------------------------------------------
237 
239 {
240  return m_lock;
241 }
242 
243 //------------------------------------------------------------------------------
244 
245 } // helper
246 } // fwDataTools
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_SLICE_INDEX_MODIFIED_SIG
Type of signal when image&#39;s buffer is added.
FWDATATOOLS_API bool createImageSliceIndex()
Create slice index if indexes are not present, NOT GENERATE MESSAGE.
virtual FWDATATOOLS_API ~Image()
Destrucotr. Do nothing.
Defines a helper to modify field on a fwData::Object and create a message notifying this modification...
Definition: Field.hpp:22
static FWDATA_API const std::string s_DEFAULT_TF_NAME
Default transfer function name.
FWDATATOOLS_API void notify()
Send the message of modification.
This class contains an integer value. Integer object is essentially used as a field in other objects...
Definition: Integer.hpp:24
static FWDATATOOLS_API const std::string m_transferFunctionCompositeId
The namespace fwDataTools contains classes which provide helpers to manipulate fwData::Object. *.
FWDATATOOLS_API void add(std::string _compositeKey,::fwData::Object::sptr _newObject)
Add an object in the composite.
Defines an helper to modify an fwData::Composite and create in parallel the message to announce this ...
FWDATATOOLS_API void setPixelBuffer(IndexType index, Image::BufferType *pixBuf)
Helpers for 3D images.
FWDATATOOLS_API void notify()
Send the built message and clear the internal maps.
Definition: Field.cpp:148
base class for BufferObject Lock
FWDATATOOLS_API bool createTransferFunctionPool()
Create transfer function pool if the pool is not present, NOT GENERATE MESSAGE.
FWDATATOOLS_API const std::string getPixelAsString(SizeType::value_type x, SizeType::value_type y, SizeType::value_type z)
Helpers for 3D images.
LockBase< T >::BufferType getBuffer() const
Returns BufferObject&#39;s buffer pointer.
FWDATATOOLS_API void notify()
Send the message of modification.
#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
FWDATATOOLS_API void setField(const ::fwData::Object::FieldNameType &name,::fwData::Object::sptr obj)
Register field with specified name. If the name does already exist, the matching field will be replac...
Definition: Field.cpp:41
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
static FWDATATOOLS_API bool checkImageValidity(::fwData::Image::csptr _pImg)
Check if the image is valid.
This class defines a composite object.
static void getMinMax(const ::fwData::Image::csptr _img, MINMAXTYPE &_min, MINMAXTYPE &_max)
Return minimum and maximum values contained in image. If image min or max value is out of MINMAXTYPE ...
FWDATATOOLS_API void * getBuffer()
Returns image buffer.
FWDATATOOLS_API Image(::fwData::Image::sptr image)
Constructor. Initialize parameters.
FWDATATOOLS_API void * getPixelBuffer(SizeType::value_type x, SizeType::value_type y, SizeType::value_type z)
Helpers for 3D images.
FWDATATOOLS_API bool createLandmarks()
Create landmark fields if not exist, NOT GENERATE MESSAGE.
FWDATATOOLS_API::fwMemory::BufferObject::Lock getLock() const
Returns a copy of current lock on image.