;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; LUSH Lisp Universal Shell
;;;   Copyright (C) 2002 Leon Bottou, Yann Le Cun, AT&T Corp, NECI.
;;; Includes parts of TL3:
;;;   Copyright (C) 1987-1999 Leon Bottou and Neuristique.
;;; Includes selected parts of SN3.2:
;;;   Copyright (C) 1991-2001 AT&T Corp.
;;;
;;; Includes information derived from the GSL (Gnu Scientific Library)
;;;   header files which are copyrighted and distributed under the GPL
;;;   by their respective authors.
;;;
;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2 of the License, or
;;; (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program; if not, write to the Free Software
;;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(libload "opencv/cv-config")



#? *** aux_macro_func

;; dummy function that adds OpenCV C header files in C file
(eval `(de dummy_aux_macro_func () ,cv-cpheader-cmd ()))

#? * (dummy_aux_macro_func)
#? * (cv_get_seq_eltype <seq>)
#? * (cv_get_seq_kind <seq>)
#? * (cv_get_seq_type <seq>)
#? * (cv_get_seq_subtype <seq>)
#? * (cv_is_seq_index <seq>)
#? * (cv_is_seq_curve <seq>)
#? * (cv_is_seq_closed <seq>)
#? * (cv_is_seq_convex <seq>)
#? * (cv_is_seq_hole <seq>)
#? * (cv_is_seq_simple <seq>)
#? * (cv_is_seq_point_set <seq>)
#? * (cv_is_seq_point_subset <seq>)
#? * (cv_is_seq_polyline <seq>)
#? * (cv_is_seq_polygon <seq>)
#? * (cv_is_seq_chain <seq>)
#? * (cv_is_seq_contour <seq>)
#? * (cv_is_seq_chain_contour <seq>)
#? * (cv_is_seq_polygon_tree <seq>)
#? * (cv_is_graph <seq>)
#? * (cv_is_graph_oriented <seq>)
#? * (cv_is_subdiv2d <seq>)
#? * (cv_is_graph_vertex_visited <vtx>)
#? * (cv_is_graph_edge_visited <edge>)
#? * (cv_get_seq_elem <elemsize> <seq> <index>)
#? * (cv_write_seq_elem <elem> <elemsize> <writer>)
#? * (cv_next_seq_elem <elemsize> <reader>)
#? * (cv_prev_seq_elem <elemsize> <reader>)
#? * (cv_read_seq_elem <elem> <elemsize> <reader>)
#? * (cv_rev_read_seq_elem <elem> <elemsize> <reader>)
#? * (cv_read_chain_point <pt> <reader>)
#? * (cv_current_point <reader> <point>)
#? * (cv_prev_point <reader> <point>)
#? * (cv_read_edge <pt1> <pt2> <reader>)
#? * (cv_is_set_elem_exists <ptr>)
#? * (cv_remove_set_elem <set> <index> <elem>)
#? * (cv_next_graph_edge <edge> <vertex>)
#? * (cvgetgraphvtx <graph> <idx>)
#? * (cvgraphvtxidx <graph> <vtx>)
#? * (cvgraphedgeidx <graph> <edge>)
#? * (cv_arr_cn <flags>)
#? * (cv_arr_depth <flags>)
#? * (cv_arr_type <flags>)
#? * (cv_arr_fmt <flags>)
#? * (cv_is_arr_cont <flags>)
#? * (cv_is_arr <arr>)
#? * (cv_is_image <arr>)
#? * (cv_is_mask_arr <arr>)
#? * (cv_are_types_eq <arr1> <arr2>)
#? * (cv_are_cns_eq <arr1> <arr2>)
#? * (cv_are_depths_eq <arr1> <arr2>)
#? * (cv_are_sizes_eq <arr1> <arr2>)
#? * (cv_is_arr_const <arr>)
#? * (cv_rgb <r> <g> <b>)
#? * (cvmatmul <srca> <srcb> <dst>)
#? * (cv_next_line_point <iterator>)
#? * (cvconvert <src> <dst>)
#? * (cv_subdiv2d_next_edge <edge>)
#? * (cv_count_obs <roi> <win> <delta> <numobs>)

;; ********************************************************


;;****************************************************************************************
;;          1.     checking Sequence type

(defvar cv-seq-testfunc-names 
  (list "CV_SEQ_ELTYPE"
        "CV_SEQ_KIND"
        "CV_IS_SEQ_INDEX"
        "CV_IS_SEQ_CLOSED"
        "CV_IS_SEQ_CONVEX"
        "CV_IS_SEQ_HOLE"
        "CV_IS_SEQ_SIMPLE"
        "CV_IS_SEQ_POINT_SET"
        "CV_IS_SEQ_POINT_SUBSET"
        "CV_IS_SEQ_POLYLINE"
        "CV_IS_SEQ_POLYGON"
        "CV_IS_SEQ_CHAIN"
        "CV_IS_SEQ_CONTOUR"
        "CV_IS_SEQ_CHAIN_CONTOUR"
        "CV_IS_SEQ_POLYGON_TREE"
        "CV_IS_GRAPH"
        "CV_IS_GRAPH_ORIENTED"
        "CV_IS_SUBDIV2D"
        ))

(each ((name cv-seq-testfunc-names))
  (eval
   `(de ,(named name) (seq)
      ((-gptr- "CvSeq *") seq)
      (int (cinline ,(sprintf "%s(%%s)" name) seq)) ) ))


