Output bits per channel. WIP.
authorMichael Ang <mang@archive.org>
Fri, 5 Mar 2010 03:36:42 +0000 (03:36 +0000)
committerMichael Ang <mang@archive.org>
Fri, 5 Mar 2010 03:36:42 +0000 (03:36 +0000)
BookReaderIA/datanode/BookReaderImages.php
BookReaderIA/test/unit/Images.js

index 9099ba3..9b6dfe1 100644 (file)
@@ -5,6 +5,10 @@ Copyright(c)2008 Internet Archive. Software license AGPL version 3.
 
 This file is part of BookReader.
 
+The canonical short name of an image type is the same as in the MIME type.
+For example both .jpeg and .jpg are considered to have type "jpeg" since
+the MIME type is "image/jpeg".
+
     BookReader is free software: you can redistribute it and/or modify
     it under the terms of the GNU Affero General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
@@ -19,8 +23,21 @@ This file is part of BookReader.
     along with BookReader.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-$MIMES = array('jpg' => 'image/jpeg',
-               'png' => 'image/png');
+$MIMES = array('gif' => 'image/gif',
+               'jp2' => 'image/jp2',
+               'jpg' => 'image/jpeg',
+               'jpeg' => 'image/jpeg',
+               'png' => 'image/png',
+               'tif' => 'image/tiff',
+               'tiff' => 'image/tiff');
+               
+$EXTENSIONS = array('gif' => 'gif',
+                    'jp2' => 'jp2',
+                    'jpeg' => 'jpeg',
+                    'jpg' => 'jpeg',
+                    'png' => 'png',
+                    'tif' => 'tiff',
+                    'tiff' => 'tiff');
                
 $exiftool = '/petabox/sw/books/exiftool/exiftool';
 
@@ -76,7 +93,21 @@ function getUnarchiveCommand($archivePath, $file)
     BRfatal('Bad image stack path or archive format');
     
 }
+
+/*
+ * Returns the image type associated with the file extension.
+ */
+function imageExtensionToType($extension)
+{
+    global $EXTENSIONS;
+    
+    if (array_key_exists($extension, $EXTENSIONS)) {
+        return $EXTENSIONS[$extension];
+    } else {
+        BRfatal('Unknown image extension');
+    }            
+}
+
 /*
  * Get the image width, height and depth from a jp2 file in zip.
  */
@@ -84,17 +115,29 @@ function getImageInfo($zipPath, $file)
 {
     global $exiftool;
     
+    $fileExt = strtolower(pathinfo($file, PATHINFO_EXTENSION));
+    $type = imageExtensionToType($fileExt);
+     
     // $$$ will exiftool work for *all* of our images?
     // BitsPerComponent present in jp2. Not present in jpeg.
     $cmd = getUnarchiveCommand($zipPath, $file)
-        . ' | '. $exiftool . ' -s -s -s -ImageWidth -ImageHeight -BitsPerComponent -';
+        . ' | '. $exiftool . ' -s -s -s -ImageWidth -ImageHeight -BitsPerComponent -Colorspace -';
     exec($cmd, $output);
     
+    $width = intval($output[0]);
+    $height = intval($output[1]);
     preg_match('/^(\d+)/', $output[2], $groups);
     $bits = intval($groups[1]);
+    $colorspace = intval($output[3]);
+    
+    // Format-specific overrides
+    if ('jpeg' == $type) {
+        // Note: JPEG may be single channel grayscale. jpegtopnm will create PGM in this case.
+        $bits = 8;
+    }
     
-    $retval = Array('width' => intval($output[0]), 'height' => intval($output[1]),
-        'bits' => $bits);
+    $retval = Array('width' => $width, 'height' => $height,
+        'bits' => $bits, 'type' => $type);
     
     return $retval;
 }
index 640250b..1f48ef0 100644 (file)
@@ -25,6 +25,32 @@ BookReader.prototype.init = function() {
 };
 
 
+// Test image info - jpeg
+asyncTest("JSLocate for armageddonafter00couruoft - jpeg", function() {
+    expect(1);
+    $.getScript( jsLocateURL('armageddonafter00couruoft'), function() {
+        equals(br.bookTitle, 'Armageddon and after', 'Title');
+        start();
+    });
+});
+
+asyncTest("Image info for jpeg", function() {
+    expect(3);
+    var expected = {"width":1349,"height":2105,"bits":8,"type":"jpeg"};
+    var imageInfoURL = br.getPageURI(8) + '&ext=json&callback=?';
+    
+    $.getJSON(imageInfoURL, function(data) {
+        equals(data != null, true, 'data is not null');
+        if (data != null) {
+            equals(data.width, expected.width, 'Image width');
+            same(data, expected, 'Image info object');
+        }
+        start();
+    });
+});
+
+
+
 // Test image info
 asyncTest("JSLocate for zc-f-c-b-4 - 1-bit jp2", function() {
     expect(1);
@@ -36,7 +62,7 @@ asyncTest("JSLocate for zc-f-c-b-4 - 1-bit jp2", function() {
 
 asyncTest("Image info for 1-bit jp2", function() {
     expect(3);
-    var expected = {"width":3295,"height":2561,"bits":1};
+    var expected = {"width":3295,"height":2561,"bits":1,"type":"jp2"};
     var imageInfoURL = br.getPageURI(0) + '&ext=json&callback=?';
     
     $.getJSON(imageInfoURL, function(data) {