[Checkins] SVN: z3c.blobfile/trunk/ retry detecting image dimensions with a longer snippet of the headers if IMAGE_INFO_BYTES wasn't enough

David Glick davidglick at onenw.org
Sun Apr 11 02:34:51 EDT 2010


Log message for revision 110732:
  retry detecting image dimensions with a longer snippet of the headers if IMAGE_INFO_BYTES wasn't enough

Changed:
  U   z3c.blobfile/trunk/CHANGES.txt
  U   z3c.blobfile/trunk/src/z3c/blobfile/image.py
  U   z3c.blobfile/trunk/src/z3c/blobfile/tests.py

-=-
Modified: z3c.blobfile/trunk/CHANGES.txt
===================================================================
--- z3c.blobfile/trunk/CHANGES.txt	2010-04-11 02:42:48 UTC (rev 110731)
+++ z3c.blobfile/trunk/CHANGES.txt	2010-04-11 06:34:51 UTC (rev 110732)
@@ -5,6 +5,9 @@
 0.1.5 (unreleased)
 ------------------
 
+- Bug: Correctly detect the dimensions of JPEG images with the dimensions
+  in a position greater than IMAGE_INFO_BYTES.
+
 - Made tests compatible with ZODB 3.9.
 
 

Modified: z3c.blobfile/trunk/src/z3c/blobfile/image.py
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/image.py	2010-04-11 02:42:48 UTC (rev 110731)
+++ z3c.blobfile/trunk/src/z3c/blobfile/image.py	2010-04-11 06:34:51 UTC (rev 110732)
@@ -28,8 +28,6 @@
 from z3c.blobfile.i18n import ZopeMessageFactory as _
 from z3c.blobfile.file import File
 
-from ZODB.blob import Blob
-
 import interfaces
 
 IMAGE_INFO_BYTES = 1024
@@ -40,18 +38,26 @@
     def _setData(self, data):
         super(Image, self)._setData(data)
         firstbytes = self.getFirstBytes()
-        contentType, self._width, self._height = getImageInfo(firstbytes)
+        res = getImageInfo(firstbytes)
+        while res == ('image/jpeg', -1, -1):
+            # header was longer than firstbytes
+            firstbytes += self.getFirstBytes(len(firstbytes))
+            res = getImageInfo(firstbytes)
+            if len(firstbytes) >= self.size:
+                break
+        contentType, self._width, self._height = res
         if contentType:
             self.contentType = contentType
 
     data = property(File._getData, _setData)
 
-    def getFirstBytes(self):
+    def getFirstBytes(self, start=0):
         """Returns the first bytes of the file.
         
         Returns an amount which is sufficient to determine the image type.
         """
         fp = self.open('r')
+        fp.seek(start)
         firstbytes = fp.read(IMAGE_INFO_BYTES)
         fp.close()
         return firstbytes

Modified: z3c.blobfile/trunk/src/z3c/blobfile/tests.py
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/tests.py	2010-04-11 02:42:48 UTC (rev 110731)
+++ z3c.blobfile/trunk/src/z3c/blobfile/tests.py	2010-04-11 06:34:51 UTC (rev 110732)
@@ -17,6 +17,7 @@
 """
 import unittest
 import zope.component
+import struct
 
 from zope.interface.verify import verifyClass
 from zope.app.file.interfaces import IImage
@@ -77,6 +78,16 @@
         self.failUnless(IBlobFile.implementedBy(Image))
         self.failUnless(IBlobImage.implementedBy(Image))
         self.failUnless(verifyClass(IBlobFile, Image))
+    
+    def testDataMutatorWithLargeHeader(self):
+        from z3c.blobfile.image import IMAGE_INFO_BYTES
+        bogus_header_length = struct.pack('>H', IMAGE_INFO_BYTES * 2)
+        data = ('\xff\xd8\xff\xe0' + bogus_header_length +
+                '\x00' * IMAGE_INFO_BYTES * 2 +
+                '\xff\xc0\x00\x11\x08\x02\xa8\x04\x00')
+        image = self._makeImage()
+        image._setData(data)
+        self.assertEqual(image.getImageSize(), (1024, 680))
 
 class TestFileAdapters(unittest.TestCase):
 
@@ -179,7 +190,7 @@
         t, w, h = getImageInfo('\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01'
                                '\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C')
         self.assertEqual(t, "image/jpeg")
-    
+
     def test_getImageInfo_bmp(self):
         t, w, h = getImageInfo('BMl\x05\x00\x00\x00\x00\x00\x006\x04\x00\x00('
                                '\x00\x00\x00\x10\x00\x00\x00\x10\x00\x00\x00'



More information about the checkins mailing list