;;****************************************************************************************
;;          2.     accessing  Sequence elements

(de CV_GET_SEQ_ELEM (elemsize seq index)
    ((-int-) elemsize)
    ((-gptr- "CvSeq *") seq)
    ((-int-) index)
    (let ((s (gptr ())))
      #{ 
      assert( sizeof($seq->first[0]) == sizeof(CvSeqBlock) && $seq->elem_size == $elemsize) ;
      
      if($seq->first && (unsigned)$index < (unsigned)($seq->first->count) )
           $s = (void *) $seq->first->data + $index * $elemsize ;
      else 
           $s = (void *) cvGetSeqElem( (CvSeq*)$seq, $index); 
      #}
      s))

;; /* macro that adds element to sequence */
;; Jie's comments: again, elemsize is added as one of the parameter to eliminate the sizeof operator
(de CV_WRITE_SEQ_ELEM (elem elemsize writer)
    ((-gptr-) elem)
    ((-int-) elemsize)
    ((-gptr- "CvSeqWriter *") writer)
    #{ 
     assert( $writer->seq->elem_size == $elemsize ); 
     if( $writer->ptr >= $writer->block_max )          
     {                                                 
         cvCreateSeqBlock( $writer);                   
     }                                                 
     assert( $writer->ptr <= $writer->block_max - $elemsize);
     memcpy($writer->ptr, $elem, $elemsize );        
     $writer->ptr += $elemsize;                     
     #}
    ())

;; /* move reader position forward */
(de CV_NEXT_SEQ_ELEM (elemsize reader)
    ((-int-) elemsize)
    ((-gptr- "CvSeqReader *") reader)
    #{ 
    if( ( $reader->ptr += $elemsize ) >= $reader->block_max ) 
               cvChangeSeqBlock( $reader, 1 );   #}
    ())

;; /* move reader position backward */
(de CV_PREV_SEQ_ELEM (elemsize reader)
    ((-int-) elemsize)
    ((-gptr- "CvSeqReader *") reader)
    #{
    if( ($reader->ptr -=  $elemsize) < $reader->block_min ) 
         cvChangeSeqBlock( $reader, -1 );    #}
    ())

