vigra - vigra/algorithm.hxx Source File

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

algorithm.hxx |

1 /************************************************************************/
2 /* */
3 /* Copyright 2010-2011 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35
36 #ifndef VIGRA_ALGORITHM_HXX
37 #define VIGRA_ALGORITHM_HXX
38
39 #include "sized_int.hxx"
40 #include "numerictraits.hxx"
41 #include "inspector_passes.hxx"
42 #include <algorithm>
43 #include <functional>
44 #include <iterator>
45
46 namespace vigra {
47
48 /** \addtogroup MathFunctions
49 */
50 //@{
51 /** \brief Find the minimum element in a sequence.
52
53 The function returns the iterator referring to the minimum element.
54 This is identical to the function <tt>std::min_element()</tt>.
55
56 <b>Required Interface:</b>
57
58 \code
59 Iterator is a standard forward iterator.
60
61 bool f = *first < NumericTraits<typename std::iterator_traits<Iterator>::value_type>::max();
62 \endcode
63
64 <b>\#include</b> <vigra/algorithm.hxx><br>
65 Namespace: vigra
66 */
67 template <class Iterator>
68 Iterator argMin(Iterator first, Iterator last)
69 {
70 if(first == last)
71 return last;
72 Iterator best = first;
73 for(++first; first != last; ++first)
74 if(*first < *best)
75 best = first;
76 return best;
77 }
78
79 /** \brief Find the maximum element in a sequence.
80
81 The function returns the iterator referring to the maximum element.
82 This is identical to the function <tt>std::max_element()</tt>.
83
84 <b>Required Interface:</b>
85
86 \code
87 Iterator is a standard forward iterator.
88
89 bool f = NumericTraits<typename std::iterator_traits<Iterator>::value_type>::min() < *first;
90 \endcode
91
92 <b>\#include</b> <vigra/algorithm.hxx><br>
93 Namespace: vigra
94 */
95 template <class Iterator>
96 Iterator argMax(Iterator first, Iterator last)
97 {
98 if(first == last)
99 return last;
100 Iterator best = first;
101 for(++first; first != last; ++first)
102 if(*best < *first)
103 best = first;
104 return best;
105 }
106
107 /** \brief Find the minimum element in a sequence conforming to a condition.
108
109 The function returns the iterator referring to the minimum element,
110 where only elements conforming to the condition (i.e. where
111 <tt>condition(*iterator)</tt> evaluates to <tt>true</tt>) are considered.
112 If no element conforms to the condition, or the sequence is empty,
113 the end iterator \a last is returned.
114
115 <b>Required Interface:</b>
116
117 \code
118 Iterator is a standard forward iterator.
119
120 bool c = condition(*first);
121
122 bool f = *first < NumericTraits<typename std::iterator_traits<Iterator>::value_type>::max();
123 \endcode
124
125 <b>\#include</b> <vigra/algorithm.hxx><br>
126 Namespace: vigra
127 */
128 template <class Iterator, class UnaryFunctor>
129 Iterator argMinIf(Iterator first, Iterator last, UnaryFunctor condition)
130 {
131 for(; first != last; ++first)
132 if(condition(*first))
133 break;
134 if(first == last)
135 return last;
136 Iterator best = first;
137 for(++first; first != last; ++first)
138 if(condition(*first) && *first < *best)
139 best = first;
140 return best;
141 }
142
143 /** \brief Find the maximum element in a sequence conforming to a condition.
144
145 The function returns the iterator referring to the maximum element,
146 where only elements conforming to the condition (i.e. where
147 <tt>condition(*iterator)</tt> evaluates to <tt>true</tt>) are considered.
148 If no element conforms to the condition, or the sequence is empty,
149 the end iterator \a last is returned.
150
151 <b>Required Interface:</b>
152
153 \code
154 Iterator is a standard forward iterator.
155
156 bool c = condition(*first);
157
158 bool f = NumericTraits<typename std::iterator_traits<Iterator>::value_type>::min() < *first;
159 \endcode
160
161 <b>\#include</b> <vigra/algorithm.hxx><br>
162 Namespace: vigra
163 */
164 template <class Iterator, class UnaryFunctor>
165 Iterator argMaxIf(Iterator first, Iterator last, UnaryFunctor condition)
166 {
167 for(; first != last; ++first)
168 if(condition(*first))
169 break;
170 if(first == last)
171 return last;
172 Iterator best = first;
173 for(++first; first != last; ++first)
174 if(condition(*first) && *best < *first)
175 best = first;
176 return best;
177 }
178
179 /** \brief Fill an array with a sequence of numbers.
180
181 The sequence starts at \a start and is incremented with \a step. Default start
182 and stepsize are 0 and 1 respectively. This is a generalization of function
183 <tt>std::iota()</tt> in C++11.
184
185 <b> Declaration:</b>
186
187 \code
188 namespace vigra {
189 template <class Iterator, class Value>
190 void linearSequence(Iterator first, Iterator last,
191 Value const & start = 0, Value const & step = 1);
192 }
193 \endcode
194
195 <b>Required Interface:</b>
196
197 \code
198 Iterator is a standard forward iterator.
199
200 *first = start;
201 start += step;
202 \endcode
203
204 <b>\#include</b> <vigra/algorithm.hxx><br>
205 Namespace: vigra
206 */
207 template <class Iterator, class Value>
208 void linearSequence(Iterator first, Iterator last, Value start, Value step)
209 {
210 for(; first != last; ++first, start += step)
211 *first = start;
212 }
213
214 template <class Iterator, class Value>
215 void linearSequence(Iterator first, Iterator last, Value start)
216 {
217 linearSequence(first, last, start, NumericTraits<Value>::one());
218 }
219
220 template <class Iterator>
221 void linearSequence(Iterator first, Iterator last)
222 {
223 typedef typename std::iterator_traits<Iterator>::value_type Value;
224
225 linearSequence(first, last, NumericTraits<Value>::zero());
226 }
227
228 /** \brief Call an analyzing functor at every element of a sequence.
229
230 This function can be used to collect statistics of the sequence
231 <tt>[first, last)</tt> defined by these two input interators.
232 The results must be stored in the functor, which serves as a return
233 value.
234
235 <b> Declarations:</b>
236
237 \code
238 namespace vigra {
239 template <class InputIterator, class Functor>
240 void
241 inspectSequence(InputIterator first, InputIterator last, Functor & f);
242 }
243 \endcode
244
245 <b> Usage:</b>
246
247 <b>\#include</b> <vigra/algorithm.hxx><br>
248 Namespace: vigra
249
250 \code
251 std::vector array(100);
252
253 // init functor
254 vigra::FindMinMax<int> minmax;
255
256 vigra::inspectSequence(array.begin(), array.end(), minmax);
257
258 cout << "Min: " << minmax.min << " Max: " << minmax.max;
259
260 \endcode
261
262 */
263 doxygen_overloaded_function(template <...> void inspectSequence)
264
265 namespace detail {
266
267 template <class InputIterator>
268 struct inspectSequence_binder
269 {
270 InputIterator first;
271 InputIterator last;
272 inspectSequence_binder(InputIterator first_, InputIterator last_)
273 : first(first_), last(last_) {}
274 template <class Functor>
275 void operator()(Functor & f)
276 {
277 for (InputIterator i = first; i != last; ++i)
278 f(*i);
279 }
280 };
281
282 } // namespace detail
283
284 template <class InputIterator, class Functor>
285 inline void
286 inspectSequence(InputIterator first, InputIterator last, Functor & f)
287 {
288 detail::inspectSequence_binder<InputIterator> g(first, last);
289 detail::extra_passes_select(g, f);
290 }
291
292 namespace detail {
293
294 template <class ArrayLike, class Compare>
295 struct IndexCompare
296 {
297 ArrayLike i_;
298 Compare c_;
299
300 IndexCompare(ArrayLike i, Compare c)
301 : i_(i),
302 c_(c)
303 {}
304
305 template <class Index>
306 bool operator()(Index const & l, Index const & r) const
307 {
308 return c_(i_[l], i_[r]);
309 }
310 };
311
312 } // namespace detail
313
314 /** \brief Create a compare functor for indirect sort.
315
316 Indirect sorting refers to the situation where you have an array holding
317 data and another array holding indices referencing the first array,
318 and you want to sort the index array according to some property of
319 the data array without changing the data array itself. The factory
320 function <tt>makeIndexComparator()</tt> creates a sorting predicate
321 for this task, given a sorting predicate for the data array.
322
323 \see vigra::indexSort(), vigra::applyPermutation()
324
325 <b>Usage:</b>
326
327 <b>\#include</b> <vigra/algorithm.hxx><br>
328 Namespace: vigra
329
330 \code
331 const std:vector<double> data(...); // data is immutable
332
333 std::vector<int> index(data.size());
334 std::iota(index.begin(), index.end());
335
336 // sort the indices such that data[index[k]] is an ascending sequence in k
337 std::sort(index.begin(), index.end(), makeIndexComparator(data));
338 \endcode
339
340 <b>Declarations:</b>
341
342 \code
343 namespace vigra {
344 // compare using std::less
345 template <class ArrayLike>
346 auto makeIndexComparator(ArrayLike a);
347
348 // compare using functor Compare
349 template <class ArrayLike, class Compare>
350 auto makeIndexComparator(ArrayLike a, Compare c);
351 }
352 \endcode
353 */
354 template <class ArrayLike, class Compare>
355 inline detail::IndexCompare<ArrayLike, Compare>
356 makeIndexComparator(ArrayLike a, Compare c)
357 {
358 return detail::IndexCompare<ArrayLike, Compare>(a, c);
359 }
360
361 template <class ArrayLike>
362 inline detail::IndexCompare<ArrayLike, std::less<typename ArrayLike::value_type> >
363 makeIndexComparator(ArrayLike a)
364 {
365 typedef std::less<typename ArrayLike::value_type> Compare;
366 return detail::IndexCompare<ArrayLike, Compare>(a, Compare());
367 }
368
369 /** \brief Return the index permutation that would sort the input array.
370
371 To actually sort an array according to the ordering thus determined, use
372 \ref applyPermutation().
373
374 <b>Usage:</b>
375
376 <b>\#include</b> <vigra/algorithm.hxx><br>
377 Namespace: vigra
378
379 \code
380 const std:vector<double> data(...); // data is immutable
381
382 std::vector<int> index(data.size());
383
384 // arrange indices such that data[index[k]] is an ascending sequence in k
385 indexSort(data.begin(), data.end(), index.begin());
386 \endcode
387
388 <b> Declarations:</b>
389
390 \code
391 namespace vigra {
392 // compare using std::less
393 template <class Iterator, class IndexIterator>
394 void indexSort(Iterator first, Iterator last, IndexIterator index_first);
395
396 // compare using functor Compare
397 template <class Iterator, class IndexIterator, class Compare>
398 void indexSort(Iterator first, Iterator last, IndexIterator index_first, Compare compare);
399 }
400 \endcode
401
402 <b>Required Interface:</b>
403
404 \code
405 Iterator and IndexIterators are random access iterators.
406
407 bool res = compare(first[*index_first], first[*index_first]);
408 \endcode
409
410 <b>\#include</b> <vigra/algorithm.hxx><br>
411 Namespace: vigra
412 */
413 template <class Iterator, class IndexIterator, class Compare>
414 void indexSort(Iterator first, Iterator last, IndexIterator index_first, Compare c)
415 {
416 int size = last - first;
417 linearSequence(index_first, index_first+size);
418 std::sort(index_first, index_first+size, makeIndexComparator(first, c));
419 }
420
421 template <class Iterator, class IndexIterator>
422 void indexSort(Iterator first, Iterator last, IndexIterator index_first)
423 {
424 typedef typename std::iterator_traits<Iterator>::value_type Value;
425 indexSort(first, last, index_first, std::less<Value>());
426 }
427
428 /** \brief Sort an array according to the given index permutation.
429
430 The iterators \a in and \a out may not refer to the same array, as
431 this would overwrite the input prematurely.
432
433 <b> Declaration:</b>
434
435 \code
436 namespace vigra {
437 template <class IndexIterator, class InIterator, class OutIterator>
438 void applyPermutation(IndexIterator index_first, IndexIterator index_last,
439 InIterator in, OutIterator out);
440 }
441 \endcode
442
443 <b>Required Interface:</b>
444
445 \code
446 OutIterator and IndexIterators are forward iterators.
447 InIterator is a random access iterator.
448
449 *out = in[*index_first];
450 \endcode
451
452 <b>\#include</b> <vigra/algorithm.hxx><br>
453 Namespace: vigra
454 */
455 template <class IndexIterator, class InIterator, class OutIterator>
456 void applyPermutation(IndexIterator index_first, IndexIterator index_last,
457 InIterator in, OutIterator out)
458 {
459 for(; index_first != index_last; ++index_first, ++out)
460 *out = in[*index_first];
461 }
462
463
464 /** \brief Compute the inverse of a given permutation.
465
466 This is just another name for \ref indexSort(), referring to
467 another semantics.
468
469 <b> Declaration:</b>
470
471 \code
472 namespace vigra {
473 template <class InIterator, class OutIterator>
474 void inversePermutation(InIterator first, InIterator last,
475 OutIterator out);
476 }
477 \endcode
478
479 <b>Required Interface:</b>
480
481 \code
482 InIterator and OutIterator are random access iterators.
483
484 *out = in[*index_first];
485 \endcode
486
487 <b>\#include</b> <vigra/algorithm.hxx><br>
488 Namespace: vigra
489 */
490 template <class InIterator, class OutIterator>
491 void inversePermutation(InIterator first, InIterator last,
492 OutIterator out)
493 {
494 indexSort(first, last, out);
495 }
496
497 namespace detail {
498
499 static bool isLittleEndian()
500 {
501 static const UIntBiggest testint = 0x01;
502 return ((UInt8 *)&testint)[0] == 0x01;
503 }
504
505 template <class INT>
506 struct ChecksumImpl
507 {
508 static UInt32 table0[256];
509 static UInt32 table1[256];
510 static UInt32 table2[256];
511 static UInt32 table3[256];
512
513 template <class InIterator>
514 static UInt32 exec(InIterator i, unsigned int size, UInt32 crc = 0xFFFFFFFF);
515 };
516
517 template <class INT>
518 UInt32 ChecksumImpl<INT>::table0[256] = {
519 0x0U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x76dc419U, 0x706af48fU,
520 0xe963a535U, 0x9e6495a3U, 0xedb8832U, 0x79dcb8a4U, 0xe0d5e91eU, 0x97d2d988U,
521 0x9b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U,
522 0xf3b97148U, 0x84be41deU, 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U,
523 0x136c9856U, 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
524 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, 0xa2677172U,
525 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, 0x35b5a8faU, 0x42b2986cU,
526 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U,
527 0x26d930acU, 0x51de003aU, 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U,
528 0xcfba9599U, 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
529 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, 0x1db7106U,
530 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x6b6b51fU, 0x9fbfe4a5U, 0xe8b8d433U,
531 0x7807c9a2U, 0xf00f934U, 0x9609a88eU, 0xe10e9818U, 0x7f6a0dbbU, 0x86d3d2dU,
532 0x91646c97U, 0xe6635c01U, 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU,
533 0x6c0695edU, 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
534 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, 0xfbd44c65U,
535 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, 0x4adfa541U, 0x3dd895d7U,
536 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, 0x346ed9fcU, 0xad678846U, 0xda60b8d0U,
537 0x44042d73U, 0x33031de5U, 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU,
538 0xbe0b1010U, 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
539 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, 0x2eb40d81U,
540 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, 0x3b6e20cU, 0x74b1d29aU,
541 0xead54739U, 0x9dd277afU, 0x4db2615U, 0x73dc1683U, 0xe3630b12U, 0x94643b84U,
542 0xd6d6a3eU, 0x7a6a5aa8U, 0xe40ecf0bU, 0x9309ff9dU, 0xa00ae27U, 0x7d079eb1U,
543 0xf00f9344U, 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
544 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, 0x67dd4accU,
545 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, 0xd6d6a3e8U, 0xa1d1937eU,
546 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU,
547 0xd80d2bdaU, 0xaf0a1b4cU, 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U,
548 0x316e8eefU, 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
549 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, 0xb2bd0b28U,
550 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, 0x2cd99e8bU, 0x5bdeae1dU,
551 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, 0x26d930aU, 0x9c0906a9U, 0xeb0e363fU,
552 0x72076785U, 0x5005713U, 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0xcb61b38U,
553 0x92d28e9bU, 0xe5d5be0dU, 0x7cdcefb7U, 0xbdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
554 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, 0x18b74777U,
555 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, 0x8f659effU, 0xf862ae69U,
556 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U,
557 0xa7672661U, 0xd06016f7U, 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU,
558 0x40df0b66U, 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
559 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, 0xcdd70693U,
560 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, 0x5d681b02U, 0x2a6f2b94U,
561 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU };
562
563 template <class INT>
564 UInt32 ChecksumImpl<INT>::table1[256] = {
565 0x00000000U, 0x191b3141U, 0x32366282U, 0x2b2d53c3U, 0x646cc504U,
566 0x7d77f445U, 0x565aa786U, 0x4f4196c7U, 0xc8d98a08U, 0xd1c2bb49U,
567 0xfaefe88aU, 0xe3f4d9cbU, 0xacb54f0cU, 0xb5ae7e4dU, 0x9e832d8eU,
568 0x87981ccfU, 0x4ac21251U, 0x53d92310U, 0x78f470d3U, 0x61ef4192U,
569 0x2eaed755U, 0x37b5e614U, 0x1c98b5d7U, 0x05838496U, 0x821b9859U,
570 0x9b00a918U, 0xb02dfadbU, 0xa936cb9aU, 0xe6775d5dU, 0xff6c6c1cU,
571 0xd4413fdfU, 0xcd5a0e9eU, 0x958424a2U, 0x8c9f15e3U, 0xa7b24620U,
572 0xbea97761U, 0xf1e8e1a6U, 0xe8f3d0e7U, 0xc3de8324U, 0xdac5b265U,
573 0x5d5daeaaU, 0x44469febU, 0x6f6bcc28U, 0x7670fd69U, 0x39316baeU,
574 0x202a5aefU, 0x0b07092cU, 0x121c386dU, 0xdf4636f3U, 0xc65d07b2U,
575 0xed705471U, 0xf46b6530U, 0xbb2af3f7U, 0xa231c2b6U, 0x891c9175U,
576 0x9007a034U, 0x179fbcfbU, 0x0e848dbaU, 0x25a9de79U, 0x3cb2ef38U,
577 0x73f379ffU, 0x6ae848beU, 0x41c51b7dU, 0x58de2a3cU, 0xf0794f05U,
578 0xe9627e44U, 0xc24f2d87U, 0xdb541cc6U, 0x94158a01U, 0x8d0ebb40U,
579 0xa623e883U, 0xbf38d9c2U, 0x38a0c50dU, 0x21bbf44cU, 0x0a96a78fU,
580 0x138d96ceU, 0x5ccc0009U, 0x45d73148U, 0x6efa628bU, 0x77e153caU,
581 0xbabb5d54U, 0xa3a06c15U, 0x888d3fd6U, 0x91960e97U, 0xded79850U,
582 0xc7cca911U, 0xece1fad2U, 0xf5facb93U, 0x7262d75cU, 0x6b79e61dU,
583 0x4054b5deU, 0x594f849fU, 0x160e1258U, 0x0f152319U, 0x243870daU,
584 0x3d23419bU, 0x65fd6ba7U, 0x7ce65ae6U, 0x57cb0925U, 0x4ed03864U,
585 0x0191aea3U, 0x188a9fe2U, 0x33a7cc21U, 0x2abcfd60U, 0xad24e1afU,
586 0xb43fd0eeU, 0x9f12832dU, 0x8609b26cU, 0xc94824abU, 0xd05315eaU,
587 0xfb7e4629U, 0xe2657768U, 0x2f3f79f6U, 0x362448b7U, 0x1d091b74U,
588 0x04122a35U, 0x4b53bcf2U, 0x52488db3U, 0x7965de70U, 0x607eef31U,
589 0xe7e6f3feU, 0xfefdc2bfU, 0xd5d0917cU, 0xcccba03dU, 0x838a36faU,
590 0x9a9107bbU, 0xb1bc5478U, 0xa8a76539U, 0x3b83984bU, 0x2298a90aU,
591 0x09b5fac9U, 0x10aecb88U, 0x5fef5d4fU, 0x46f46c0eU, 0x6dd93fcdU,
592 0x74c20e8cU, 0xf35a1243U, 0xea412302U, 0xc16c70c1U, 0xd8774180U,
593 0x9736d747U, 0x8e2de606U, 0xa500b5c5U, 0xbc1b8484U, 0x71418a1aU,
594 0x685abb5bU, 0x4377e898U, 0x5a6cd9d9U, 0x152d4f1eU, 0x0c367e5fU,
595 0x271b2d9cU, 0x3e001cddU, 0xb9980012U, 0xa0833153U, 0x8bae6290U,
596 0x92b553d1U, 0xddf4c516U, 0xc4eff457U, 0xefc2a794U, 0xf6d996d5U,
597 0xae07bce9U, 0xb71c8da8U, 0x9c31de6bU, 0x852aef2aU, 0xca6b79edU,
598 0xd37048acU, 0xf85d1b6fU, 0xe1462a2eU, 0x66de36e1U, 0x7fc507a0U,
599 0x54e85463U, 0x4df36522U, 0x02b2f3e5U, 0x1ba9c2a4U, 0x30849167U,
600 0x299fa026U, 0xe4c5aeb8U, 0xfdde9ff9U, 0xd6f3cc3aU, 0xcfe8fd7bU,
601 0x80a96bbcU, 0x99b25afdU, 0xb29f093eU, 0xab84387fU, 0x2c1c24b0U,
602 0x350715f1U, 0x1e2a4632U, 0x07317773U, 0x4870e1b4U, 0x516bd0f5U,
603 0x7a468336U, 0x635db277U, 0xcbfad74eU, 0xd2e1e60fU, 0xf9ccb5ccU,
604 0xe0d7848dU, 0xaf96124aU, 0xb68d230bU, 0x9da070c8U, 0x84bb4189U,
605 0x03235d46U, 0x1a386c07U, 0x31153fc4U, 0x280e0e85U, 0x674f9842U,
606 0x7e54a903U, 0x5579fac0U, 0x4c62cb81U, 0x8138c51fU, 0x9823f45eU,
607 0xb30ea79dU, 0xaa1596dcU, 0xe554001bU, 0xfc4f315aU, 0xd7626299U,
608 0xce7953d8U, 0x49e14f17U, 0x50fa7e56U, 0x7bd72d95U, 0x62cc1cd4U,
609 0x2d8d8a13U, 0x3496bb52U, 0x1fbbe891U, 0x06a0d9d0U, 0x5e7ef3ecU,
610 0x4765c2adU, 0x6c48916eU, 0x7553a02fU, 0x3a1236e8U, 0x230907a9U,
611 0x0824546aU, 0x113f652bU, 0x96a779e4U, 0x8fbc48a5U, 0xa4911b66U,
612 0xbd8a2a27U, 0xf2cbbce0U, 0xebd08da1U, 0xc0fdde62U, 0xd9e6ef23U,
613 0x14bce1bdU, 0x0da7d0fcU, 0x268a833fU, 0x3f91b27eU, 0x70d024b9U,
614 0x69cb15f8U, 0x42e6463bU, 0x5bfd777aU, 0xdc656bb5U, 0xc57e5af4U,
615 0xee530937U, 0xf7483876U, 0xb809aeb1U, 0xa1129ff0U, 0x8a3fcc33U,
616 0x9324fd72U };
617
618 template <class INT>
619 UInt32 ChecksumImpl<INT>::table2[256] = {
620 0x00000000U, 0x01c26a37U, 0x0384d46eU, 0x0246be59U, 0x0709a8dcU,
621 0x06cbc2ebU, 0x048d7cb2U, 0x054f1685U, 0x0e1351b8U, 0x0fd13b8fU,
622 0x0d9785d6U, 0x0c55efe1U, 0x091af964U, 0x08d89353U, 0x0a9e2d0aU,
623 0x0b5c473dU, 0x1c26a370U, 0x1de4c947U, 0x1fa2771eU, 0x1e601d29U,
624 0x1b2f0bacU, 0x1aed619bU, 0x18abdfc2U, 0x1969b5f5U, 0x1235f2c8U,
625 0x13f798ffU, 0x11b126a6U, 0x10734c91U, 0x153c5a14U, 0x14fe3023U,
626 0x16b88e7aU, 0x177ae44dU, 0x384d46e0U, 0x398f2cd7U, 0x3bc9928eU,
627 0x3a0bf8b9U, 0x3f44ee3cU, 0x3e86840bU, 0x3cc03a52U, 0x3d025065U,
628 0x365e1758U, 0x379c7d6fU, 0x35dac336U, 0x3418a901U, 0x3157bf84U,
629 0x3095d5b3U, 0x32d36beaU, 0x331101ddU, 0x246be590U, 0x25a98fa7U,
630 0x27ef31feU, 0x262d5bc9U, 0x23624d4cU, 0x22a0277bU, 0x20e69922U,
631 0x2124f315U, 0x2a78b428U, 0x2bbade1fU, 0x29fc6046U, 0x283e0a71U,
632 0x2d711cf4U, 0x2cb376c3U, 0x2ef5c89aU, 0x2f37a2adU, 0x709a8dc0U,
633 0x7158e7f7U, 0x731e59aeU, 0x72dc3399U, 0x7793251cU, 0x76514f2bU,
634 0x7417f172U, 0x75d59b45U, 0x7e89dc78U, 0x7f4bb64fU, 0x7d0d0816U,
635 0x7ccf6221U, 0x798074a4U, 0x78421e93U, 0x7a04a0caU, 0x7bc6cafdU,
636 0x6cbc2eb0U, 0x6d7e4487U, 0x6f38fadeU, 0x6efa90e9U, 0x6bb5866cU,
637 0x6a77ec5bU, 0x68315202U, 0x69f33835U, 0x62af7f08U, 0x636d153fU,
638 0x612bab66U, 0x60e9c151U, 0x65a6d7d4U, 0x6464bde3U, 0x662203baU,
639 0x67e0698dU, 0x48d7cb20U, 0x4915a117U, 0x4b531f4eU, 0x4a917579U,
640 0x4fde63fcU, 0x4e1c09cbU, 0x4c5ab792U, 0x4d98dda5U, 0x46c49a98U,
641 0x4706f0afU, 0x45404ef6U, 0x448224c1U, 0x41cd3244U, 0x400f5873U,
642 0x4249e62aU, 0x438b8c1dU, 0x54f16850U, 0x55330267U, 0x5775bc3eU,
643 0x56b7d609U, 0x53f8c08cU, 0x523aaabbU, 0x507c14e2U, 0x51be7ed5U,
644 0x5ae239e8U, 0x5b2053dfU, 0x5966ed86U, 0x58a487b1U, 0x5deb9134U,
645 0x5c29fb03U, 0x5e6f455aU, 0x5fad2f6dU, 0xe1351b80U, 0xe0f771b7U,
646 0xe2b1cfeeU, 0xe373a5d9U, 0xe63cb35cU, 0xe7fed96bU, 0xe5b86732U,
647 0xe47a0d05U, 0xef264a38U, 0xeee4200fU, 0xeca29e56U, 0xed60f461U,
648 0xe82fe2e4U, 0xe9ed88d3U, 0xebab368aU, 0xea695cbdU, 0xfd13b8f0U,
649 0xfcd1d2c7U, 0xfe976c9eU, 0xff5506a9U, 0xfa1a102cU, 0xfbd87a1bU,
650 0xf99ec442U, 0xf85cae75U, 0xf300e948U, 0xf2c2837fU, 0xf0843d26U,
651 0xf1465711U, 0xf4094194U, 0xf5cb2ba3U, 0xf78d95faU, 0xf64fffcdU,
652 0xd9785d60U, 0xd8ba3757U, 0xdafc890eU, 0xdb3ee339U, 0xde71f5bcU,
653 0xdfb39f8bU, 0xddf521d2U, 0xdc374be5U, 0xd76b0cd8U, 0xd6a966efU,
654 0xd4efd8b6U, 0xd52db281U, 0xd062a404U, 0xd1a0ce33U, 0xd3e6706aU,
655 0xd2241a5dU, 0xc55efe10U, 0xc49c9427U, 0xc6da2a7eU, 0xc7184049U,
656 0xc25756ccU, 0xc3953cfbU, 0xc1d382a2U, 0xc011e895U, 0xcb4dafa8U,
657 0xca8fc59fU, 0xc8c97bc6U, 0xc90b11f1U, 0xcc440774U, 0xcd866d43U,
658 0xcfc0d31aU, 0xce02b92dU, 0x91af9640U, 0x906dfc77U, 0x922b422eU,
659 0x93e92819U, 0x96a63e9cU, 0x976454abU, 0x9522eaf2U, 0x94e080c5U,
660 0x9fbcc7f8U, 0x9e7eadcfU, 0x9c381396U, 0x9dfa79a1U, 0x98b56f24U,
661 0x99770513U, 0x9b31bb4aU, 0x9af3d17dU, 0x8d893530U, 0x8c4b5f07U,
662 0x8e0de15eU, 0x8fcf8b69U, 0x8a809decU, 0x8b42f7dbU, 0x89044982U,
663 0x88c623b5U, 0x839a6488U, 0x82580ebfU, 0x801eb0e6U, 0x81dcdad1U,
664 0x8493cc54U, 0x8551a663U, 0x8717183aU, 0x86d5720dU, 0xa9e2d0a0U,
665 0xa820ba97U, 0xaa6604ceU, 0xaba46ef9U, 0xaeeb787cU, 0xaf29124bU,
666 0xad6fac12U, 0xacadc625U, 0xa7f18118U, 0xa633eb2fU, 0xa4755576U,
667 0xa5b73f41U, 0xa0f829c4U, 0xa13a43f3U, 0xa37cfdaaU, 0xa2be979dU,
668 0xb5c473d0U, 0xb40619e7U, 0xb640a7beU, 0xb782cd89U, 0xb2cddb0cU,
669 0xb30fb13bU, 0xb1490f62U, 0xb08b6555U, 0xbbd72268U, 0xba15485fU,
670 0xb853f606U, 0xb9919c31U, 0xbcde8ab4U, 0xbd1ce083U, 0xbf5a5edaU,
671 0xbe9834edU };
672
673 template <class INT>
674 UInt32 ChecksumImpl<INT>::table3[256] = {
675 0x00000000U, 0xb8bc6765U, 0xaa09c88bU, 0x12b5afeeU, 0x8f629757U,
676 0x37def032U, 0x256b5fdcU, 0x9dd738b9U, 0xc5b428efU, 0x7d084f8aU,
677 0x6fbde064U, 0xd7018701U, 0x4ad6bfb8U, 0xf26ad8ddU, 0xe0df7733U,
678 0x58631056U, 0x5019579fU, 0xe8a530faU, 0xfa109f14U, 0x42acf871U,
679 0xdf7bc0c8U, 0x67c7a7adU, 0x75720843U, 0xcdce6f26U, 0x95ad7f70U,
680 0x2d111815U, 0x3fa4b7fbU, 0x8718d09eU, 0x1acfe827U, 0xa2738f42U,
681 0xb0c620acU, 0x087a47c9U, 0xa032af3eU, 0x188ec85bU, 0x0a3b67b5U,
682 0xb28700d0U, 0x2f503869U, 0x97ec5f0cU, 0x8559f0e2U, 0x3de59787U,
683 0x658687d1U, 0xdd3ae0b4U, 0xcf8f4f5aU, 0x7733283fU, 0xeae41086U,
684 0x525877e3U, 0x40edd80dU, 0xf851bf68U, 0xf02bf8a1U, 0x48979fc4U,
685 0x5a22302aU, 0xe29e574fU, 0x7f496ff6U, 0xc7f50893U, 0xd540a77dU,
686 0x6dfcc018U, 0x359fd04eU, 0x8d23b72bU, 0x9f9618c5U, 0x272a7fa0U,
687 0xbafd4719U, 0x0241207cU, 0x10f48f92U, 0xa848e8f7U, 0x9b14583dU,
688 0x23a83f58U, 0x311d90b6U, 0x89a1f7d3U, 0x1476cf6aU, 0xaccaa80fU,
689 0xbe7f07e1U, 0x06c36084U, 0x5ea070d2U, 0xe61c17b7U, 0xf4a9b859U,
690 0x4c15df3cU, 0xd1c2e785U, 0x697e80e0U, 0x7bcb2f0eU, 0xc377486bU,
691 0xcb0d0fa2U, 0x73b168c7U, 0x6104c729U, 0xd9b8a04cU, 0x446f98f5U,
692 0xfcd3ff90U, 0xee66507eU, 0x56da371bU, 0x0eb9274dU, 0xb6054028U,
693 0xa4b0efc6U, 0x1c0c88a3U, 0x81dbb01aU, 0x3967d77fU, 0x2bd27891U,
694 0x936e1ff4U, 0x3b26f703U, 0x839a9066U, 0x912f3f88U, 0x299358edU,
695 0xb4446054U, 0x0cf80731U, 0x1e4da8dfU, 0xa6f1cfbaU, 0xfe92dfecU,
696 0x462eb889U, 0x549b1767U, 0xec277002U, 0x71f048bbU, 0xc94c2fdeU,
697 0xdbf98030U, 0x6345e755U, 0x6b3fa09cU, 0xd383c7f9U, 0xc1366817U,
698 0x798a0f72U, 0xe45d37cbU, 0x5ce150aeU, 0x4e54ff40U, 0xf6e89825U,
699 0xae8b8873U, 0x1637ef16U, 0x048240f8U, 0xbc3e279dU, 0x21e91f24U,
700 0x99557841U, 0x8be0d7afU, 0x335cb0caU, 0xed59b63bU, 0x55e5d15eU,
701 0x47507eb0U, 0xffec19d5U, 0x623b216cU, 0xda874609U, 0xc832e9e7U,
702 0x708e8e82U, 0x28ed9ed4U, 0x9051f9b1U, 0x82e4565fU, 0x3a58313aU,
703 0xa78f0983U, 0x1f336ee6U, 0x0d86c108U, 0xb53aa66dU, 0xbd40e1a4U,
704 0x05fc86c1U, 0x1749292fU, 0xaff54e4aU, 0x322276f3U, 0x8a9e1196U,
705 0x982bbe78U, 0x2097d91dU, 0x78f4c94bU, 0xc048ae2eU, 0xd2fd01c0U,
706 0x6a4166a5U, 0xf7965e1cU, 0x4f2a3979U, 0x5d9f9697U, 0xe523f1f2U,
707 0x4d6b1905U, 0xf5d77e60U, 0xe762d18eU, 0x5fdeb6ebU, 0xc2098e52U,
708 0x7ab5e937U, 0x680046d9U, 0xd0bc21bcU, 0x88df31eaU, 0x3063568fU,
709 0x22d6f961U, 0x9a6a9e04U, 0x07bda6bdU, 0xbf01c1d8U, 0xadb46e36U,
710 0x15080953U, 0x1d724e9aU, 0xa5ce29ffU, 0xb77b8611U, 0x0fc7e174U,
711 0x9210d9cdU, 0x2aacbea8U, 0x38191146U, 0x80a57623U, 0xd8c66675U,
712 0x607a0110U, 0x72cfaefeU, 0xca73c99bU, 0x57a4f122U, 0xef189647U,
713 0xfdad39a9U, 0x45115eccU, 0x764dee06U, 0xcef18963U, 0xdc44268dU,
714 0x64f841e8U, 0xf92f7951U, 0x41931e34U, 0x5326b1daU, 0xeb9ad6bfU,
715 0xb3f9c6e9U, 0x0b45a18cU, 0x19f00e62U, 0xa14c6907U, 0x3c9b51beU,
716 0x842736dbU, 0x96929935U, 0x2e2efe50U, 0x2654b999U, 0x9ee8defcU,
717 0x8c5d7112U, 0x34e11677U, 0xa9362eceU, 0x118a49abU, 0x033fe645U,
718 0xbb838120U, 0xe3e09176U, 0x5b5cf613U, 0x49e959fdU, 0xf1553e98U,
719 0x6c820621U, 0xd43e6144U, 0xc68bceaaU, 0x7e37a9cfU, 0xd67f4138U,
720 0x6ec3265dU, 0x7c7689b3U, 0xc4caeed6U, 0x591dd66fU, 0xe1a1b10aU,
721 0xf3141ee4U, 0x4ba87981U, 0x13cb69d7U, 0xab770eb2U, 0xb9c2a15cU,
722 0x017ec639U, 0x9ca9fe80U, 0x241599e5U, 0x36a0360bU, 0x8e1c516eU,
723 0x866616a7U, 0x3eda71c2U, 0x2c6fde2cU, 0x94d3b949U, 0x090481f0U,
724 0xb1b8e695U, 0xa30d497bU, 0x1bb12e1eU, 0x43d23e48U, 0xfb6e592dU,
725 0xe9dbf6c3U, 0x516791a6U, 0xccb0a91fU, 0x740cce7aU, 0x66b96194U,
726 0xde0506f1U };
727
728
729 template <class INT>
730 template <class InIterator>
731 UInt32 ChecksumImpl<INT>::exec(InIterator i, unsigned int size, UInt32 crc)
732 {
733 InIterator end = i + size;
734
735 if(isLittleEndian() && size > 3)
736 {
737 // take care of alignment
738 for(; (std::size_t)i % 4 != 0; ++i)
739 {
740 crc = (crc >> 8) ^ table0[(crc ^ *i) & 0xFF];
741 }
742 for(; i < end-3; i+=4)
743 {
744 crc ^= *((UInt32 *)i);
745 crc = table3[crc & 0xFF] ^
746 table2[(crc >> 8) & 0xFF] ^
747 table1[(crc >> 16) & 0xFF] ^
748 table0[crc >> 24];
749 }
750 }
751 for(; i < end; ++i)
752 {
753 crc = (crc >> 8) ^ table0[(crc ^ *i) & 0xFF];
754 }
755 return ~crc;
756 }
757
758 } // namespace detail
759
760 /** \brief Compute the CRC-32 checksum of a byte array.
761
762 Implementation note: This function is slower on big-endian machines
763 because the "4 bytes at a time" optimization is only implemented for
764 little-endian.
765 */
766 inline UInt32 checksum(const char * data, unsigned int size)
767 {
768 return detail::ChecksumImpl<UInt32>::exec(data, size);
769 }
770
771 /** Concatenate a byte array to an existing CRC-32 checksum.
772 */
773 inline UInt32 concatenateChecksum(UInt32 checksum, const char * data, unsigned int size)
774 {
775
776 return detail::ChecksumImpl<UInt32>::exec(data, size, ~checksum);
777 }
778
779 template <class T>
780 void updateMin(T & x, const T & y)
781 {
782 using std::min;
783 x = min(x, y);
784 }
785
786 template <class T>
787 void updateMax(T & x, const T & y)
788 {
789 using std::max;
790 x = max(x, y);
791 }
792
793
794 //@}
795
796 } // namespace vigra
797
798 #endif /* VIGRA_ALGORITHM_HXX */

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.10.0 (Thu Jan 8 2015)