Clean up some refactoring artifacts, new package.xml, search/replace artifacts etc...
authorMichael J. Rubinsky <mrubinsk@horde.org>
Sat, 1 Aug 2009 15:53:27 +0000 (11:53 -0400)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Sat, 1 Aug 2009 15:53:27 +0000 (11:53 -0400)
framework/Image/lib/Horde/Image/Exif.php
framework/Image/lib/Horde/Image/Exif/Base.php
framework/Image/package.xml

index 9bd9758..2f76c17 100644 (file)
@@ -24,7 +24,7 @@ class Horde_Image_Exif
      * @param $num
      * @return unknown_type
      */
-    static public function Horde_Image_Exif::intel2Moto($num)
+    static public function intel2Moto($num)
     {
         $len  = strlen($intel);
         $moto = '';
@@ -35,4 +35,363 @@ class Horde_Image_Exif
         return $moto;
     }
 
+    /**
+     *
+     * @return unknown_type
+     */
+    static public function getFields()
+    {
+        return array('Make' => array('description' => _("Camera Make"), 'type' => 'text'),
+                     'Model' => array('description' => _("Camera Model"), 'type' => 'text'),
+                     'ImageType' => array('description' => _("Photo Type"), 'type' => 'text'),
+                     'ImageDescription' => array('description' => _("Photo Description"), 'type' => 'text'),
+                     'FileSize' => array('description' => _("File Size"), 'type' => 'number'),
+                     'DateTime' => array('description' => _("Date Photo Modified"), 'type' => 'date'),
+                     'DateTimeOriginal' => array('description' => _("Date Photo Taken"), 'type' => 'date'),
+                     'DateTimeDigitized' => array('description' => _("Date Photo Digitized"), 'type' => 'date'),
+                     'ExifImageWidth' => array('description' => _("Width"), 'type' => 'number'),
+                     'ExifImageLength' => array('description' => _("Height"), 'type' => 'number'),
+                     'XResolution' => array('description' => _("X Resolution"), 'type' => 'number'),
+                     'YResolution' => array('description' => _("Y Resolution"), 'type' => 'number'),
+                     'ResolutionUnit' => array('description' => _("Resolution Unit"), 'type' => 'text'),
+                     'ShutterSpeedValue' => array('description' => _("Shutter Speed"), 'type' => 'number'),
+                     'ExposureTime' => array('description' => _("Exposure"), 'type' => 'number'),
+                     'FocalLength' => array('description' => _("Focal Length"), 'type' => 'number'),
+                     'FocalLengthIn35mmFilm' => array('description' => _("Focal Length (35mm equiv)"), 'type' => 'number'),
+                     'ApertureValue' => array('description' => _("Aperture"), 'type' => 'number'),
+                     'FNumber' => array('description' => _("F-Number"), 'type' => 'number'),
+                     'ISOSpeedRatings' => array('description' => _("ISO Setting"), 'type' => 'number'),
+                     'ExposureBiasValue' => array('description' => _("Exposure Bias"), 'type' => 'number'),
+                     'ExposureMode' => array('description' => _("Exposure Mode"), 'type' => 'number'),
+                     'ExposureProgram' => array('description' => _("Exposure Program"), 'type' => 'number'),
+                     'MeteringMode' => array('description' => _("Metering Mode"), 'type' => 'number'),
+                     'Flash' => array('description' => _("Flash Setting"), 'type' => 'number'),
+                     'UserComment' => array('description' => _("User Comment"), 'type' => 'text'),
+                     'ColorSpace' => array('description' => _("Color Space"), 'type' => 'number'),
+                     'SensingMethod' => array('description' => _("Sensing Method"), 'type' => 'number'),
+                     'WhiteBalance' => array('description' => _("White Balance"), 'type' => 'number'),
+                     'Orientation' => array('description' => _("Camera Orientation"), 'type' => 'number'),
+                     'Copyright' => array('description' => _("Copyright"), 'type' => 'text'),
+                     'Artist' => array('description' => _("Artist"), 'type' => 'text'),
+                     'GPSLatitude' => array('description' => _("Latitude"), 'type' => 'gps'),
+                     'GPSLongitude' => array('description' => _("Longitude"), 'type' => 'gps'),
+                     'LightSource' => array('description' => _("Light source"), 'type' => 'number'),
+                     'FileSource' => array('description' => _("File source"), 'type' => 'number'),
+        );
+    }
+
+    /**
+     * More human friendly exposure formatting.
+     */
+    static protected function _formatExposure($data) {
+        if ($data > 0) {
+            if ($data > 1) {
+                return sprintf(_("%d sec"), round($data, 2));
+            } else {
+                $n = $d = 0;
+                self::_convertToFraction($data, $n, $d);
+                if ($n <> 1) {
+                    return sprintf(_("%4f sec"), $n / $d);
+                }
+                return sprintf(_("%s / %s sec"), $n, $d);
+            }
+        } else {
+            return _("Bulb");
+        }
+    }
+
+    /**
+     * Converts a floating point number into a fraction.
+     * Many thanks to Matthieu Froment for this code.
+     *
+     * (Ported from the Exifer library).
+     */
+    static protected function _convertToFraction($v, &$n, &$d)
+    {
+        $MaxTerms = 15;         // Limit to prevent infinite loop
+        $MinDivisor = 0.000001; // Limit to prevent divide by zero
+        $MaxError = 0.00000001; // How close is enough
+
+        // Initialize fraction being converted
+        $f = $v;
+
+        // Initialize fractions with 1/0, 0/1
+        $n_un = 1;
+        $d_un = 0;
+        $n_deux = 0;
+        $d_deux = 1;
+
+        for ($i = 0; $i < $MaxTerms; $i++) {
+            $a = floor($f); // Get next term
+            $f = $f - $a; // Get new divisor
+            $n = $n_un * $a + $n_deux; // Calculate new fraction
+            $d = $d_un * $a + $d_deux;
+            $n_deux = $n_un; // Save last two fractions
+            $d_deux = $d_un;
+            $n_un = $n;
+            $d_un = $d;
+
+            // Quit if dividing by zero
+            if ($f < $MinDivisor) {
+                break;
+            }
+            if (abs($v - $n / $d) < $MaxError) {
+                break;
+            }
+
+            // reciprocal
+            $f = 1 / $f;
+        }
+    }
+
+    /**
+     * Convert an exif field into human-readable form.
+     * Some of these cases are ported from the Exifer library, others were
+     * changed from their implementation where the EXIF standard dictated
+     * different behaviour.
+     *
+     * @param string $field  The name of the field to translate.
+     * @param string $data   The data value to translate.
+     *
+     * @return string  The converted data.
+     */
+    static public function getHumanReadable($field, $data)
+    {
+        switch ($field) {
+        case 'ExposureMode':
+            switch ($data) {
+            case 0: return _("Auto exposure");
+            case 1: return _("Manual exposure");
+            case 2: return _("Auto bracket");
+            default: return _("Unknown");
+            }
+
+        case 'ExposureProgram':
+            switch ($data) {
+            case 1: return _("Manual");
+            case 2: return _("Normal Program");
+            case 3: return _("Aperture Priority");
+            case 4: return _("Shutter Priority");
+            case 5: return _("Creative");
+            case 6: return _("Action");
+            case 7: return _("Portrait");
+            case 8: return _("Landscape");
+            default: return _("Unknown");
+            }
+
+        case 'XResolution':
+        case 'YResolution':
+            if (strpos($data, '/') !== false) {
+                list($n, $d) = explode('/', $data, 2);
+                return sprintf(_("%d dots per unit"), $n);
+            }
+            return sprintf(_("%d per unit"), $data);
+
+        case 'ResolutionUnit':
+            switch ($data) {
+            case 1: return _("Pixels");
+            case 2: return _("Inch");
+            case 3: return _("Centimeter");
+            default: return _("Unknown");
+            }
+
+        case 'ExifImageWidth':
+        case 'ExifImageLength':
+            return sprintf(_("%d pixels"), $data);
+
+        case 'Orientation':
+            switch ($data) {
+            case 1:
+                return sprintf(_("Normal (O deg)"));
+            case 2:
+                return sprintf(_("Mirrored"));
+            case 3:
+                return sprintf(_("Upsidedown"));
+            case 4:
+                return sprintf(_("Upsidedown Mirrored"));
+            case 5:
+                return sprintf(_("90 deg CW Mirrored"));
+            case 6:
+                return sprintf(_("90 deg CCW"));
+            case 7:
+                return sprintf(_("90 deg CCW Mirrored"));
+            case 8:
+                return sprintf(_("90 deg CW"));
+            }
+            break;
+
+        case 'ExposureTime':
+            if (strpos($data, '/') !== false) {
+                list($n, $d) = explode('/', $data, 2);
+                $data = $n / $d;
+            }
+            return self::_formatExposure($data);
+
+        case 'ShutterSpeedValue':
+            if (strpos($data, '/') !== false) {
+                list($n, $d) = explode('/', $data, 2);
+                $data = $n / $d;
+            }
+            $data = exp($data * log(2));
+            if ($data > 0) {
+                $data = 1 / $data;
+            }
+            return self::_formatExposure($data);
+
+        case 'ApertureValue':
+        case 'MaxApertureValue':
+            if (strpos($data, '/') !== false) {
+                list($n, $d) = explode('/', $data, 2);
+                $data = $n / $d;
+                $data = exp(($data * log(2)) / 2);
+
+                // Precision is 1 digit.
+                $data = round($data, 1);
+            }
+            return 'f/' . $data;
+
+        case 'FocalLength':
+            if (strpos($data, '/') !== false) {
+                list($n, $d) = explode('/', $data, 2);
+                return sprintf(_("%d mm"), round($n / $d));
+            }
+            return sprintf(_("%d mm"), $data);
+
+        case 'FNumber':
+            if (strpos($data, '/') !== false) {
+                list($n, $d) = explode('/', $data, 2);
+                if ($d != 0) {
+                    return 'f/' . round($n / $d, 1);
+                }
+            }
+            return 'f/' . $data;
+
+        case 'ExposureBiasValue':
+            if (strpos($data, '/') !== false) {
+                list($n, $d) = explode('/', $data, 2);
+                if ($n == 0) {
+                    return '0 EV';
+                }
+            }
+            return $data . ' EV';
+
+        case 'MeteringMode':
+            switch ($data) {
+            case 0: return _("Unknown");
+            case 1: return _("Average");
+            case 2: return _("Center Weighted Average");
+            case 3: return _("Spot");
+            case 4: return _("Multi-Spot");
+            case 5: return _("Multi-Segment");
+            case 6: return _("Partial");
+            case 255: return _("Other");
+            default: return sprintf(_("Unknown: %s"), $data);
+            }
+            break;
+
+        case 'LightSource':
+            switch ($data) {;
+            case 1: return _("Daylight");
+            case 2: return _("Fluorescent");
+            case 3: return _("Tungsten");
+            case 4: return _("Flash");
+            case 9: return _("Fine weather");
+            case 10: return _("Cloudy weather");
+            case 11: return _("Shade");
+            case 12: return _("Daylight fluorescent");
+            case 13: return _("Day white fluorescent");
+            case 14: return _("Cool white fluorescent");
+            case 15: return _("White fluorescent");
+            case 17: return _("Standard light A");
+            case 18: return _("Standard light B");
+            case 19: return _("Standard light C");
+            case 20: return 'D55';
+            case 21: return 'D65';
+            case 22: return 'D75';
+            case 23: return 'D50';
+            case 24: return _("ISO studio tungsten");
+            case 255: return _("other light source");
+            default: return _("Unknown");
+            }
+
+        case 'WhiteBalance':
+            switch ($data) {
+            case 0: return _("Auto");
+            case 1: return _("Manual");
+            default: _("Unknown");
+            }
+            break;
+
+        case 'FocalLengthIn35mmFilm':
+            return $data . ' mm';
+
+        case 'Flash':
+            switch ($data) {
+            case 0: return _("No Flash");
+            case 1: return _("Flash");
+            case 5: return _("Flash, strobe return light not detected");
+            case 7: return _("Flash, strobe return light detected");
+            case 9: return _("Compulsory Flash");
+            case 13: return _("Compulsory Flash, Return light not detected");
+            case 15: return _("Compulsory Flash, Return light detected");
+            case 16: return _("No Flash");
+            case 24: return _("No Flash");
+            case 25: return _("Flash, Auto-Mode");
+            case 29: return _("Flash, Auto-Mode, Return light not detected");
+            case 31: return _("Flash, Auto-Mode, Return light detected");
+            case 32: return _("No Flash");
+            case 65: return _("Red Eye");
+            case 69: return _("Red Eye, Return light not detected");
+            case 71: return _("Red Eye, Return light detected");
+            case 73: return _("Red Eye, Compulsory Flash");
+            case 77: return _("Red Eye, Compulsory Flash, Return light not detected");
+            case 79: return _("Red Eye, Compulsory Flash, Return light detected");
+            case 89: return _("Red Eye, Auto-Mode");
+            case 93: return _("Red Eye, Auto-Mode, Return light not detected");
+            case 95: return _("Red Eye, Auto-Mode, Return light detected");
+            }
+            break;
+
+        case 'FileSize':
+           if ($data <= 0) {
+              return '0 Bytes';
+           }
+           $s = array('B', 'kB', 'MB', 'GB');
+           $e = floor(log($data, 1024));
+           return round($data/pow(1024, $e), 2) . ' ' . $s[$e];
+
+        case 'FileSource':
+            $data = bin2hex($data);
+            $data = str_replace('00', '', $data);
+            $data = str_replace('03', _("Digital Still Camera"), $data);
+            return $data;
+
+        case 'SensingMethod':
+            switch ($data) {
+            case 1: return _("Not defined");
+            case 2: return _("One Chip Color Area Sensor");
+            case 3: return _("Two Chip Color Area Sensor");
+            case 4: return _("Three Chip Color Area Sensor");
+            case 5: return _("Color Sequential Area Sensor");
+            case 7: return _("Trilinear Sensor");
+            case 8: return _("Color Sequential Linear Sensor");
+            default: return _("Unknown");
+            }
+
+        case 'ColorSpace':
+            switch ($data) {
+            case 1: return _("sRGB");
+            default: return _("Uncalibrated");
+            }
+
+        case 'DateTime':
+        case 'DateTimeOriginal':
+        case 'DateTimeDigitized':
+            return date('m/d/Y H:i:s O', $data);
+
+        default:
+            return $data;
+        }
+    }
+
 }
