SMIL  0.9.1
DBaseImageOperations.hxx
1 /*
2  * Copyright (c) 2011-2016, Matthieu FAESSEL and ARMINES
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Matthieu FAESSEL, or ARMINES nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 
30 #ifndef _BASE_IMAGE_OPERATIONS_HXX
31 #define _BASE_IMAGE_OPERATIONS_HXX
32 
33 #include "Core/include/private/DImage.hpp"
34 
35 namespace smil
36 {
37 
38  template <class T>
39  struct fillLine;
40 
41  template <class T>
42  typename Image<T>::lineType *imageFunctionBase<T>::createAlignedBuffers(size_t nbr, size_t len)
43  {
44  if (alignedBuffers)
45  {
46  if (nbr==bufferNumber && len==bufferLength)
47  return alignedBuffers;
48  else
49  deleteAlignedBuffers();
50  }
51 
52 
53  bufferNumber = nbr;
54  bufferLength = len;
55  bufferSize = bufferLength * sizeof(T);
56 
57  alignedBuffers = new lineType[bufferNumber];
58  for (size_t i=0;i<bufferNumber;i++)
59  alignedBuffers[i] = ImDtTypes<T>::createLine(len);
60 
61  return alignedBuffers;
62  }
63 
64 
65  template <class T>
67  {
68  if (!alignedBuffers) return;
69 
70  for (UINT i=0;i<bufferNumber;i++)
71  ImDtTypes<T>::deleteLine(alignedBuffers[i]);
72  delete[] alignedBuffers;
73  alignedBuffers = NULL;
74  }
75 
76  template <class T>
77  inline void imageFunctionBase<T>::copyLineToBuffer(T *line, size_t bufIndex)
78  {
79  memcpy(alignedBuffers[bufIndex], line, bufferSize);
80  }
81 
82  template <class T>
83  inline void imageFunctionBase<T>::copyBufferToLine(size_t bufIndex, T *line)
84  {
85  memcpy(line, alignedBuffers[bufIndex], bufferSize);
86  }
87 
88 
89 
90 
91  template <class T, class lineFunction_T, class T_out>
93  {
94  if (!areAllocated(&imIn, &imOut, NULL))
95  return RES_ERR_BAD_ALLOCATION;
96 
97  int lineLen = imIn.getWidth();
98  int lineCount = imIn.getLineCount();
99 
100  sliceInType srcLines = imIn.getLines();
101  sliceOutType destLines = imOut.getLines();
102 
103  int i;
104  #ifdef USE_OPEN_MP
105  int nthreads = Core::getInstance()->getNumberOfThreads();
106  #pragma omp parallel private(i) num_threads(nthreads)
107  #endif // USE_OPEN_MP
108  {
109  #ifdef USE_OPEN_MP
110  #pragma omp for
111  #endif // USE_OPEN_MP
112  for (i=0;i<lineCount;i++)
113  lineFunction._exec(srcLines[i], lineLen, destLines[i]);
114  }
115  imOut.modified();
116 
117  return RES_OK;
118  }
119 
120 
121  template <class T, class lineFunction_T, class T_out>
122  RES_T unaryImageFunction<T, lineFunction_T, T_out>::_exec(imageOutType &imOut, const T_out &value)
123  {
124  if (!areAllocated(&imOut, NULL))
125  return RES_ERR_BAD_ALLOCATION;
126 
127  size_t lineLen = imOut.getWidth();
128  int lineCount = imOut.getLineCount();
129 
130  sliceOutType destLines = imOut.getLines();
131  lineOutType constBuf = ImDtTypes<T_out>::createLine(lineLen);
132 
133  // Fill the first aligned buffer with the constant value
134  fillLine<T_out>(constBuf, lineLen, value);
135 
136  // Use it for operations on lines
137 
138  int i;
139  #ifdef USE_OPEN_MP
140  int nthreads = Core::getInstance()->getNumberOfThreads();
141  #pragma omp parallel private(i) num_threads(nthreads)
142  #endif // USE_OPEN_MP
143  {
144  #ifdef USE_OPEN_MP
145  #pragma omp for
146  #endif // USE_OPEN_MP
147  for (i=0;i<lineCount;i++)
148  lineFunction._exec(constBuf, lineLen, destLines[i]);
149  }
151  imOut.modified();
152 
153  return RES_OK;
154  }
155 
156 
157  // Binary image function
158  template <class T, class lineFunction_T>
159  RES_T binaryImageFunction<T, lineFunction_T>::_exec(const imageType &imIn1, const imageType &imIn2, imageType &imOut)
160  {
161  if (!areAllocated(&imIn1, &imIn2, &imOut, NULL))
162  return RES_ERR_BAD_ALLOCATION;
163 
164  size_t lineLen = imIn1.getWidth();
165  size_t lineCount = imIn1.getLineCount();
166 
167  lineType *srcLines1 = imIn1.getLines();
168  lineType *srcLines2 = imIn2.getLines();
169  lineType *destLines = imOut.getLines();
170 
171  int i;
172  #ifdef USE_OPEN_MP
173  int nthreads = Core::getInstance()->getNumberOfThreads();
174  #pragma omp parallel private(i) num_threads(nthreads)
175  #endif // USE_OPEN_MP
176  {
177  #ifdef USE_OPEN_MP
178  #pragma omp for
179  #endif // USE_OPEN_MP
180  for (i=0;i<(int)lineCount;i++)
181  lineFunction(srcLines1[i], srcLines2[i], lineLen, destLines[i]);
182  }
183  imOut.modified();
184 
185  return RES_OK;
186  }
187 
188  // Binary image function
189  template <class T, class lineFunction_T>
190  RES_T binaryImageFunction<T, lineFunction_T>::_exec(const imageType &imIn, imageType &imInOut)
191  {
192  if (!areAllocated(&imIn, &imInOut, NULL))
193  return RES_ERR_BAD_ALLOCATION;
194 
195  size_t lineLen = imIn.getWidth();
196  int lineCount = imIn.getLineCount();
197 
198  sliceType srcLines1 = imIn.getLines();
199  sliceType srcLines2 = imInOut.getLines();
200 
201  lineType tmpBuf = ImDtTypes<T>::createLine(lineLen);
202 
203  int i;
204  #ifdef USE_OPEN_MP
205  int nthreads = Core::getInstance()->getNumberOfThreads();
206  #pragma omp parallel private(i) num_threads(nthreads)
207  #endif // USE_OPEN_MP
208  {
209  #ifdef USE_OPEN_MP
210  #pragma omp for
211  #endif // USE_OPEN_MP
212  for (i=0;i<lineCount;i++)
213  lineFunction(srcLines1[i], srcLines2[i], lineLen, tmpBuf);
214  }
215 
216  ImDtTypes<T>::deleteLine(tmpBuf);
217  imInOut.modified();
218 
219  return RES_OK;
220  }
221 
222 
223  // Binary image function
224  template <class T, class lineFunction_T>
225  RES_T binaryImageFunction<T, lineFunction_T>::_exec(const imageType &imIn, const T &value, imageType &imOut)
226  {
227  if (!areAllocated(&imIn, &imOut, NULL))
228  return RES_ERR_BAD_ALLOCATION;
229 
230  size_t lineLen = imIn.getWidth();
231  int lineCount = imIn.getLineCount();
232 
233  sliceType srcLines = imIn.getLines();
234  sliceType destLines = imOut.getLines();
235 
236  lineType constBuf = ImDtTypes<T>::createLine(lineLen);
237 
238  // Fill the const buffer with the value
239  fillLine<T> f;
240  f(constBuf, lineLen, value);
241 
242  int i;
243  #ifdef USE_OPEN_MP
244  int nthreads = Core::getInstance()->getNumberOfThreads();
245  #pragma omp parallel private(i) num_threads(nthreads)
246  #endif // USE_OPEN_MP
247  {
248  #ifdef USE_OPEN_MP
249  #pragma omp for
250  #endif // USE_OPEN_MP
251  for (i=0;i<lineCount;i++)
252  lineFunction(srcLines[i], constBuf, lineLen, destLines[i]);
253  }
254 
255  ImDtTypes<T>::deleteLine(constBuf);
256  imOut.modified();
257 
258  return RES_OK;
259  }
260 
261 
262  template <class T, class lineFunction_T>
263  RES_T binaryImageFunction<T, lineFunction_T>::_exec(const T &value, const imageType &imIn, imageType &imOut)
264  {
265  if (!areAllocated(&imIn, &imOut, NULL))
266  return RES_ERR_BAD_ALLOCATION;
267 
268  size_t lineLen = imIn.getWidth();
269  int lineCount = imIn.getLineCount();
270 
271  sliceType srcLines = imIn.getLines();
272  sliceType destLines = imOut.getLines();
273 
274  lineType constBuf = ImDtTypes<T>::createLine(lineLen);
275 
276  // Fill the const buffer with the value
277  fillLine<T> f;
278  f(constBuf, lineLen, value);
279 
280  int i;
281  #ifdef USE_OPEN_MP
282  int nthreads = Core::getInstance()->getNumberOfThreads();
283  #pragma omp parallel private(i) num_threads(nthreads)
284  #endif // USE_OPEN_MP
285  {
286  #ifdef USE_OPEN_MP
287  #pragma omp for
288  #endif // USE_OPEN_MP
289  for (i=0;i<lineCount;i++)
290  lineFunction(constBuf, srcLines[i], lineLen, destLines[i]);
291  }
292 
293  ImDtTypes<T>::deleteLine(constBuf);
294  imOut.modified();
295 
296  return RES_OK;
297  }
298 
299 
300 
301  // Tertiary image function
302  template <class T, class lineFunction_T>
303  template <class T2>
304  RES_T tertiaryImageFunction<T, lineFunction_T>::_exec(const imageType &imIn1, const Image<T2> &imIn2, const Image<T2> &imIn3, Image<T2> &imOut)
305  {
306  if (!areAllocated(&imIn1, &imIn2, &imIn3, &imOut, NULL))
307  return RES_ERR_BAD_ALLOCATION;
308 
309  size_t lineLen = imIn1.getWidth();
310  int lineCount = imIn1.getLineCount();
311 
312  typedef typename Image<T2>::sliceType sliceType2;
313 
314  sliceType srcLines1 = imIn1.getLines();
315  sliceType2 srcLines2 = imIn2.getLines();
316  sliceType2 srcLines3 = imIn3.getLines();
317  sliceType2 destLines = imOut.getLines();
318 
319  int i;
320  #ifdef USE_OPEN_MP
321  int nthreads = Core::getInstance()->getNumberOfThreads();
322  #pragma omp parallel private(i) num_threads(nthreads)
323  #endif // USE_OPEN_MP
324  {
325  #ifdef USE_OPEN_MP
326  #pragma omp for
327  #endif // USE_OPEN_MP
328  for (i=0;i<lineCount;i++)
329  lineFunction(srcLines1[i], srcLines2[i], srcLines3[i], lineLen, destLines[i]);
330  }
331 
332  imOut.modified();
333 
334  return RES_OK;
335  }
336 
337  // Tertiary image function
338  template <class T, class lineFunction_T>
339  template <class T2>
340  RES_T tertiaryImageFunction<T, lineFunction_T>::_exec(const imageType &imIn1, const Image<T2> &imIn2, const T2 &value, Image<T2> &imOut)
341  {
342  if (!areAllocated(&imIn1, &imIn2, &imOut, NULL))
343  return RES_ERR_BAD_ALLOCATION;
344 
345  size_t lineLen = imIn1.getWidth();
346  int lineCount = imIn1.getLineCount();
347 
348  typedef typename Image<T2>::lineType lineType2;
349  typedef typename Image<T2>::sliceType sliceType2;
350 
351  sliceType srcLines1 = imIn1.getLines();
352  sliceType2 srcLines2 = imIn2.getLines();
353  sliceType2 destLines = imOut.getLines();
354 
355  lineType2 constBuf = ImDtTypes<T2>::createLine(lineLen);
356 
357  // Fill the const buffer with the value
358  fillLine<T2> f;
359  f(constBuf, lineLen, value);
360 
361  int i;
362  #ifdef USE_OPEN_MP
363  int nthreads = Core::getInstance()->getNumberOfThreads();
364  #pragma omp parallel private(i) num_threads(nthreads)
365  #endif // USE_OPEN_MP
366  {
367  #ifdef USE_OPEN_MP
368  #pragma omp for
369  #endif // USE_OPEN_MP
370  for (i=0;i<lineCount;i++)
371  lineFunction(srcLines1[i], srcLines2[i], constBuf, lineLen, destLines[i]);
372  }
373 
374  ImDtTypes<T2>::deleteLine(constBuf);
375  imOut.modified();
376 
377  return RES_OK;
378  }
379 
380  template <class T, class lineFunction_T>
381  template <class T2>
382  RES_T tertiaryImageFunction<T, lineFunction_T>::_exec(const imageType &imIn1, const T2 &value, const Image<T2> &imIn2, Image<T2> &imOut)
383  {
384  if (!areAllocated(&imIn1, &imIn2, &imOut, NULL))
385  return RES_ERR_BAD_ALLOCATION;
386 
387  size_t lineLen = imIn1.getWidth();
388  int lineCount = imIn1.getLineCount();
389 
390  typedef typename Image<T2>::lineType lineType2;
391  typedef typename Image<T2>::sliceType sliceType2;
392 
393  sliceType srcLines1 = imIn1.getLines();
394  sliceType2 srcLines2 = imIn2.getLines();
395  sliceType2 destLines = imOut.getLines();
396 
397  lineType2 constBuf = ImDtTypes<T2>::createLine(lineLen);
398 
399  // Fill the const buffer with the value
400  fillLine<T2> f;
401  f(constBuf, lineLen, value);
402 
403  int i;
404  #ifdef USE_OPEN_MP
405  int nthreads = Core::getInstance()->getNumberOfThreads();
406  #pragma omp parallel private(i) num_threads(nthreads)
407  #endif // USE_OPEN_MP
408  {
409  #ifdef USE_OPEN_MP
410  #pragma omp for
411  #endif // USE_OPEN_MP
412  for (i=0;i<lineCount;i++)
413  lineFunction(srcLines1[i], constBuf, srcLines2[i], lineLen, destLines[i]);
414  }
415 
416  ImDtTypes<T2>::deleteLine(constBuf);
417  imOut.modified();
418 
419  return RES_OK;
420  }
421 
422 
423  template <class T, class lineFunction_T>
424  template <class T2>
425  RES_T tertiaryImageFunction<T, lineFunction_T>::_exec(const imageType &imIn, const T2 &value1, const T2 &value2, Image<T2> &imOut)
426  {
427  if (!areAllocated(&imIn, &imOut, NULL))
428  return RES_ERR_BAD_ALLOCATION;
429 
430  size_t lineLen = imIn.getWidth();
431  int lineCount = imIn.getLineCount();
432 
433  typedef typename Image<T2>::lineType lineType2;
434  typedef typename Image<T2>::sliceType sliceType2;
435 
436  sliceType srcLines = imIn.getLines();
437  sliceType2 destLines = imOut.getLines();
438 
439  lineType2 constBuf1 = ImDtTypes<T2>::createLine(lineLen);
440  lineType2 constBuf2 = ImDtTypes<T2>::createLine(lineLen);
441 
442  // Fill the const buffers with the values
443  fillLine<T2> f;
444  f(constBuf1, lineLen, value1);
445  f(constBuf2, lineLen, value2);
446 
447  int i;
448  #ifdef USE_OPEN_MP
449  int nthreads = Core::getInstance()->getNumberOfThreads();
450  #pragma omp parallel private(i) num_threads(nthreads)
451  #endif // USE_OPEN_MP
452  {
453  #ifdef USE_OPEN_MP
454  #pragma omp for
455  #endif // USE_OPEN_MP
456  for (i=0;i<lineCount;i++)
457  lineFunction(srcLines[i], constBuf1, constBuf2, lineLen, destLines[i]);
458  }
459 
460  ImDtTypes<T2>::deleteLine(constBuf1);
461  ImDtTypes<T2>::deleteLine(constBuf2);
462  imOut.modified();
463 
464  return RES_OK;
465  }
466 
467 } // namespace smil
468 
469 
470 #endif
Definition: DBaseImageOperations.hpp:42
Definition: DColorConvert.h:38
sliceType getLines() const
Get an array containing the start offset of each line.
Definition: DImage.hpp:114
Definition: DBaseImageOperations.hpp:72
Definition: DBaseImageOperations.hxx:39
virtual void modified()
Trigger modified event (allows to force display update)
Definition: DImage.hxx:223
size_t getWidth() const
Get image width.
Definition: DBaseImage.h:87
Definition: DBaseImageOperations.hpp:114
Definition: DTypes.hpp:78
Main Image class.
Definition: DQVtkViewer.hpp:44
size_t getLineCount() const
Get the number of lines.
Definition: DBaseImage.h:154
Definition: DBaseImageOperations.hpp:161