SMIL  1.0.4
DLineArith_Bit.h
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
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 
32 #ifndef _D_LINE_ARITH_BIT_H
33 #define _D_LINE_ARITH_BIT_H
34 
35 
36 #include "DBitArray.h"
37 #include "Base/include/private/DLineArith.hpp"
38 
44 namespace smil
45 {
46 
47  template <>
48  inline void copyLine<Bit>(const typename Image<Bit>::lineType lIn, const size_t size, typename Image<Bit>::lineType lOut)
49  {
50  // copyLine<BitArray::INT_TYPE>(lIn.intArray, BitArray::INT_SIZE(size), lOut.intArray);
51  // UINT realSize = BitArray::INT_SIZE(size)*sizeof(BitArray::INT_TYPE);
52  // memcpy(&lOut, &lIn, realSize);
53 
54  if (lIn.index==0 && lOut.index==0)
55  {
56  UINT fullNbr = size/BitArray::INT_TYPE_SIZE;
57  UINT bitRes = size - fullNbr*BitArray::INT_TYPE_SIZE;
58 
59  memcpy(lOut.intArray, lIn.intArray, fullNbr*sizeof(BitArray::INT_TYPE));
60 
61  if (bitRes)
62  lOut.intArray[fullNbr] = lIn.intArray[fullNbr];
63  // lOut.intArray[fullNbr] = ((lIn.intArray[fullNbr] >> (BitArray::INT_TYPE_SIZE-bitRes))) | ((lOut.intArray[fullNbr] << bitRes));
64  }
65  else
66  {
67  for (size_t i=0;i<size;i++)
68  lOut[i] = lIn[i];
69  }
70  }
71 
72  template <>
73  struct fillLine<Bit> : public unaryLineFunctionBase<Bit>
74  {
75  fillLine() {}
76  fillLine(BitArray lInOut, size_t size, Bit value) { this->_exec(lInOut, size, value); }
77 
78  inline void _exec(BitArray lIn, size_t size, BitArray lOut) { copyLine<Bit>(lIn, size, lOut); }
79  inline void _exec(BitArray lInOut, size_t size, Bit value)
80  {
81  BitArray::INT_TYPE intVal = (bool)value ? BitArray::INT_TYPE_MAX() : BitArray::INT_TYPE_MIN();
82  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
83  lInOut.intArray[i] = intVal;
84  }
85  };
86  // template <class T1>
87  // inline void copyLine(T1 *lIn, size_t size, BitArray lOut)
88  // {
89  // UINT nBin = Bit::binLen(size);
90  // T1 *pIn = lIn;
91  // Bit::Type *bOut = (Bit::Type*)lOut;
92  // Bit::Type tmp;
93  //
94  // for (int b=0;b<nBin-1;b++,bOut++)
95  // {
96  // for (int i=0;i<Bit::SIZE;i++,pIn++)
97  // {
98  // if (*pIn!=0)
99  // tmp |= (1<<i);
100  // else
101  // tmp &= ~(1<<i);
102  // }
103  // *bOut = tmp;
104  // }
105  // for (int i=0;i<size%Bit::SIZE;i++,pIn++)
106  // {
107  // if (*pIn!=0)
108  // tmp |= (1<<i);
109  // else
110  // tmp &= ~(1<<i);
111  // }
112  // *bOut = tmp;
113  //
114  // }
115 
116  // template <class T2>
117  // inline void copyLine(BitArray lIn, int size, T2 *lOut)
118  // {
119  // // size must correspond here to the imIn width, i.e. the real number of pixels (see DImageArith.hpp)
120  //
121  // UINT nBin = (size-1)/Bit::SIZE + 1;
122  // T1 *pIn = lIn;
123  // Bit::Type *bOut = (Bit::Type*)lOut;
124  // Bit::Type tmp;
125  //
126  // for (int b=0;b<nBin-1;b++,bOut++)
127  // {
128  // for (int i=0;i<Bit::SIZE;i++,pIn++)
129  // {
130  // if (*pIn!=0)
131  // tmp |= (1<<i);
132  // else
133  // tmp &= ~(1<<i);
134  // }
135  // *bOut = tmp;
136  // }
137  // for (int i=0;i<size%Bit::SIZE;i++,pIn++)
138  // {
139  // if (*pIn!=0)
140  // tmp |= (1<<i);
141  // else
142  // tmp &= ~(1<<i);
143  // }
144  // *bOut = tmp;
145  // }
146 
147 
148 
149  inline void bitShiftLeft(BitArray lIn, int dx, size_t lineLen, BitArray lOut, Bit borderValue)
150  {
151  UINT realLen = BitArray::INT_SIZE(lineLen);
152  UINT dxBytes = dx/BitArray::INT_TYPE_SIZE;
153 
154  BitArray::INT_TYPE *bIn = lIn.intArray;
155  BitArray::INT_TYPE *bOut = lOut.intArray;
156  BitArray::INT_TYPE bBorder = (bool)borderValue ? BitArray::INT_TYPE_MAX() : BitArray::INT_TYPE_MIN();
157 
158  if (dx>=(int)lineLen)
159  {
160  fillLine<Bit>(lOut, lineLen, borderValue);
161  return;
162  }
163 
164  for (int i=0;i<(int)dxBytes;i++,bOut++)
165  *bOut = bBorder;
166 
167  UINT lMov = dx%BitArray::INT_TYPE_SIZE;
168  UINT rMov = BitArray::INT_TYPE_SIZE - lMov;
169 
170  // First run with border to keep the loop clean for vectorization
171  *bOut++ = (*bIn++ << lMov) | (bBorder >> rMov);
172 
173  for (int i=dxBytes+1;i<(int)realLen;i++,bIn++,bOut++)
174  *bOut = (*bIn << lMov) | (*(bIn-1) >> rMov);
175  }
176 
177  inline void bitShiftRight(BitArray lIn, int dx, size_t lineLen, BitArray lOut, Bit borderValue)
178  {
179  UINT realLen = BitArray::INT_SIZE(lineLen);
180  UINT lenDiff = lIn.getBitPadX();
181  UINT dxReal = dx + lenDiff;
182 
183  UINT dxBytes = dxReal/BitArray::INT_TYPE_SIZE;
184 
185  BitArray::INT_TYPE *bIn = lIn.intArray + realLen-1;
186  BitArray::INT_TYPE *bOut = lOut.intArray + realLen-1;
187  BitArray::INT_TYPE bBorder = (bool)borderValue ? BitArray::INT_TYPE_MAX() : BitArray::INT_TYPE_MIN();
188 
189  if (dx>=(int)lineLen)
190  {
191  fillLine<Bit>(lOut, lineLen, borderValue);
192  return;
193  }
194 
195  for (int i=0;i<(int)dxBytes;i++,bOut--)
196  *bOut = bBorder;
197 
198  BitArray::INT_TYPE rMov = dx%BitArray::INT_TYPE_SIZE;
199  BitArray::INT_TYPE lMov = BitArray::INT_TYPE_SIZE - rMov;
200 
201  // First run with border to keep the loop clean for vectorization
202  BitArray::INT_TYPE rightMask = *bIn-- & (BitArray::INT_TYPE_MAX() >> lenDiff);
203  *bOut-- = (rightMask >> rMov) | (bBorder << lMov);
204 
205  if (dxBytes+1<realLen)
206  *bOut-- = (*bIn-- >> rMov) | (rightMask << lMov);
207 
208  for (int i=dxBytes+2;i<(int)realLen;i++,bIn--,bOut--)
209  *bOut = (*bIn >> rMov) | (*(bIn+1) << lMov);
210  }
211 
212  template <>
213  inline void shiftLine<Bit>(const Image<Bit>::lineType lIn, int dx, size_t lineLen, Image<Bit>::lineType lOut, Bit borderValue)
214  {
215  if (dx==0)
216  copyLine<Bit>(lIn, lineLen, lOut);
217  else if (dx>0)
218  bitShiftLeft(lIn, dx, lineLen, lOut, borderValue);
219  else
220  bitShiftRight(lIn, -dx, lineLen, lOut, borderValue);
221  }
222 
223 
224  template <>
225  struct invLine<Bit> : public unaryLineFunctionBase<Bit>
226  {
227  inline void _exec(BitArray lIn, size_t size, BitArray lOut)
228  {
229  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
230  lOut.intArray[i] = ~(lIn.intArray[i]);
231  }
232  };
233 
234  template <>
235  struct addLine<Bit> : public binaryLineFunctionBase<Bit>
236  {
237  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
238  {
239  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
240  lOut.intArray[i] = lIn1.intArray[i] | lIn2.intArray[i];
241  }
242  };
243 
244  template <>
245  struct addNoSatLine<Bit> : public binaryLineFunctionBase<Bit>
246  {
247  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
248  {
249  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
250  lOut.intArray[i] = lIn1.intArray[i] ^ lIn2.intArray[i];
251  }
252  };
253 
254  template <>
255  struct subLine<Bit> : public binaryLineFunctionBase<Bit>
256  {
257  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
258  {
259  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
260  lOut.intArray[i] = lIn1.intArray[i] & ~lIn2.intArray[i];
261  }
262  };
263 
264  template <>
265  struct subNoSatLine<Bit> : public binaryLineFunctionBase<Bit>
266  {
267  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
268  {
269  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
270  lOut.intArray[i] = lIn1.intArray[i] ^ lIn2.intArray[i];
271  }
272  };
273 
274  template <>
275  struct supLine<Bit> : public binaryLineFunctionBase<Bit>
276  {
277  typedef typename Image<Bit>::lineType lineType;
278  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
279  {
280  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
281  lOut.intArray[i] = (lIn1.intArray[i] | lIn2.intArray[i]);
282  }
283  };
284 
285  template <>
286  struct infLine<Bit> : public binaryLineFunctionBase<Bit>
287  {
288  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
289  {
290  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
291  lOut.intArray[i] = lIn1.intArray[i] & lIn2.intArray[i];
292  }
293  };
294 
295  template <>
296  struct grtLine<Bit> : public binaryLineFunctionBase<Bit>
297  {
298  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
299  {
300  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
301  lOut.intArray[i] = lIn1.intArray[i] & ~lIn2.intArray[i];
302  }
303  };
304 
305  template <>
306  struct grtOrEquLine<Bit> : public binaryLineFunctionBase<Bit>
307  {
308  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
309  {
310  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
311  lOut.intArray[i] = lIn1.intArray[i] | ~lIn2.intArray[i];
312  }
313  };
314 
315  template <>
316  struct lowLine<Bit> : public binaryLineFunctionBase<Bit>
317  {
318  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
319  {
320  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
321  lOut.intArray[i] = ~lIn1.intArray[i] & lIn2.intArray[i];
322  }
323  };
324 
325  template <>
326  struct lowOrEquLine<Bit> : public binaryLineFunctionBase<Bit>
327  {
328  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
329  {
330  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
331  lOut.intArray[i] = ~lIn1.intArray[i] | lIn2.intArray[i];
332  }
333  };
334 
335  template <>
336  struct equLine<Bit> : public binaryLineFunctionBase<Bit>
337  {
338  typedef typename Image<Bit>::lineType lineType;
339  inline void _exec(lineType lIn1, lineType lIn2, size_t size, lineType lOut)
340  {
341  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
342  lOut.intArray[i] = ~(lIn1.intArray[i] ^ lIn2.intArray[i]);
343  }
344  };
345 
346  template <>
347  struct diffLine<Bit> : public binaryLineFunctionBase<Bit>
348  {
349  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
350  {
351  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
352  lOut.intArray[i] = lIn1.intArray[i] ^ lIn2.intArray[i];
353  }
354  };
355 
356  template <>
357  struct mulLine<Bit> : public binaryLineFunctionBase<Bit>
358  {
359  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
360  {
361  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
362  lOut.intArray[i] = lIn1.intArray[i] & lIn2.intArray[i];
363  }
364  };
365 
366  template <>
367  struct mulNoSatLine<Bit> : public binaryLineFunctionBase<Bit>
368  {
369  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
370  {
371  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
372  lOut.intArray[i] = lIn1.intArray[i] & lIn2.intArray[i];
373  }
374  };
375 
376  template <>
377  struct divLine<Bit> : public binaryLineFunctionBase<Bit>
378  {
379  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
380  {
381  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
382  lOut.intArray[i] = lIn1.intArray[i] | ~lIn2.intArray[i];
383  }
384  };
385 
386  template <>
387  struct logicAndLine<Bit> : public binaryLineFunctionBase<Bit>
388  {
389  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
390  {
391  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
392  lOut.intArray[i] = lIn1.intArray[i] & lIn2.intArray[i];
393  }
394  };
395 
396  template <>
397  struct logicOrLine<Bit> : public binaryLineFunctionBase<Bit>
398  {
399  inline void _exec(BitArray lIn1, BitArray lIn2, size_t size, BitArray lOut)
400  {
401  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
402  lOut.intArray[i] = lIn1.intArray[i] | lIn2.intArray[i];
403  }
404  };
405 
406  template <>
407  struct testLine<Bit, Bit> : public tertiaryLineFunctionBase<Bit>
408  {
409  inline void _exec(BitArray lIn1, BitArray lIn2, BitArray lIn3, size_t size, BitArray lOut)
410  {
411  for (size_t i=0;i<BitArray::INT_SIZE(size);i++)
412  lOut.intArray[i] = (lIn1.intArray[i] & lIn2.intArray[i]) | (~lIn1.intArray[i] & lIn3.intArray[i]);
413  }
414  };
415 
416 } // namespace smil
417 
420 #endif // _D_LINE_ARITH_BIT_H
Definition: DBitArray.h:46
Definition: DBaseLineOperations.hpp:110
Definition: DLineArith_Bit.h:74
Definition: DBaseImageOperations.hxx:39
Definition: DBaseLineOperations.hpp:187
Definition: DBaseLineOperations.hpp:46