index d8d68c9..9206225 100644 (file)
@@ -8,51 +8,6 @@ abstract class Horde_Image_Exif_Base
 
     /**
      *
-     * @return unknown_type
-     */
-    static public function getFields()
-    {
-        return array('Make' => array('description' => _("Camera Make"), 'type' => 'text'),
-                     'Model' => array('description' => _("Camera Model"), 'type' => 'text'),
-                     'ImageType' => array('description' => _("Photo Type"), 'type' => 'text'),
-                     'ImageDescription' => array('description' => _("Photo Description"), 'type' => 'text'),
-                     'FileSize' => array('description' => _("File Size"), 'type' => 'number'),
-                     'DateTime' => array('description' => _("Date Photo Modified"), 'type' => 'date'),
-                     'DateTimeOriginal' => array('description' => _("Date Photo Taken"), 'type' => 'date'),
-                     'DateTimeDigitized' => array('description' => _("Date Photo Digitized"), 'type' => 'date'),
-                     'ExifImageWidth' => array('description' => _("Width"), 'type' => 'number'),
-                     'ExifImageLength' => array('description' => _("Height"), 'type' => 'number'),
-                     'XResolution' => array('description' => _("X Resolution"), 'type' => 'number'),
-                     'YResolution' => array('description' => _("Y Resolution"), 'type' => 'number'),
-                     'ResolutionUnit' => array('description' => _("Resolution Unit"), 'type' => 'text'),
-                     'ShutterSpeedValue' => array('description' => _("Shutter Speed"), 'type' => 'number'),
-                     'ExposureTime' => array('description' => _("Exposure"), 'type' => 'number'),
-                     'FocalLength' => array('description' => _("Focal Length"), 'type' => 'number'),
-                     'FocalLengthIn35mmFilm' => array('description' => _("Focal Length (35mm equiv)"), 'type' => 'number'),
-                     'ApertureValue' => array('description' => _("Aperture"), 'type' => 'number'),
-                     'FNumber' => array('description' => _("F-Number"), 'type' => 'number'),
-                     'ISOSpeedRatings' => array('description' => _("ISO Setting"), 'type' => 'number'),
-                     'ExposureBiasValue' => array('description' => _("Exposure Bias"), 'type' => 'number'),
-                     'ExposureMode' => array('description' => _("Exposure Mode"), 'type' => 'number'),
-                     'ExposureProgram' => array('description' => _("Exposure Program"), 'type' => 'number'),
-                     'MeteringMode' => array('description' => _("Metering Mode"), 'type' => 'number'),
-                     'Flash' => array('description' => _("Flash Setting"), 'type' => 'number'),
-                     'UserComment' => array('description' => _("User Comment"), 'type' => 'text'),
-                     'ColorSpace' => array('description' => _("Color Space"), 'type' => 'number'),
-                     'SensingMethod' => array('description' => _("Sensing Method"), 'type' => 'number'),
-                     'WhiteBalance' => array('description' => _("White Balance"), 'type' => 'number'),
-                     'Orientation' => array('description' => _("Camera Orientation"), 'type' => 'number'),
-                     'Copyright' => array('description' => _("Copyright"), 'type' => 'text'),
-                     'Artist' => array('description' => _("Artist"), 'type' => 'text'),
-                     'GPSLatitude' => array('description' => _("Latitude"), 'type' => 'gps'),
-                     'GPSLongitude' => array('description' => _("Longitude"), 'type' => 'gps'),
-                     'LightSource' => array('description' => _("Light source"), 'type' => 'number'),
-                     'FileSource' => array('description' => _("File source"), 'type' => 'number'),
-        );
-    }
-
-    /**
-     *
      * @param $exif
      * @return unknown_type
      */
