Insert a sequence into the middle of another sequence: !!! TODO !!! Implement more efficient algorithm
| 1743 | // Insert a sequence into the middle of another sequence: |
| 1744 | // !!! TODO !!! Implement more efficient algorithm |
| 1745 | CV_IMPL void |
| 1746 | cvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr ) |
| 1747 | { |
| 1748 | CvSeqReader reader_to, reader_from; |
| 1749 | int i, elem_size, total, from_total; |
| 1750 | CvSeq from_header, *from = (CvSeq*)from_arr; |
| 1751 | CvSeqBlock block; |
| 1752 | |
| 1753 | if( !CV_IS_SEQ(seq) ) |
| 1754 | CV_Error( CV_StsBadArg, "Invalid destination sequence header" ); |
| 1755 | |
| 1756 | if( !CV_IS_SEQ(from)) |
| 1757 | { |
| 1758 | CvMat* mat = (CvMat*)from; |
| 1759 | if( !CV_IS_MAT(mat)) |
| 1760 | CV_Error( CV_StsBadArg, "Source is not a sequence nor matrix" ); |
| 1761 | |
| 1762 | if( !CV_IS_MAT_CONT(mat->type) || (mat->rows != 1 && mat->cols != 1) ) |
| 1763 | CV_Error( CV_StsBadArg, "The source array must be 1d coninuous vector" ); |
| 1764 | |
| 1765 | from = cvMakeSeqHeaderForArray( CV_SEQ_KIND_GENERIC, sizeof(from_header), |
| 1766 | CV_ELEM_SIZE(mat->type), |
| 1767 | mat->data.ptr, mat->cols + mat->rows - 1, |
| 1768 | &from_header, &block ); |
| 1769 | } |
| 1770 | |
| 1771 | if( seq->elem_size != from->elem_size ) |
| 1772 | CV_Error( CV_StsUnmatchedSizes, |
| 1773 | "Source and destination sequence element sizes are different." ); |
| 1774 | |
| 1775 | from_total = from->total; |
| 1776 | |
| 1777 | if( from_total == 0 ) |
| 1778 | return; |
| 1779 | |
| 1780 | total = seq->total; |
| 1781 | index += index < 0 ? total : 0; |
| 1782 | index -= index > total ? total : 0; |
| 1783 | |
| 1784 | if( (unsigned)index > (unsigned)total ) |
| 1785 | CV_Error( CV_StsOutOfRange, "" ); |
| 1786 | |
| 1787 | elem_size = seq->elem_size; |
| 1788 | |
| 1789 | if( index < (total >> 1) ) |
| 1790 | { |
| 1791 | cvSeqPushMulti( seq, 0, from_total, 1 ); |
| 1792 | |
| 1793 | cvStartReadSeq( seq, &reader_to ); |
| 1794 | cvStartReadSeq( seq, &reader_from ); |
| 1795 | cvSetSeqReaderPos( &reader_from, from_total ); |
| 1796 | |
| 1797 | for( i = 0; i < index; i++ ) |
| 1798 | { |
| 1799 | memcpy( reader_to.ptr, reader_from.ptr, elem_size ); |
| 1800 | CV_NEXT_SEQ_ELEM( elem_size, reader_to ); |
| 1801 | CV_NEXT_SEQ_ELEM( elem_size, reader_from ); |
| 1802 | } |
no test coverage detected