Add a binder for the ansel face driver, some cleanup while I was poking
authorMichael J. Rubinsky <mrubinsk@horde.org>
Mon, 31 May 2010 00:44:33 +0000 (20:44 -0400)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Mon, 31 May 2010 00:44:33 +0000 (20:44 -0400)
22 files changed:
ansel/faces/claim.php
ansel/faces/custom.php
ansel/faces/face.php
ansel/faces/gallery.php
ansel/faces/image.php
ansel/faces/img.php
ansel/faces/name.php
ansel/faces/report.php
ansel/faces/savecustom.php
ansel/faces/search/tabs.php
ansel/lib/Ajax/Imple/EditFaces.php
ansel/lib/Application.php
ansel/lib/Block/recent_faces.php
ansel/lib/Faces.php
ansel/lib/Faces/Base.php
ansel/lib/Faces/facedetect.php
ansel/lib/Faces/opencv.php [deleted file]
ansel/lib/Faces/user.php
ansel/lib/Injector/Binder/Faces.php [new file with mode: 0644]
ansel/lib/Widget/GalleryFaces.php
ansel/lib/Widget/ImageFaces.php
ansel/lib/Widget/OwnerFaces.php

index 5a0da90..35273d1 100644 (file)
@@ -13,7 +13,7 @@
 require_once dirname(__FILE__) . '/../lib/Application.php';
 Horde_Registry::appInit('ansel');
 