@@ -60,7 +15,7 @@ abstract class Horde_Image_Exif_Base
     {
         $results = array();
         if ($exif) {
-            $fields = self::getFields();
+            $fields = Horde_Image_Exif::getFields();
 
             foreach ($fields as $field => $data) {
                 $value = isset($exif[$field]) ? $exif[$field] : '';
index 6372b96..677b887 100644 (file)
@@ -71,6 +71,21 @@ http://pear.php.net/dtd/package-2.0.xsd">
         <file name="UnsharpMask.php" role="php" />
        </dir> <!-- /Horde/Image/Effect/gd -->
       </dir> <!-- /Horde/Image/Effect -->
+      <dir name="Exif">
+        <dir name="Parser">
+          <file name="Base.php" role="php" />
+          <file name="Canon.php" role="php" />
+          <file name="Fujifilm.php" role="php" />
+          <file name="Gps.php" role="php" />
+          <file name="Nikon.php" role="php" />
+          <file name="Olympus.php" role="php" />
+          <file name="Panasonic.php" role="php" />
+          <file name="Sanyo.php" role="php" />
+        </dir> <!-- /Horde/Image/Exif/Parser -->
+        <file name="Base.php" role="php" />
+        <file name="Bundled.php" role="php" />
+        <file name="Php.php" role="php" />
+      </dir> <!-- /Horde/Image/Exif -->
       <file name="Effect.php" role="php" />
       <file name="Gd.php" role="php" />
       <file name="Im.php" role="php" />
@@ -80,6 +95,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
       <file name="rgb.php" role="php" />
       <file name="Svg.php" role="php" />
       <file name="Swf.php" role="php" />
+      <file name="Exif.php" role="php" />
       <file name="Exception.php" role="php" />
      </dir> <!-- /Horde/Image -->
      <file name="Image.php" role="php" />
@@ -115,6 +131,18 @@ http://pear.php.net/dtd/package-2.0.xsd">
  </dependencies>
  <phprelease>
   <filelist>
+   <install name="lib/Horde/Image/Exif/Parser/Base.php" as="Horde/Image/Exif/Parser/Base.php" />
+   <install name="lib/Horde/Image/Exif/Parser/Canon.php" as="Horde/Image/Exif/Parser/Canon.php" />
+   <install name="lib/Horde/Image/Exif/Parser/Fujifilm.php" as="Horde/Image/Exif/Parser/Fujifilm.php" />
+   <install name="lib/Horde/Image/Exif/Parser/Gps.php" as="Horde/Image/Exif/Parser/Gps.php" />
+   <install name="lib/Horde/Image/Exif/Parser/Nikon.php" as="Horde/Image/Exif/Parser/Nikon.php" />
+   <install name="lib/Horde/Image/Exif/Parser/Olympus.php" as="Horde/Image/Exif/Parser/Olympus.php" />
+   <install name="lib/Horde/Image/Exif/Parser/Panasonic.php" as="Horde/Image/Exif/Parser/Panasonic.php" />
+   <install name="lib/Horde/Image/Exif/Parser/Sanyo.php" as="Horde/Image/Exif/Parser/Sanyo.php" />
+   <install name="lib/Horde/Image/Exif/Base.php" as="Horde/Image/Exif/Base.php" />
+   <install name="lib/Horde/Image/Exif/Bundled.php" as="Horde/Image/Exif/Bundled.php" />
+   <install name="lib/Horde/Image/Exif/Php.php" as="Horde/Image/Exif/Php.php" />
+   <install name="lib/Horde/Image/Exif.php" as="Horde/Image/Exif.php" />
    <install name="lib/Horde/Image/Effect/Border.php" as="Horde/Image/Effect/Border.php" />
    <install name="lib/Horde/Image/Effect/Im/DropShadow.php" as="Horde/Image/Effect/Im/DropShadow.php" />
    <install name="lib/Horde/Image/Effect/Im/RoundCorners.php" as="Horde/Image/Effect/Im/RoundCorners.php" />