| 667 | |
| 668 | |
| 669 | static void |
| 670 | icvFetchContourEx( schar* ptr, |
| 671 | int step, |
| 672 | CvPoint pt, |
| 673 | CvSeq* contour, |
| 674 | int _method, |
| 675 | int nbd, |
| 676 | CvRect* _rect ) |
| 677 | { |
| 678 | int deltas[16]; |
| 679 | CvSeqWriter writer; |
| 680 | schar *i0 = ptr, *i1, *i3, *i4; |
| 681 | CvRect rect; |
| 682 | int prev_s = -1, s, s_end; |
| 683 | int method = _method - 1; |
| 684 | |
| 685 | assert( (unsigned) _method <= CV_CHAIN_APPROX_SIMPLE ); |
| 686 | assert( 1 < nbd && nbd < 128 ); |
| 687 | |
| 688 | /* initialize local state */ |
| 689 | CV_INIT_3X3_DELTAS( deltas, step, 1 ); |
| 690 | memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] )); |
| 691 | |
| 692 | /* initialize writer */ |
| 693 | cvStartAppendToSeq( contour, &writer ); |
| 694 | |
| 695 | if( method < 0 ) |
| 696 | ((CvChain *)contour)->origin = pt; |
| 697 | |
| 698 | rect.x = rect.width = pt.x; |
| 699 | rect.y = rect.height = pt.y; |
| 700 | |
| 701 | s_end = s = CV_IS_SEQ_HOLE( contour ) ? 0 : 4; |
| 702 | |
| 703 | do |
| 704 | { |
| 705 | s = (s - 1) & 7; |
| 706 | i1 = i0 + deltas[s]; |
| 707 | if( *i1 != 0 ) |
| 708 | break; |
| 709 | } |
| 710 | while( s != s_end ); |
| 711 | |
| 712 | if( s == s_end ) /* single pixel domain */ |
| 713 | { |
| 714 | *i0 = (schar) (nbd | 0x80); |
| 715 | if( method >= 0 ) |
| 716 | { |
| 717 | CV_WRITE_SEQ_ELEM( pt, writer ); |
| 718 | } |
| 719 | } |
| 720 | else |
| 721 | { |
| 722 | i3 = i0; |
| 723 | |
| 724 | prev_s = s ^ 4; |
| 725 | |
| 726 | /* follow border */ |
no test coverage detected