;; /* read element and move read position forward */
(de CV_READ_SEQ_ELEM (elem elemsize reader)
    ((-gptr-) elem)
    ((-int-) elemsize)
    ((-gptr- "CvSeqReader *") reader)
    #{  
    assert( $reader->seq->elem_size == $elemsize );          
    memcpy( $elem, ($reader)->ptr, $elemsize);  

    if( ( $reader->ptr += $elemsize ) >= $reader->block_max ) 
          cvChangeSeqBlock( $reader, 1 );             #}
    ())

;; /* read element and move read position backward */
(de CV_REV_READ_SEQ_ELEM ( elem elemsize reader)
    ((-str-) elem)
    ((-int-) elemsize)
    ((-gptr- "CvSeqReader *") reader)
    #{ 
    assert( $reader->seq->elem_size == $elemsize );            
    memcpy($elem, $reader->ptr, $elemsize );               

    if( ($reader->ptr -=  $elemsize) < $reader->block_min ) 
         cvChangeSeqBlock( $reader, -1 );           #}
    ())


(de CV_READ_CHAIN_POINT ( pt reader)
    ((-gptr- "CvPoint *") pt)
    ((-gptr- "CvChainPtReader *") reader)
    #{ 
     memcpy($pt,&($reader->pt),sizeof(CvPoint));                                    
     if( $reader->ptr )                                                  
     { 
         // CV_READ_SEQ_ELEM
	 assert( $reader->seq->elem_size == sizeof(char)  );          
	 $reader->code = *(($reader)->ptr) ;
	 
	 // CV_NEXT_SEQ_ELEM
	 if( ( $reader->ptr += sizeof(char) ) >= $reader->block_max ) 
               cvChangeSeqBlock( (CvSeqReader *)$reader, 1 );

	 //  update 
         assert( ($reader->code & ~7) == 0 );                            
         ($reader->pt).x += ($reader)->deltas[(int)$reader->code][0];             
         ($reader->pt).y += ($reader)->deltas[(int)$reader->code][1];             
     }  #}
    ())


(de CV_CURRENT_POINT (reader point)
    ((-gptr- "CvSeqReader *") reader)
    ((-gptr- "CvPoint *") point)
    #{ memcpy($point, $reader->ptr, sizeof(CvPoint)); #}
    ())
    

(de CV_PREV_POINT ( reader point )
    ((-gptr- "CvSeqReader *") reader)
    ((-gptr- "CvPoint *") point)
    #{ memcpy($point, $reader->prev_elem, sizeof(CvPoint)); #}
    ())


(de CV_READ_EDGE (pt1 pt2 reader)
    ((-gptr- "CvPoint *") pt1 pt2)
    ((-gptr- "CvSeqReader *") reader)
    #{ 
    CV_READ_EDGE( (*$pt1), (*$pt2), (*$reader) ) ;  #}
    ())