-$faces = Ansel_Faces::factory();
+$faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
 $face_id = Horde_Util::getFormData('face');
 try {
     $face = $faces->getFaceById($face_id);
index 8202497..09465ef 100644 (file)
@@ -45,7 +45,7 @@ $y2 = $conf['screen']['width'];
 $name = Horde_Util::getFormData('name');
 
 if ($face_id) {
-    $faces = Ansel_Faces::factory();
+    $faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
     try {
         $face = $faces->getFaceById($face_id, true);
         $x1 = $face['face_x1'];
index 1d664fe..f306408 100644 (file)
@@ -17,7 +17,7 @@
 require_once dirname(__FILE__) . '/../lib/Application.php';
 Horde_Registry::appInit('ansel');
 
-$faces = Ansel_Faces::factory();
+$faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
 $face_id = Horde_Util::getFormData('face');
 try {
     $face = $faces->getFaceById($face_id);
index b49625f..fe765b8 100644 (file)
@@ -41,7 +41,7 @@ $images = $gallery->getImages($page * $perpage, $perpage);
 $reloadimage = Horde_Themes::img('reload.png');
 $customimage = Horde_Themes::img('layout.png');
 $customurl = Horde_Util::addParameter(Horde::applicationUrl('faces/custom.php'), 'page', $page);
-$face = Ansel_Faces::factory();
+$face = $GLOBALS['injector']->getInstance('Ansel_Faces');
 $autogenerate = $face->canAutogenerate();
 
 $vars = Horde_Variables::getDefaultVariables();
index 2d6ad8e..11c8aae 100644 (file)
@@ -13,7 +13,7 @@
 require_once dirname(__FILE__) . '/../lib/Application.php';
 Horde_Registry::appInit('ansel');
 
-$faces = Ansel_Faces::factory();
+$faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
 
 $name = '';
 $autocreate = true;
index af68ad0..025fd9b 100644 (file)
@@ -14,7 +14,7 @@ require_once dirname(__FILE__) . '/../lib/Application.php';
 Horde_Registry::appInit('ansel');
 
 $face_id = Horde_Util::getFormData('face');
-$faces = Ansel_Faces::factory();
+$faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
 
 // Sendfile support. Lighttpd < 1.5 only understands the X-LIGHTTPD-send-file
 // header
index 5ba5606..e85f5f2 100644 (file)
@@ -23,5 +23,5 @@ if (!$gallery->hasPermission(Horde_Auth::getAuth(), Horde_Perms::EDIT)) {
     throw new Horde_Exception('Access denied editing the photo.');
 }
 
-$faces = Ansel_Faces::factory();
+$faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
 $result = $faces->setName($face_id, $name);
index 0d9a7f3..cecd1bd 100644 (file)
@@ -15,7 +15,7 @@ Horde_Registry::appInit('ansel');
 
 $face_id = Horde_Util::getFormData('face');
 
-$faces = Ansel_Faces::factory();
+$faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
 try {
     $face = $faces->getFaceById($face_id);
 } catch (Horde_Exception $e) {
index 5fba259..79a88bc 100644 (file)
@@ -31,7 +31,7 @@ if (Horde_Util::getPost('submit') == _("Cancel")) {
     exit;
 }
 try {
-    $faces = Ansel_Faces::factory();
+    $faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
     $result = $faces->saveCustomFace(
                            $face_id,
                            $image_id,
index aef5a04..c76d665 100644 (file)
@@ -13,7 +13,7 @@
 require_once dirname(__FILE__) . '/../../lib/Application.php';
 Horde_Registry::appInit('ansel');
 
-$faces = Ansel_Faces::factory();
+$faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
 
 /* Show tabs */
 $vars = Horde_Variables::getDefaultVariables();
index 5f59bbf..44d0d0d 100644 (file)
@@ -39,7 +39,7 @@ class Ansel_Ajax_Imple_EditFaces extends Horde_Ajax_Imple_Base
                 return array('response' => 0);
             }
 
-            $faces = Ansel_Faces::factory();
+            $faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
             switch($action) {
             case 'process':
                 // process - detects all faces in the image.
@@ -77,7 +77,7 @@ class Ansel_Ajax_Imple_EditFaces extends Horde_Ajax_Imple_Base
                     throw new Horde_Exception('Access denied editing the photo.');
                 }
 
-                $faces = Ansel_Faces::factory();
+                $faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
                 $faces->delete($image, $face_id);
                 break;
 
@@ -95,7 +95,7 @@ class Ansel_Ajax_Imple_EditFaces extends Horde_Ajax_Imple_Base
                     throw new Horde_Exception('You are not allowed to edit this photo');
                 }
 
-                $faces = Ansel_Faces::factory();
+                $faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
                 $result = $faces->setName($face_id, $name);
                 return array('response' => 1,
                              'message' => Ansel_Faces::getFaceTile($face_id));
index d99d131..a22e9f1 100644 (file)
@@ -61,6 +61,7 @@ class Ansel_Application extends Horde_Registry_Application
         $binders = array(
             'Ansel_Storage' => new Ansel_Injector_Binder_Storage(),
             'Ansel_Styles' => new Ansel_Injector_Binder_Styles(),
+            'Ansel_Faces' => new Ansel_Injector_Binder_Faces(),
         );
         foreach ($binders as $interface => $binder) {
             $GLOBALS['injector']->addBinder($interface, $binder);
index ae22e2a..5056b9e 100644 (file)
@@ -34,7 +34,7 @@ class Horde_Block_ansel_recent_faces extends Horde_Block
 
     function _content()
     {
-        $faces = Ansel_Faces::factory();
+        $faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
         $results = $faces->allFaces(0, $this->_params['limit']);
         $html = '';
         foreach ($results as $face_id => $face) {
index a0339c6..a557384 100644 (file)
 class Ansel_Faces
 {
     /**
-     * Create instance
-     */
-    static function factory($driver = null, $params = array())
-    {
-        if ($driver === null) {
-            $driver = $GLOBALS['conf']['faces']['driver'];
-        }
-
-        if (empty($params)) {
-            $params = $GLOBALS['conf']['faces'];
-        }
-
-        $class_name = 'Ansel_Faces_' . $driver;
-        $parser = new $class_name($params);
-
-        return $parser;
-    }
-
-    /**
      * Delete faces from VFS and DB storage.
      *
      * @TODO: Move SQL queries to Ansel_Storage::
@@ -118,7 +99,7 @@ class Ansel_Faces
      */
     static public function getFaceTile($face)
     {
-        $faces = Ansel_Faces::factory();
+        $faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
         if (!is_array($face)) {
             $face = $faces->getFaceById($face, true);
         }
@@ -154,8 +135,7 @@ class Ansel_Faces
         }
 
         // Link for searching for similar faces.
-        $html .= ' <a href="' . Horde_Util::addParameter($search_url, 'face_id', $face_id)
-            . '">' . _("Find similar") . '</a>';
+        $html .= ' <a href="' . Horde_Util::addParameter($search_url, 'face_id', $face_id) . '">' . _("Find similar") . '</a>';
         $html .= '</div></td></tr></table>';
 
         return $html;
index b862c6d..ec55161 100644 (file)
@@ -35,7 +35,7 @@ class Ansel_Faces_Base
      *
      * @return mixed  Array of face data
      */
-    public function getFaces(&$image)
+    public function getFaces($image)
     {
         if ($image instanceof Ansel_Image) {
             // First check if screen view exists
@@ -44,7 +44,10 @@ class Ansel_Faces_Base
             // Make sure we have an on-disk copy of the file.
             $file = $GLOBALS['injector']->getInstance('Horde_Vfs')->getVfs('images')->readFile($image->getVFSPath('screen'),
                                                     $image->getVFSName('screen'));
-        } elseif (empty($file) || !is_string($image)) {
+        } else {
+            $file = $image;
+        }
+        if (empty($file) || !is_string($image)) {
               return array();
         }
 
@@ -87,7 +90,7 @@ class Ansel_Faces_Base
             $sql .= ', gallery_id, face_x1, face_y1, face_x2, face_y2';
         }
         $sql .= ' FROM ansel_faces WHERE image_id = ' . (int)$image_id
-                . ' ORDER BY face_id DESC';
+            . ' ORDER BY face_id DESC';
 
        Horde::logMessage('SQL Query by Ansel_Faces::getImageFacesData: ' . $sql, 'DEBUG');
        $result = $GLOBALS['ansel_db']->query($sql);
@@ -128,7 +131,7 @@ class Ansel_Faces_Base
     public function getGalleryFaces($gallery)
     {
         $sql = 'SELECT face_id, image_id, gallery_id, face_name FROM ansel_faces '
-               . ' WHERE gallery_id = ' . (int)$gallery . ' ORDER BY face_id DESC';
+            . ' WHERE gallery_id = ' . (int)$gallery . ' ORDER BY face_id DESC';
 
         $result = $GLOBALS['ansel_db']->query($sql);
         if ($result instanceof PEAR_Error) {
@@ -184,9 +187,9 @@ class Ansel_Faces_Base
         $faces = array();
         while ($face = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) {
             $faces[$face['face_id']] = array('face_name' => $face['face_name'],
-                                            'face_id' => $face['face_id'],
-                                            'gallery_id' => $face['gallery_id'],
-                                            'image_id' => $face['image_id']);
+                                             'face_id' => $face['face_id'],
+                                             'gallery_id' => $face['gallery_id'],
+                                             'image_id' => $face['image_id']);
         }
 
         return $faces;
@@ -255,7 +258,8 @@ class Ansel_Faces_Base
     {
         $info = array(
             'filter' => 's.share_owner = ' . $GLOBALS['ansel_db']->quote($owner),
-            'order' => 'f.face_id DESC');
+            'order' => 'f.face_id DESC'
+        );
 
         if (!Horde_Auth::getAuth() || $owner != Horde_Auth::getAuth()) {
             $info['filter'] .= ' AND s.gallery_passwd IS NULL';
@@ -346,8 +350,7 @@ class Ansel_Faces_Base
                 return false;
             }
             $data = $this->getFaceById($face_id, true);
-
-            $image = &$GLOBALS['ansel_storage']->getImage($image_id);
+            $image = $GLOBALS['ansel_storage']->getImage($image_id);
 
             // Actually create the image.
             $this->createView(
@@ -441,7 +444,7 @@ class Ansel_Faces_Base
      */
     public function saveCustomFace($face_id, $image, $x1, $y1, $x2, $y2, $name = '')
     {
-        $image = &$GLOBALS['ansel_storage']->getImage($image);
+        $image = $GLOBALS['ansel_storage']->getImage($image);
         $gallery = $GLOBALS['ansel_storage']->getGallery($image->gallery);
         if (!$gallery->hasPermission(Horde_Auth::getAuth(), Horde_Perms::EDIT)) {
             throw new Horde_Exception_PermissionDenied('Access denied editing the photo.');
@@ -460,16 +463,15 @@ class Ansel_Faces_Base
 
         // Process the image
         $this->createView($face_id,
-                                    $image,
-                                    $x1,
-                                    $y1,
-                                    $x2,
-                                    $y2);
+                          $image,
+                          $x1,
+                          $y1,
+                          $x2,
+                          $y2);
 
         // Clean up as images are static and all gallery images data will remain in memory
         $image->reset();
 
-
         // Store face id db
         if (empty($new)) {
             $sql = 'UPDATE ansel_faces SET face_name = ?, face_x1 = ?, face_y1 = ?, face_x2 = ?, face_y2 = ?'
@@ -605,7 +607,7 @@ class Ansel_Faces_Base
      *
      * @return integer the face id
      */
-    public function createView($face_id, &$image, $x1, $y1, $x2, $y2)
+    public function createView($face_id, $image, $x1, $y1, $x2, $y2)
     {
         // Make sure screen view is created and loaded
         $image->load('screen');
@@ -621,8 +623,11 @@ class Ansel_Faces_Base
         $path = Ansel_Faces::getVFSPath($image->id);
         $image->getHordeImage()->resize(50, 50, false);
         try {
-            $GLOBALS['injector']->getInstance('Horde_Vfs')->getVfs('images')->writeData($path . 'faces', $face_id . $ext,
-                                             $image->getHordeImage()->raw(), true);
+            $GLOBALS['injector']->getInstance('Horde_Vfs')->getVfs('images')->writeData(
+                $path . 'faces',
+                $face_id . $ext,
+                $image->getHordeImage()->raw(),
+                true);
         } catch (VFS_Exception $e) {
             throw new Horde_Exception_Prior($e);
         }
@@ -648,8 +653,9 @@ class Ansel_Faces_Base
         }
 
         // Ensure we have an on-disk file to read the signature from.
-        $path  = $GLOBALS['injector']->getInstance('Horde_Vfs')->getVfs('images')->readFile(Ansel_Faces::getVFSPath($image_id) . '/faces',
-                                                 $face_id . Ansel_Faces::getExtension());
+        $path  = $GLOBALS['injector']->getInstance('Horde_Vfs')->getVfs('images')->readFile(
+            Ansel_Faces::getVFSPath($image_id) . '/faces',
+            $face_id . Ansel_Faces::getExtension());
 
         $signature = puzzle_fill_cvec_from_file($path);
         if (empty($signature)) {
@@ -754,7 +760,6 @@ class Ansel_Faces_Base
     {
         $sql = 'UPDATE ansel_faces SET face_name = ? WHERE face_id = ?';
         $params = array($name, $face);
-
         $q = $GLOBALS['ansel_db']->prepare($sql, null, MDB2_PREPARE_MANIP);
         if ($q instanceof PEAR_Error) {
             throw new Horde_Exception_Prior($q);
@@ -796,8 +801,7 @@ class Ansel_Faces_Base
         // Always return the face_id
         $face['face_id'] = $face_id;
 
-        if ($full && $GLOBALS['conf']['faces']['search'] &&
-            function_exists('puzzle_uncompress_cvec')) {
+        if ($full && $GLOBALS['conf']['faces']['search'] && function_exists('puzzle_uncompress_cvec')) {
             $face['face_signature'] = puzzle_uncompress_cvec($face['face_signature']);
         }
 
@@ -841,8 +845,7 @@ class Ansel_Faces_Base
             $indexes[] = '(index_position = '
                 . $GLOBALS['ansel_db']->quote($i, 'integer')
                 . ' AND index_part = '
-                . $GLOBALS['ansel_db']->quote(
-                    substr($signature, $i * $word_len, $word_len))
+                . $GLOBALS['ansel_db']->quote(substr($signature, $i * $word_len, $word_len))
                 . ')';
         }
 
@@ -877,7 +880,8 @@ class Ansel_Faces_Base
                 'image_id' => $face['image_id'],
                 'similarity' => puzzle_vector_normalized_distance(
                     $signature,
-                    puzzle_uncompress_cvec($face['face_signature'])));
+                    puzzle_uncompress_cvec($face['face_signature']))
+            );
         }
         uasort($faces, array($this, '_getSignatureMatches'));
 
index 720ddff..ec69751 100644 (file)
@@ -5,7 +5,7 @@
  * @author  Duck <duck@obala.net>
  * @package Ansel
  */
-class Ansel_Faces_facedetect extends Ansel_Faces_Base
+class Ansel_Faces_Facedetect extends Ansel_Faces_Base
 {
     /**
      * Where the face defintions are stored
@@ -20,6 +20,9 @@ class Ansel_Faces_facedetect extends Ansel_Faces_Base
         $this->_defs = $params['defs'];
     }
 
+    /**
+     *
+     */
     public function canAutogenerate()
     {
         return true;
@@ -33,8 +36,7 @@ class Ansel_Faces_facedetect extends Ansel_Faces_Base
      */
     protected function _getFaces($file)
     {
-        $result = Horde_Util::loadExtension('facedetect');
-        if (!$result) {
+        if (!Horde_Util::loadExtension('facedetect')) {
             throw new Horde_Exception('You do not have the facedetect extension enabled in PHP');
         }
 
@@ -63,14 +65,13 @@ class Ansel_Faces_facedetect extends Ansel_Faces_Base
 
     protected function _getParamsArray($face_id, $image, $rect)
     {
-        $params = array($face_id,
-                $image->id,
-                $image->gallery,
-                $rect['x'],
-                $rect['y'],
-                $rect['x'] + $rect['w'],
-                $rect['y'] + $rect['h']);
-       return $params;
+        return array($face_id,
+                     $image->id,
+                     $image->gallery,
+                     $rect['x'],
+                     $rect['y'],
+                     $rect['x'] + $rect['w'],
+                     $rect['y'] + $rect['h']);
     }
 
     protected function _createView($face_id, $image, $rect)
diff --git a/ansel/lib/Faces/opencv.php b/ansel/lib/Faces/opencv.php
deleted file mode 100644 (file)
index 0622d92..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-/**
- * OpenCV implementation
- *
- * @author  Duck <duck@obala.net>
- * @package Ansel
- */
-class Ansel_Faces_opencv extends Ansel_Faces_Base
-{
-    /**
-     * Where the face defintions are stored
-     */
-    private $_defs = '';
-
-    /**
-     * Create instance
-     */
-    public function __construct($params)
-    {
-        $this->_defs = $params['defs'];
-    }
-
-    public function canAutogenerate()
-    {
-        return true;
-    }
-
-    /**
-     * Get faces
-     *
-     * @param string $file Picture filename
-     */
-    protected function _getFaces($file)
-    {
-        $result = Horde_Util::loadExtension('opencv');
-        if (!$result) {
-            throw new Horde_Exception('You do not have the opencv extension enabled in PHP');
-        }
-        $im = cv_image_load($file);
-        $haar = cv_object_load($this->_defs);
-        $seq = cv_haar_classifier_cascade_detect_objects($haar, $im);
-        $l = cv_seq_count($seq);
-        Horde::logMessage(sprintf("opencv extension detected %u faces.", $l), 'DEBUG');
-        $rects = array();
-        for ($i = 0; $i < $l; $i++) {
-            $r = cv_seq_get($seq, $i);
-            $rects[] = array('x' => $r['x'],
-                             'y' => $r['y'],
-                             'width' => $r['w'],
-                             'height' => $r['h']);
-        }
-
-        return $rects;
-    }
-
-    /**
-     * Check if a face in is inside anoter face
-     *
-     * @param array $face  Face we are cheking
-     * @param array $faces Existing faces
-     *
-     * @param int Face ID containg passed face
-     */
-    protected function _isInFace($face, $faces)
-    {
-        foreach ($faces as $id => $rect) {
-            if ($face['x'] > $rect['x'] && $face['x'] + $face['width'] < $face['x'] + $rect['width']
-                && $face['y'] > $rect['y'] && $face['y'] + $face['height'] < $face['y'] + $rect['height']) {
-                return $id;
-            }
-        }
-
-        return false;
-    }
-
-    protected function _getParamsArray($face_id, $image, $rect)
-    {
-        $params = array($face_id,
-                $image->id,
-                $image->gallery,
-                $rect['x'],
-                $rect['y'],
-                $rect['x'] + $rect['width'],
-                $rect['y'] + $rect['height']);
-       return $params;
-    }
-
-    protected function _createView($face_id, $image, $rect)
-    {
-        return $this->createView($face_id,
-                                $image,
-                                $rect['x'],
-                                $rect['y'],
-                                $rect['x'] + $rect['width'],
-                                $rect['y'] + $rect['height']);
-    }
-}
index 0e8d338..ff6f0d2 100644 (file)
@@ -3,6 +3,6 @@
  * @author  Duck <duck@obala.net>
  * @package Ansel
  */
-class Ansel_Faces_user extends Ansel_Faces_Base
+class Ansel_Faces_User extends Ansel_Faces_Base
 {
 }
diff --git a/ansel/lib/Injector/Binder/Faces.php b/ansel/lib/Injector/Binder/Faces.php
new file mode 100644 (file)
index 0000000..99d8be5
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Binder for Ansel_Faces
+ *
+ * @author Michael J. Rubinsky <mrubinsk@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/gpl.html GPL
+ * @package  Ansel
+ */
+class Ansel_Injector_Binder_Faces Implements Horde_Injector_Binder
+{
+    public function create (Horde_Injector $injector)
+    {
+        $driver = $GLOBALS['conf']['faces']['driver'];
+        $params = $GLOBALS['conf']['faces'];
+        $class_name = 'Ansel_Faces_' . ucfirst($driver);
+
+        return new $class_name($params);
+    }
+
+    /**
+     */
+    public function equals(Horde_Injector_Binder $binder)
+    {
+        return false;
+    }
+}
\ No newline at end of file
index f26a000..3009799 100644 (file)
@@ -58,7 +58,7 @@ class Ansel_Widget_GalleryFaces extends Ansel_Widget_Base
                     . '<br /><em>' . _("No faces found") . '</em></div>';
         }
 
-        $faces = Ansel_Faces::factory();
+        $faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
 
         // Check for existing faces for this gallery.
         $html = '<div style="display: block'
index ce20946..fc04aa8 100644 (file)
@@ -53,7 +53,7 @@ class Ansel_Widget_ImageFaces extends Ansel_Widget_Base
      */
     protected function _getFaceNames()
     {
-        $faces = Ansel_Faces::factory();
+        $faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
 
         // Check for existing faces for this image.
         $html = '';
index 054e5ab..06727c3 100644 (file)
@@ -23,7 +23,7 @@ class Ansel_Widget_OwnerFaces extends Ansel_Widget_Base
             return '';
         }
 
-        $this->_faces = Ansel_Faces::factory();
+        $this->_faces = $GLOBALS['injector']->getInstance('Ansel_Faces');
         $this->_owner = $this->_view->gallery->get('owner');
         try {
             $this->_count = $this->_faces->countOwnerFaces($this->_owner);