fw4spl
ImageDiff.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 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/ImageDiff.hpp"
8 
9 namespace fwDataTools
10 {
11 
12 //-----------------------------------------------------------------------------
13 
14 ImageDiff::ImageDiff(const size_t imageElementSize, const size_t reservedElements) :
15  m_imgEltSize(imageElementSize),
16  m_eltSize(imageElementSize * 2 + sizeof(::fwData::Image::IndexType)),
17  m_nbElts(0),
18  m_reservedSize(reservedElements * imageElementSize),
19  m_buffer(nullptr)
20 {
21 }
22 
23 //------------------------------------------------------------------------------
24 
26 {
27  free(m_buffer);
28 }
29 
30 //------------------------------------------------------------------------------
31 
33  m_imgEltSize(other.m_imgEltSize),
34  m_eltSize(other.m_eltSize),
35  m_nbElts(other.m_nbElts),
36  m_reservedSize(other.m_reservedSize),
37  m_buffer(reinterpret_cast<std::uint8_t*>(malloc(other.m_reservedSize)))
38 {
39  std::memcpy(m_buffer, other.m_buffer, m_reservedSize);
40 }
41 
42 //------------------------------------------------------------------------------
43 
45  m_imgEltSize(other.m_imgEltSize),
46  m_eltSize(other.m_eltSize),
47  m_nbElts(other.m_nbElts),
48  m_reservedSize(other.m_reservedSize),
49  m_buffer(other.m_buffer)
50 {
51  other.m_buffer = nullptr;
52 }
53 
54 //------------------------------------------------------------------------------
55 
57 {
58  ImageDiff tmpImageDiffs(other);
59  *this = std::move(tmpImageDiffs);
60 
61  return *this;
62 }
63 
64 //------------------------------------------------------------------------------
65 
67 {
68  free(m_buffer);
69 
70  m_buffer = other.m_buffer;
71  other.m_buffer = nullptr;
72 
73  m_imgEltSize = other.m_imgEltSize;
74  m_eltSize = other.m_eltSize;
75  m_nbElts = other.m_nbElts;
76  m_reservedSize = other.m_reservedSize;
77 
78  return *this;
79 }
80 
81 //------------------------------------------------------------------------------
82 
83 void ImageDiff::addDiff(const ImageDiff& diff)
84 {
85  SLM_ASSERT("Diff elements must be the same size.", m_eltSize == diff.m_eltSize);
86 
87  const size_t oldSize = this->getSize();
88  const size_t newSize = oldSize + diff.getSize();
89 
90  if(m_reservedSize < newSize || m_buffer == nullptr)
91  {
92  // Double the reserved size.
93  m_reservedSize = newSize + m_reservedSize * 2;
94  m_buffer = reinterpret_cast<std::uint8_t*>(realloc(m_buffer, m_reservedSize));
95 
96  SLM_FATAL_IF("Reallocation failed.", m_buffer == nullptr);
97  }
98 
99  std::uint8_t* eltPtr = (m_buffer + oldSize);
100  std::memcpy(eltPtr, diff.m_buffer, diff.getSize());
101 
102  m_nbElts += diff.m_nbElts;
103 }
104 
105 //-----------------------------------------------------------------------------
106 
107 void ImageDiff::addDiff(const ::fwData::Image::IndexType index, const ::fwData::Image::BufferType* oldValue,
108  const ::fwData::Image::BufferType* newValue)
109 {
110  const size_t oldSize = this->getSize();
111  const size_t newSize = oldSize + m_eltSize;
112 
113  if(m_reservedSize < newSize || m_buffer == nullptr)
114  {
115  // Double the reserved size.
116  m_reservedSize = m_reservedSize * 2 + m_eltSize;
117  m_buffer = reinterpret_cast<std::uint8_t*>(realloc(m_buffer, m_reservedSize));
118 
119  SLM_FATAL_IF("Reallocation failed.", m_buffer == nullptr);
120  }
121 
122  std::uint8_t* eltPtr = (m_buffer + oldSize);
123 
124  std::memcpy(eltPtr, &index, sizeof(index));
125  size_t offset = sizeof(index);
126  std::memcpy(eltPtr + offset, oldValue, m_imgEltSize);
127  offset += m_imgEltSize;
128  std::memcpy(eltPtr + offset, newValue, m_imgEltSize);
129 
130  m_nbElts++;
131 }
132 
133 //------------------------------------------------------------------------------
134 
135 void ImageDiff::applyDiff(const ::fwData::Image::sptr& img) const
136 {
137  helper::Image imgHelper(img);
138 
139  for(size_t i = 0; i < m_nbElts; ++i)
140  {
141  applyDiffElt(imgHelper, i);
142  }
143 }
144 
145 //------------------------------------------------------------------------------
146 
147 void ImageDiff::revertDiff(const ::fwData::Image::sptr& img) const
148 {
149  helper::Image imgHelper(img);
150 
151  for(size_t i = 0; i < m_nbElts; ++i)
152  {
153  revertDiffElt(imgHelper, i);
154  }
155 }
156 
157 //------------------------------------------------------------------------------
158 
159 size_t ImageDiff::getSize() const
160 {
161  return m_nbElts * m_eltSize;
162 }
163 
164 //------------------------------------------------------------------------------
165 
167 {
168  return m_nbElts;
169 }
170 
171 //------------------------------------------------------------------------------
172 
174 {
175  m_nbElts = 0;
176 }
177 
178 //------------------------------------------------------------------------------
179 
181 {
182  m_reservedSize = this->getSize();
183  m_buffer = reinterpret_cast<std::uint8_t*>(realloc(m_buffer, m_reservedSize));
184 
185  SLM_FATAL_IF("Reallocation failed.", m_buffer == nullptr);
186 }
187 
188 //------------------------------------------------------------------------------
189 
191 {
192  std::uint8_t* eltPtr = m_buffer + index * m_eltSize;
193  ElementType elt;
194  elt.m_index = *reinterpret_cast< ::fwData::Image::IndexType* >(eltPtr);
195 
196  size_t offset = sizeof(::fwData::Image::IndexType);
197 
198  elt.m_oldValue = reinterpret_cast< ::fwData::Image::BufferType* >(eltPtr + offset);
199 
200  offset += m_imgEltSize;
201 
202  elt.m_newValue = reinterpret_cast< ::fwData::Image::BufferType* >(eltPtr + offset);
203 
204  return elt;
205 }
206 
207 //------------------------------------------------------------------------------
208 
209 void ImageDiff::applyDiffElt(helper::Image& img, size_t eltIndex) const
210 {
211  std::uint8_t* eltPtr = m_buffer + eltIndex * m_eltSize;
212  const ::fwData::Image::IndexType index = *reinterpret_cast< ::fwData::Image::IndexType* >(eltPtr);
213 
214  const size_t offset = sizeof(index) + m_imgEltSize;
215 
216  ::fwData::Image::BufferType* newValue = reinterpret_cast< ::fwData::Image::BufferType* >(eltPtr + offset);
217 
218  img.setPixelBuffer(index, newValue);
219 }
220 
221 //------------------------------------------------------------------------------
222 
223 void ImageDiff::revertDiffElt(helper::Image& img, size_t eltIndex) const
224 {
225  std::uint8_t* eltPtr = m_buffer + eltIndex * m_eltSize;
226  const ::fwData::Image::IndexType index = *reinterpret_cast< ::fwData::Image::IndexType* >(eltPtr);
227 
228  const size_t offset = sizeof(index);
229 
230  ::fwData::Image::BufferType* oldValue = reinterpret_cast< ::fwData::Image::BufferType* >(eltPtr + offset);
231 
232  img.setPixelBuffer(index, oldValue);
233 }
234 
235 } // namespace fwDataTools
FWDATATOOLS_API void addDiff(const ImageDiff &diff)
Concatenate two diffs.
Definition: ImageDiff.cpp:83
FWDATATOOLS_API ImageDiff & operator=(const ImageDiff &other)
Copy assignement.
Definition: ImageDiff.cpp:56
FWDATATOOLS_API void shrink()
Reallocate the buffer to fit the actual size of the container.
Definition: ImageDiff.cpp:180
The namespace fwDataTools contains classes which provide helpers to manipulate fwData::Object. *.
STL namespace.
FWDATATOOLS_API void setPixelBuffer(IndexType index, Image::BufferType *pixBuf)
Helpers for 3D images.
FWDATATOOLS_API ElementType getElement(size_t index) const
Returns the element at the given index.
Definition: ImageDiff.cpp:190
FWDATATOOLS_API size_t getSize() const
Return the amount of memory actually used by the elements.
Definition: ImageDiff.cpp:159
FWDATATOOLS_API void clear()
Set the number of elements to 0.
Definition: ImageDiff.cpp:173
FWDATATOOLS_API void revertDiff(const ::fwData::Image::sptr &img) const
Write the old value back in the image.
Definition: ImageDiff.cpp:147
Defines an helper to modify an fwData::Image by adding few medical fields and create in parallel the ...
FWDATATOOLS_API ImageDiff(const size_t imageElementSize=0, const size_t reservedElements=0)
Constructor.
Definition: ImageDiff.cpp:14
FWDATATOOLS_API void applyDiff(const ::fwData::Image::sptr &img) const
Write the new values in the image.
Definition: ImageDiff.cpp:135
FWDATATOOLS_API size_t getNumberOfElements() const
Returns the number of stored pixel diffs.
Definition: ImageDiff.cpp:166
#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
#define SLM_FATAL_IF(message, cond)
Definition: spyLog.hpp:287
Class memorizing pixel changes in an image.
Definition: ImageDiff.hpp:21
FWDATATOOLS_API ~ImageDiff()
Destructor.
Definition: ImageDiff.cpp:25
Contains the representation of the data objects used in the framework.
This class contains helper to generate and compare images.