;;*******************************************************
;;           3.  Set 
(de CV_IS_SET_ELEM_EXISTS (ptr)
    ((-gptr-) ptr)
    (int #{  CV_IS_SET_ELEM_EXISTS( $ptr) #}))


;; (de CV_REMOVE_SET_ELEM (set index elem)
;;     ((-gptr- "CvSet *") set)
;;     ((-int-) index)
;;     ((-gptr-) elem )
;;     #{  CV_REMOVE_SET_ELEM( $set, $index, $elem); #}
;;     ())



;;*******************************************************
;;          4.  Graph 

;; /* returns next graph edge for given vertex */
(de CV_NEXT_GRAPH_EDGE (edge vertex)
    ((-gptr- "CvGraphEdge *") edge)
    ((-gptr- "CvGraphVtx *") vertex)
    (let ((s (gptr ())))
      #{ $s = CV_NEXT_GRAPH_EDGE( $edge, $vertex ); #}
      s))


;;  /*F///////////////////////////////////////////////////////////////////////////////////////
;;  //    Name:    cvGetGraphVtx
;;  //    Purpose: finds graph vertex by its index
;;  //    Context:
;;  //    Parameters:
;;  //         graph - graph
;;  //         idx - vertex index
;;  //    Returns:
;;  //      pointer to vertex
;;  //F*/

(de cvGetGraphVtx(graph idx)
    ((-gptr- "CvGraph *") graph)
    ((-int-) idx)
    (let ((s (gptr ())))
      #{ $s = (CvGraphVtx *) cvGetSetElem ((CvSet *)$graph, $idx);   #}
      s))


;;  /*F///////////////////////////////////////////////////////////////////////////////////////
;;  //    Name:    cvGraphVtxIdx
;;  //    Purpose: calculates index of the graph vertex
;;  //    Context:
;;  //    Parameters:
;;  //         graph - graph
;;  //         vtx - pointer to vertex
;;  //    Returns:
;;  //      vertex index
;;  //F*/
(de cvGraphVtxIdx(graph vtx)
    ((-gptr- "CvGraph *") graph)
    ((-gptr- "CvGraphVtx *") vtx)
    (let ((s 0))
      ((-int-) s)
      #{ $s = cvSeqElemIdx((CvSeq *)$graph,  $vtx, 0); #}
      s))


;;  /*F///////////////////////////////////////////////////////////////////////////////////////
;;  //    Name:    cvGraphEdgeIdx
;;  //    Purpose: calculates index of the graph edge
;;  //    Context:
;;  //    Parameters:
;;  //         graph - graph
;;  //         edge - pointer to graph edge
;;  //    Returns:
;;  //      edge index
;;  //F*/
(de cvGraphEdgeIdx(graph edge)
    ((-gptr- "CvGraph *") graph)
    ((-gptr- "CvGraphEdge *") edge)
    (let ((s 0))
      ((-int-) s)
      #{ $s = cvSeqElemIdx((CvSeq *)($graph->edges), $edge, 0); #}
      s))



;;************************************************************
;;           5. matrix

;; (de CV_ARR_CN (flags)
;;     ((-int-) flags)
;;     (int #{ ((( $flags) & CV_ARR_CN_MASK) >> 3) + 1 #} ))

;; (de CV_ARR_DEPTH (flags)
;;     ((-int-) flags)
;;     (int #{ (( $flags) & CV_ARR_DEPTH_MASK) #}))

;; (de CV_ARR_TYPE (flags)
;;     ((-int-) flags)
;;     (int #{ (( $flags) & CV_ARR_TYPE_MASK)  #}))

;; (de CV_ARR_FMT (flags)
;;     ((-int-) flags)
;;     (int #{ (( $flags) & CV_ARR_FMT_MASK)  #}))

;; (de CV_IS_ARR_CONT (flags)
;;     ((-int-) flags)
;;     (int #{ (( $flags) & CV_ARR_CONT_FLAG)  #}))

(de CV_IS_MATND (arr)
    ((-gptr- "CvArr *") arr)
    (int #{ ( CV_IS_MATND( $arr) ) #}))

(de CV_IS_MATND_HDR (arr)
    ((-gptr- "CvArr *") arr)
    (int #{ ( CV_IS_MATND_HDR( $arr) ) #}))

(de CV_IS_SPARSE_MAT (arr)
    ((-gptr- "CvArr *") arr)
    (int #{ ( CV_IS_SPARSE_MAT( $arr) ) #}))

(de CV_IS_SPARSE_MAT_HDR (arr)
    ((-gptr- "CvArr *") arr)
    (int #{ ( CV_IS_SPARSE_MAT_HDR( $arr) ) #}))

(de CV_IS_IMAGE (arr)
    ((-gptr- "CvArr *") arr)
    (int  #{ CV_IS_IMAGE($arr) #} ))

;; (de CV_IS_MASK_ARR (arr)
;;     ((-gptr- "CvMat *") arr)
;;     (int #{ CV_IS_MASK_ARR($arr) #}))

;; (de CV_ARE_TYPES_EQ (arr1 arr2)
;;     ((-gptr- "CvMat *") arr1 arr2)
;;     (int #{ CV_ARE_TYPES_EQ($arr1, $arr2) #} ))

;; (de CV_ARE_CNS_EQ (arr1 arr2)
;;     ((-gptr- "CvMat *") arr1 arr2)
;;     (int  #{ CV_ARE_CNS_EQ($arr1, $arr2) #}))
    
;; (de CV_ARE_DEPTHS_EQ (arr1 arr2)
;;     ((-gptr- "CvMat *") arr1 arr2)
;;     (int  #{ CV_ARE_DEPTHS_EQ($arr1, $arr2) #}))

;; (de CV_ARE_SIZES_EQ (arr1 arr2)
;;     ((-gptr- "CvMat *") arr1 arr2)
;;     (int  #{  ( ( $arr1)->rows == ( $arr2)->rows && ( $arr1)->cols == ( $arr2)->cols )  #}))

;; (de CV_IS_ARR_CONST (arr)
;;     ((-gptr- "CvMat *") arr)
;;     (int  #{   ( ( ($arr)->rows | ( $arr)->cols) == 1 )  #})) 

;; #define CV_RGB( r, g, b )  (int)((uchar)(b) + ((uchar)(g) << 8) + ((uchar)(r) << 16))
(de CV_RGB ( r g b)
    ((-ubyte-) r g b)
    (int #{ ((uchar)($b) + ((uchar)($g) << 8) + ((uchar)($r) << 16)) #} ))

;; (de cvMatMul (srca srcb dst)
;;     ((-gptr- "const CvArr *") srca srcb)
;;     ((-gptr- "CvArr *") dst)
;;     #{ cvMatMul($srca, $srcb, $dst); #}
;;     ())
  
;;**********************************************************************************
;;          6. utilities

;;  /* Move to the next line point */
(de CV_NEXT_LINE_POINT (iterator)
    ((-gptr- "CvLineIterator *") iterator)
    #{ { int mask = $iterator->err < 0 ? -1 : 0;
    $iterator->err += $iterator->minus_delta + (($iterator->plus_delta) & mask);
    $iterator->ptr += $iterator->minus_step  + (($iterator->plus_step)  & mask); 
    }#}
    ())

(de cvConvert (src dst)
    ((-gptr- "const CvArr *") src)
    ((-gptr- "CvArr *") dst)
    #{  cvConvertScale($src, $dst, 1, 0); #}
    ())

;;************************************************************************************
;;          7. subdiv2d

(de CV_SUBDIV2D_NEXT_EDGE (edge)
    ((-int-) edge)
    (int #{  CV_SUBDIV2D_NEXT_EDGE( (long)$edge) #}))
    

;; ********************************************************

(dhc-make-all ()
  (cons 'dummy_aux_macro_func
  (append (mapcar named cv-seq-testfunc-names)
  `(cv_get_seq_elem
    cv_write_seq_elem
    cv_next_seq_elem
    cv_prev_seq_elem
    cv_read_seq_elem
    cv_rev_read_seq_elem
    cv_read_chain_point
    cv_current_point
    cv_prev_point
    cv_read_edge
    cv_is_set_elem_exists
    ;cv_remove_set_elem
    cv_next_graph_edge
    cvgetgraphvtx
    cvgraphvtxidx
    cvgraphedgeidx
    ;cv_arr_cn
    ;cv_arr_depth
    ;cv_arr_type
    ;cv_arr_fmt
    ;cv_is_arr_cont
    ;cv_is_arr
    cv-is-matnd
    cv-is-matnd-hdr
    cv-is-image
    cv-is-sparse-mat
    cv-is-sparse-mat-hdr
    ;cv_is_mask_arr
    ;cv_are_types_eq
    ;cv_are_cns_eq
    ;cv_are_depths_eq
    ;cv_are_sizes_eq
    ;cv_is_arr_const
    cv_rgb
    ;cvmatmul
    cv_next_line_point
    cvconvert
    cv_subdiv2d_next_edge
    )))
  () )
