<?xml version="1.0" ?>
<!DOCTYPE extension SYSTEM "extension.dtd">
<extension name="opencv" version="0.0.1">
  <summary>PHP OpenCV</summary>

  <maintainer>
    <user>making</user>
    <name>Toshiaki Maki</name>
    <email>makingx [at] gmail [dot] com</email>
    <role>lead</role>
  </maintainer>

  <release>
    <version>0.0.1</version>
    <date>2008-01-03</date>
    <state>alpha</state>
    <notes>
      First version.
    </notes>
  </release>

  <deps language="c" platform="all">
    <with defaults="/usr:/usr/local:$HOME/usr" testfile="include/opencv/cv.h">
      <header name="opencv/cv.h" />
      <header name="opencv/highgui.h" />
      <lib name="cv" platform="all" />
      <lib name="cvaux" platform="all" />
      <lib name="highgui" platform="all" />
      <lib name="cxcore" platform="all" />
      <lib name="ml" platform="all" />
    </with>
  </deps>

  <constant name="IPL_DEPTH_8U"/>
  <constant name="IPL_DEPTH_8S"/>
  <constant name="IPL_DEPTH_16U"/>
  <constant name="IPL_DEPTH_16S"/>
  <constant name="IPL_DEPTH_32S"/>
  <constant name="IPL_DEPTH_32F"/>
  <constant name="IPL_DEPTH_64F"/>
  <constant name="CV_LOAD_IMAGE_UNCHANGED"/>
  <constant name="CV_LOAD_IMAGE_GRAYSCALE"/>
  <constant name="CV_LOAD_IMAGE_COLOR"/>
  <constant name="CV_LOAD_IMAGE_ANYCOLOR"/>
  <constant name="CV_LOAD_IMAGE_ANYDEPTH"/>
  <constant name="CV_BGR2HSV"/>
  <constant name="CV_HSV2RGB"/>
  <constant name="CV_BGR2GRAY"/>
  <constant name="CV_GRAY2BGR"/>
  <constant name="CV_BGR2BGRA"/>
  <constant name="CV_BGRA2BGR"/>
  <constant name="CV_BGR2XYZ"/>
  <constant name="CV_BGR2YCrCb"/>
  <constant name="CV_BGR2Lab"/>
  <constant name="CV_BLUR_NO_SCALE"/>
  <constant name="CV_BLUR"/>
  <constant name="CV_GAUSSIAN"/>
  <constant name="CV_MEDIAN"/>
  <constant name="CV_BILATERAL"/>
  <constant name="CV_THRESH_BINARY"/>
  <constant name="CV_THRESH_BINARY_INV"/>
  <constant name="CV_THRESH_TRUNC"/>
  <constant name="CV_THRESH_TOZERO"/>
  <constant name="CV_THRESH_TOZERO_INV"/>

  <code position="top">
    <![CDATA[
    int bytes_per_pixel(const IplImage* image) {
      return((((image)->depth & 255) / 8 ) *(image)->nChannels);
    }
    ]]>
  </code>

  <resource name="IplImage" payload="IplImage" alloc="no">
    <destruct>
      <![CDATA[
     cvReleaseImage(&resource);
    ]]>
    </destruct>
  </resource>

  <function name="cvCreateImage">
    <proto>resource IplImage cvCreateImage(int width, int height[, int depths[, int channels]])</proto>
    <code>
      <![CDATA[
     if (!(return_res = cvCreateImage(cvSize(width, height), depths, channels))) RETURN_FALSE;
    ]]>
    </code>
  </function>

  <function name="cvLoadImage">
    <proto>resource IplImage cvLoadImage(string filename[, int flags])</proto>
    <code>
      <![CDATA[
     if (!(return_res = cvLoadImage(filename, flags))) RETURN_FALSE;
    ]]>
    </code>
  </function>

  <function name="cvCloneImage">
    <proto>resource IplImage cvCloneImage(resource IplImage image)</proto>
    <code>
      <![CDATA[
     if (!(return_res = cvCloneImage(res_image))) RETURN_FALSE;
    ]]>
    </code>
  </function>

  <function name="cvSaveImage">
    <proto>int cvSaveImage(string filename, resource IplImage image)</proto>
    <code>
      <![CDATA[
    RETURN_LONG(cvSaveImage(filename, res_image));
    ]]>
    </code>
  </function>

  <function name="cvSmooth">
    <proto>void cvSmooth(resource IplImage src, resource IplImage dst, int smooth_type[, int param1[, int param2[, float param3[, float param4]]]])</proto>
    <code>
    <![CDATA[
    cvSmooth(res_src, res_dst, smooth_type, param1, param2, param3, param4);
    ]]>
    </code>
  </function>

  <function name="cvCvtColor">
    <proto>void cvCvtColor(resource IplImage src, resource IplImage dst, int code)</proto>
    <code>
    <![CDATA[
    cvCvtColor(res_src, res_dst, code);
    ]]>
    </code>
  </function>

  <function name="cvThreshold">
    <proto>void cvThreshold(resource IplImage src, resource IplImage dst, float threshold, float max_value, int threshold_type )</proto>
    <code>
    <![CDATA[
    cvThreshold(res_src, res_dst, threshold, max_value, threshold_type);
    ]]>
    </code>
  </function>

  <function name="cvSobel">
    <proto>void cvSobel(resource IplImage src, resource IplImage dst, int xorder, int yorder, int aperture_size)</proto>
    <code>
    <![CDATA[
    cvSobel(res_src, res_dst, xorder, yorder, aperture_size);
    ]]>
    </code>
  </function>

  <function name="cvLaplace">
    <proto>void cvLaplace(resource IplImage src, resource IplImage dst, int aperture_size)</proto>
    <code>
    <![CDATA[
    cvLaplace(res_src, res_dst, aperture_size);
    ]]>
    </code>
  </function>

  <function name="cvCanny">
    <proto>void cvCanny(resource IplImage image, resource IplImage edges, float threshold1, float threshold2, int aperture_size)</proto>
    <code>
    <![CDATA[
    cvCanny(res_image, res_edges, threshold1, threshold2, aperture_size);
    ]]>
    </code>
  </function>

  <function name="cvConvertScale">
    <proto>void cvConvertScale(resource IplImage src, resource IplImage dst, float scale, float shift)</proto>
    <code>
    <![CDATA[
    cvConvertScale(res_src, res_dst, scale, shift);
    ]]>
    </code>
  </function>

  <function name="cvConvertScaleAbs">
    <proto>void cvConvertScaleAbs(resource IplImage src, resource IplImage dst, float scale, float shift)</proto>
    <code>
    <![CDATA[
    cvConvertScaleAbs(res_src, res_dst, scale, shift);
    ]]>
    </code>
  </function>

  <function name="cvGetSize">
    <proto>array cvGetSize(resource IplImage image)</proto>
    <code>
      <![CDATA[
   array_init(return_value);
   add_assoc_long(return_value, "width", res_image->width);
   add_assoc_long(return_value, "height", res_image->height);
   add_assoc_long(return_value, "depth", res_image->depth);
   add_assoc_long(return_value, "channels", res_image->nChannels);
   ]]>
    </code>
  </function>

  <function name="cvGetWidth">
    <proto>int cvGetWidth(resource IplImage image)</proto>
    <code>
      RETURN_LONG(res_image->width);
    </code>
  </function>

  <function name="cvGetHeight">
    <proto>int cvGetHeight(resource IplImage image)</proto>
    <code>
      RETURN_LONG(res_image->height);
    </code>
  </function>

  <function name="cvGetDepth">
    <proto>int cvGetDepth(resource IplImage image)</proto>
    <code>
      RETURN_LONG(res_image->depth);
    </code>
  </function>

  <function name="cvGetChannels">
    <proto>int cvGetChannels(resource IplImage image)</proto>
    <code>
      RETURN_LONG(res_image->nChannels);
    </code>
  </function>

  <function name="cvGetData">
    <proto>array cvGetData(resource IplImage image)</proto>
    <code>
    <![CDATA[
    int step, x, y, c;

    array_init(return_value);

    for (y = 0; y < res_image->height; y++) {
      for (x = 0; x < res_image->width; x++) {
        for (c = 0; c < res_image->nChannels; c++) {
          add_next_index_long(return_value, ((uchar *)(res_image->imageData + res_image->widthStep * y))[x * res_image->nChannels + c]);
        }
      }
    }
    ]]>
    </code>
  </function>

  <function name="cvSetData">
    <proto>void cvSetData(resource IplImage image, array arr)</proto>
    <code>
    <![CDATA[
    int i = 0, x, y, c, length = zend_hash_num_elements(arr_hash);
    uchar adata[length];
    zval **entry;

    if (length != res_image->width * res_image->height * res_image->nChannels) php_error(E_ERROR, "different size error!");

    zend_hash_internal_pointer_reset(arr_hash);

    while( zend_hash_get_current_data(arr_hash, (void **) &entry ) == SUCCESS){ 
      convert_to_long_ex(entry);
      adata[i] = Z_LVAL_PP(entry);
      zend_hash_move_forward(arr_hash);
      i++;
    }

    i = 0;
    for (y = 0; y < res_image->height; y++) {
      for (x = 0; x < res_image->width; x++) {
        for (c = 0; c < res_image->nChannels; c++) {
          ((uchar *)(res_image->imageData + res_image->widthStep * y))[x * res_image->nChannels + c] = adata[i++];
        }
      }
    }
    ]]>
    </code>
  </function>

  <function name="cvReleaseImage">
    <proto>void cvReleaseImage(resource IplImage image)</proto>
    <code>FREE_RESOURCE(image);</code>
  </function>
</extension>
