|
|
|
@ -455,235 +455,6 @@ CV_INLINE CvSize cvGetMatSize( const CvMat* mat ) |
|
|
|
|
#define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n)) |
|
|
|
|
#define CV_FLT_TO_FIX(x,n) cvRound((x)*(1<<(n))) |
|
|
|
|
|
|
|
|
|
/****************************************************************************************\
|
|
|
|
|
|
|
|
|
|
Generic implementation of QuickSort algorithm. |
|
|
|
|
---------------------------------------------- |
|
|
|
|
Using this macro user can declare customized sort function that can be much faster |
|
|
|
|
than built-in qsort function because of lower overhead on elements |
|
|
|
|
comparison and exchange. The macro takes less_than (or LT) argument - a macro or function |
|
|
|
|
that takes 2 arguments returns non-zero if the first argument should be before the second |
|
|
|
|
one in the sorted sequence and zero otherwise. |
|
|
|
|
|
|
|
|
|
Example: |
|
|
|
|
|
|
|
|
|
Suppose that the task is to sort points by ascending of y coordinates and if |
|
|
|
|
y's are equal x's should ascend. |
|
|
|
|
|
|
|
|
|
The code is: |
|
|
|
|
------------------------------------------------------------------------------ |
|
|
|
|
#define cmp_pts( pt1, pt2 ) \ |
|
|
|
|
((pt1).y < (pt2).y || ((pt1).y < (pt2).y && (pt1).x < (pt2).x)) |
|
|
|
|
|
|
|
|
|
[static] CV_IMPLEMENT_QSORT( icvSortPoints, CvPoint, cmp_pts ) |
|
|
|
|
------------------------------------------------------------------------------ |
|
|
|
|
|
|
|
|
|
After that the function "void icvSortPoints( CvPoint* array, size_t total, int aux );" |
|
|
|
|
is available to user. |
|
|
|
|
|
|
|
|
|
aux is an additional parameter, which can be used when comparing elements. |
|
|
|
|
The current implementation was derived from *BSD system qsort(): |
|
|
|
|
|
|
|
|
|
* Copyright (c) 1992, 1993 |
|
|
|
|
* The Regents of the University of California. All rights reserved. |
|
|
|
|
* |
|
|
|
|
* Redistribution and use in source and binary forms, with or without |
|
|
|
|
* modification, are permitted provided that the following conditions |
|
|
|
|
* are met: |
|
|
|
|
* 1. Redistributions of source code must retain the above copyright |
|
|
|
|
* notice, this list of conditions and the following disclaimer. |
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
|
|
|
* notice, this list of conditions and the following disclaimer in the |
|
|
|
|
* documentation and/or other materials provided with the distribution. |
|
|
|
|
* 3. All advertising materials mentioning features or use of this software |
|
|
|
|
* must display the following acknowledgement: |
|
|
|
|
* This product includes software developed by the University of |
|
|
|
|
* California, Berkeley and its contributors. |
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors |
|
|
|
|
* may be used to endorse or promote products derived from this software |
|
|
|
|
* without specific prior written permission. |
|
|
|
|
* |
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
|
|
|
* SUCH DAMAGE. |
|
|
|
|
|
|
|
|
|
\****************************************************************************************/ |
|
|
|
|
|
|
|
|
|
#define CV_IMPLEMENT_QSORT_EX( func_name, T, LT, user_data_type ) \ |
|
|
|
|
void func_name( T *array, size_t total, user_data_type aux ) \
|
|
|
|
|
{ \
|
|
|
|
|
int isort_thresh = 7; \
|
|
|
|
|
T t; \
|
|
|
|
|
int sp = 0; \
|
|
|
|
|
\
|
|
|
|
|
struct \ |
|
|
|
|
{ \
|
|
|
|
|
T *lb; \
|
|
|
|
|
T *ub; \
|
|
|
|
|
} \
|
|
|
|
|
stack[48]; \
|
|
|
|
|
\
|
|
|
|
|
aux = aux; \
|
|
|
|
|
\
|
|
|
|
|
if( total <= 1 ) \
|
|
|
|
|
return; \
|
|
|
|
|
\
|
|
|
|
|
stack[0].lb = array; \
|
|
|
|
|
stack[0].ub = array + (total - 1); \
|
|
|
|
|
\
|
|
|
|
|
while( sp >= 0 ) \
|
|
|
|
|
{ \
|
|
|
|
|
T* left = stack[sp].lb; \
|
|
|
|
|
T* right = stack[sp--].ub; \
|
|
|
|
|
\
|
|
|
|
|
for(;;) \
|
|
|
|
|
{ \
|
|
|
|
|
int i, n = (int)(right - left) + 1, m; \
|
|
|
|
|
T* ptr; \
|
|
|
|
|
T* ptr2; \
|
|
|
|
|
\
|
|
|
|
|
if( n <= isort_thresh ) \
|
|
|
|
|
{ \
|
|
|
|
|
insert_sort: \
|
|
|
|
|
for( ptr = left + 1; ptr <= right; ptr++ ) \
|
|
|
|
|
{ \
|
|
|
|
|
for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--) \
|
|
|
|
|
CV_SWAP( ptr2[0], ptr2[-1], t ); \
|
|
|
|
|
} \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
else \
|
|
|
|
|
{ \
|
|
|
|
|
T* left0; \
|
|
|
|
|
T* left1; \
|
|
|
|
|
T* right0; \
|
|
|
|
|
T* right1; \
|
|
|
|
|
T* pivot; \
|
|
|
|
|
T* a; \
|
|
|
|
|
T* b; \
|
|
|
|
|
T* c; \
|
|
|
|
|
int swap_cnt = 0; \
|
|
|
|
|
\
|
|
|
|
|
left0 = left; \
|
|
|
|
|
right0 = right; \
|
|
|
|
|
pivot = left + (n/2); \
|
|
|
|
|
\
|
|
|
|
|
if( n > 40 ) \
|
|
|
|
|
{ \
|
|
|
|
|
int d = n / 8; \
|
|
|
|
|
a = left, b = left + d, c = left + 2*d; \
|
|
|
|
|
left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \
|
|
|
|
|
: (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \
|
|
|
|
|
\
|
|
|
|
|
a = pivot - d, b = pivot, c = pivot + d; \
|
|
|
|
|
pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \
|
|
|
|
|
: (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \
|
|
|
|
|
\
|
|
|
|
|
a = right - 2*d, b = right - d, c = right; \
|
|
|
|
|
right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \
|
|
|
|
|
: (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
a = left, b = pivot, c = right; \
|
|
|
|
|
pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a)) \
|
|
|
|
|
: (LT(*c, *b) ? b : (LT(*a, *c) ? a : c)); \
|
|
|
|
|
if( pivot != left0 ) \
|
|
|
|
|
{ \
|
|
|
|
|
CV_SWAP( *pivot, *left0, t ); \
|
|
|
|
|
pivot = left0; \
|
|
|
|
|
} \
|
|
|
|
|
left = left1 = left0 + 1; \
|
|
|
|
|
right = right1 = right0; \
|
|
|
|
|
\
|
|
|
|
|
for(;;) \
|
|
|
|
|
{ \
|
|
|
|
|
while( left <= right && !LT(*pivot, *left) ) \
|
|
|
|
|
{ \
|
|
|
|
|
if( !LT(*left, *pivot) ) \
|
|
|
|
|
{ \
|
|
|
|
|
if( left > left1 ) \
|
|
|
|
|
CV_SWAP( *left1, *left, t ); \
|
|
|
|
|
swap_cnt = 1; \
|
|
|
|
|
left1++; \
|
|
|
|
|
} \
|
|
|
|
|
left++; \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
while( left <= right && !LT(*right, *pivot) ) \
|
|
|
|
|
{ \
|
|
|
|
|
if( !LT(*pivot, *right) ) \
|
|
|
|
|
{ \
|
|
|
|
|
if( right < right1 ) \
|
|
|
|
|
CV_SWAP( *right1, *right, t ); \
|
|
|
|
|
swap_cnt = 1; \
|
|
|
|
|
right1--; \
|
|
|
|
|
} \
|
|
|
|
|
right--; \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
if( left > right ) \
|
|
|
|
|
break; \
|
|
|
|
|
CV_SWAP( *left, *right, t ); \
|
|
|
|
|
swap_cnt = 1; \
|
|
|
|
|
left++; \
|
|
|
|
|
right--; \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
if( swap_cnt == 0 ) \
|
|
|
|
|
{ \
|
|
|
|
|
left = left0, right = right0; \
|
|
|
|
|
goto insert_sort; \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
n = MIN( (int)(left1 - left0), (int)(left - left1) ); \
|
|
|
|
|
for( i = 0; i < n; i++ ) \
|
|
|
|
|
CV_SWAP( left0[i], left[i-n], t ); \
|
|
|
|
|
\
|
|
|
|
|
n = MIN( (int)(right0 - right1), (int)(right1 - right) ); \
|
|
|
|
|
for( i = 0; i < n; i++ ) \
|
|
|
|
|
CV_SWAP( left[i], right0[i-n+1], t ); \
|
|
|
|
|
n = (int)(left - left1); \
|
|
|
|
|
m = (int)(right1 - right); \
|
|
|
|
|
if( n > 1 ) \
|
|
|
|
|
{ \
|
|
|
|
|
if( m > 1 ) \
|
|
|
|
|
{ \
|
|
|
|
|
if( n > m ) \
|
|
|
|
|
{ \
|
|
|
|
|
stack[++sp].lb = left0; \
|
|
|
|
|
stack[sp].ub = left0 + n - 1; \
|
|
|
|
|
left = right0 - m + 1, right = right0; \
|
|
|
|
|
} \
|
|
|
|
|
else \
|
|
|
|
|
{ \
|
|
|
|
|
stack[++sp].lb = right0 - m + 1; \
|
|
|
|
|
stack[sp].ub = right0; \
|
|
|
|
|
left = left0, right = left0 + n - 1; \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
else \
|
|
|
|
|
left = left0, right = left0 + n - 1; \
|
|
|
|
|
} \
|
|
|
|
|
else if( m > 1 ) \
|
|
|
|
|
left = right0 - m + 1, right = right0; \
|
|
|
|
|
else \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define CV_IMPLEMENT_QSORT( func_name, T, cmp ) \ |
|
|
|
|
CV_IMPLEMENT_QSORT_EX( func_name, T, cmp, int ) |
|
|
|
|
|
|
|
|
|
/****************************************************************************************\
|
|
|
|
|
* Structures and macros for integration with IPP * |
|
|
|
|
\****************************************************************************************/ |
|
|
|
|