public function getSignatureMatches($signature, $face_id = 0, $from = 0, $count = 0)
{
$word_len = $GLOBALS['conf']['faces']['search'];
$str_len = strlen($signature);
$c = $str_len - $word_len;
$indexes = array();
for ($i = 0; $i <= $c; $i++) {
$sig = new Horde_Db_Value_Binary(substr($signature, $i, $word_len));
$indexes[] = '(index_position = ' . $i . ' AND index_part = ' . $sig->quote($GLOBALS['ansel_db']) . ')';
}
$sql = 'SELECT i.face_id, f.face_name, ' . 'f.image_id, f.gallery_id, f.face_signature ' . 'FROM ansel_faces_index i, ansel_faces f ' . 'WHERE f.face_id = i.face_id';
if ($face_id) {
$sql .= ' AND i.face_id <> ' . (int) $face_id;
}
if ($indexes) {
$sql .= ' AND (' . implode(' OR ', $indexes) . ')';
}
$sql .= ' GROUP BY i.face_id, f.face_name, f.image_id, f.gallery_id, ' . 'f.face_signature HAVING count(i.face_id) > 0 ' . 'ORDER BY count(i.face_id) DESC';
$sql = $GLOBALS['ansel_db']->addLimitOffset($sql, array('limit' => $count, 'offset' => $from));
try {
$columns = $GLOBALS['ansel_db']->columns('ansel_faces');
$faces = $GLOBALS['ansel_db']->selectAll($sql);
} catch (Horde_Db_Exception $e) {
throw new Ansel_Exception($e);
}
if (empty($faces)) {
return array();
}
foreach ($faces as &$face) {
$face['similarity'] = puzzle_vector_normalized_distance($signature, puzzle_uncompress_cvec($columns['face_signature']->binaryToString($face['face_signature'])));
}
uasort($faces, array($this, '_getSignatureMatches'));
return $faces;
}