| 853 | |
| 854 | |
| 855 | static void |
| 856 | icvFetchContourEx_32s( int* ptr, |
| 857 | int step, |
| 858 | CvPoint pt, |
| 859 | CvSeq* contour, |
| 860 | int _method, |
| 861 | CvRect* _rect ) |
| 862 | { |
| 863 | int deltas[16]; |
| 864 | CvSeqWriter writer; |
| 865 | int *i0 = ptr, *i1, *i3, *i4; |
| 866 | CvRect rect; |
| 867 | int prev_s = -1, s, s_end; |
| 868 | int method = _method - 1; |
| 869 | const int right_flag = INT_MIN; |
| 870 | const int new_flag = (int)((unsigned)INT_MIN >> 1); |
| 871 | const int value_mask = ~(right_flag | new_flag); |
| 872 | const int ccomp_val = *i0 & value_mask; |
| 873 | const int nbd0 = ccomp_val | new_flag; |
| 874 | const int nbd1 = nbd0 | right_flag; |
| 875 | |
| 876 | assert( (unsigned) _method <= CV_CHAIN_APPROX_SIMPLE ); |
| 877 | |
| 878 | /* initialize local state */ |
| 879 | CV_INIT_3X3_DELTAS( deltas, step, 1 ); |
| 880 | memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] )); |
| 881 | |
| 882 | /* initialize writer */ |
| 883 | cvStartAppendToSeq( contour, &writer ); |
| 884 | |
| 885 | if( method < 0 ) |
| 886 | ((CvChain *)contour)->origin = pt; |
| 887 | |
| 888 | rect.x = rect.width = pt.x; |
| 889 | rect.y = rect.height = pt.y; |
| 890 | |
| 891 | s_end = s = CV_IS_SEQ_HOLE( contour ) ? 0 : 4; |
| 892 | |
| 893 | do |
| 894 | { |
| 895 | s = (s - 1) & 7; |
| 896 | i1 = i0 + deltas[s]; |
| 897 | if( (*i1 & value_mask) == ccomp_val ) |
| 898 | break; |
| 899 | } |
| 900 | while( s != s_end ); |
| 901 | |
| 902 | if( s == s_end ) /* single pixel domain */ |
| 903 | { |
| 904 | *i0 = nbd1; |
| 905 | if( method >= 0 ) |
| 906 | { |
| 907 | CV_WRITE_SEQ_ELEM( pt, writer ); |
| 908 | } |
| 909 | } |
| 910 | else |
| 911 | { |
| 912 | i3 = i0; |
no test coverage detected