[Checkins] SVN: z3c.filetype/trunk/src/z3c/filetype/ added specific size adapters

Bernd Dorn bernd.dorn at fhv.at
Wed Aug 30 12:27:58 EDT 2006


Log message for revision 69893:
  added specific size adapters

Changed:
  U   z3c.filetype/trunk/src/z3c/filetype/README.txt
  U   z3c.filetype/trunk/src/z3c/filetype/configure.zcml
  U   z3c.filetype/trunk/src/z3c/filetype/magic.txt
  U   z3c.filetype/trunk/src/z3c/filetype/size.py
  A   z3c.filetype/trunk/src/z3c/filetype/testdata/IMG_0504.JPG

-=-
Modified: z3c.filetype/trunk/src/z3c/filetype/README.txt
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/README.txt	2006-08-30 15:44:42 UTC (rev 69892)
+++ z3c.filetype/trunk/src/z3c/filetype/README.txt	2006-08-30 16:27:55 UTC (rev 69893)
@@ -24,6 +24,8 @@
   ...     print i
   DS_Store
   set([<InterfaceClass z3c.filetype.interfaces.filetypes.IBinaryFile>])
+  IMG_0504.JPG
+  set([<InterfaceClass z3c.filetype.interfaces.filetypes.IJPGFile>])
   faces_gray.avi
   set([<InterfaceClass z3c.filetype.interfaces.filetypes.IAVIFile>])
   ftyp.mov
@@ -181,3 +183,37 @@
   [<InterfaceClass z3c.filetype.interfaces.filetypes.IQuickTimeFile>]
   >>> interfaces.IFileType(foo).contentType
   'video/quicktime'
+
+Size adapters
+=============
+
+There are adapters registered for ISized for IPNGFile, IJPEGFile and
+IGIFFile.
+
+  >>> from z3c.filetype import size
+  >>> from zope.size.interfaces import ISized
+  >>> component.provideAdapter(size.GIFFileSized)
+  >>> component.provideAdapter(size.PNGFileSized)
+  >>> component.provideAdapter(size.JPGFileSized)
+
+  >>> foo.data = file(os.path.join(testData,'thumbnailImage_small.jpeg'))
+  >>> notify(ObjectModifiedEvent(foo))
+  >>> ISized(foo).sizeForDisplay().mapping
+  {'width': '120', 'height': '90', 'size': '3'}
+
+  >>> foo.data = file(os.path.join(testData,'test.png'))
+  >>> notify(ObjectModifiedEvent(foo))
+  >>> ISized(foo).sizeForDisplay().mapping
+  {'width': '279', 'height': '19', 'size': '4'}
+
+  >>> foo.data = file(os.path.join(testData,'logo.gif'))
+  >>> notify(ObjectModifiedEvent(foo))
+  >>> ISized(foo).sizeForDisplay().mapping
+  {'width': '201', 'height': '54', 'size': '2'}
+
+  >>> foo.data = file(os.path.join(testData,'IMG_0504.JPG'))
+  >>> notify(ObjectModifiedEvent(foo))
+  >>> ISized(foo).sizeForDisplay().mapping
+  {'width': '1600', 'height': '1200', 'size': '499'}
+
+

Modified: z3c.filetype/trunk/src/z3c/filetype/configure.zcml
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/configure.zcml	2006-08-30 15:44:42 UTC (rev 69892)
+++ z3c.filetype/trunk/src/z3c/filetype/configure.zcml	2006-08-30 16:27:55 UTC (rev 69893)
@@ -14,7 +14,9 @@
  
  <adapter factory=".adapters.TypedFileType"/>
 
- <adapter factory=".size.ImageFileSized" />
+ <adapter factory=".size.PNGFileSized" />
+ <adapter factory=".size.JPGFileSized" />
+ <adapter factory=".size.GIFFileSized" />
 
  
 </configure>

Modified: z3c.filetype/trunk/src/z3c/filetype/magic.txt
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/magic.txt	2006-08-30 15:44:42 UTC (rev 69892)
+++ z3c.filetype/trunk/src/z3c/filetype/magic.txt	2006-08-30 16:27:55 UTC (rev 69893)
@@ -14,6 +14,7 @@
   ...     path = os.path.join(testData, name)
   ...     print name, m.detect(file(path))
   DS_Store set([])
+  IMG_0504.JPG set(['image/jpeg'])
   faces_gray.avi set(['video/x-msvideo'])
   ftyp.mov set(['video/quicktime'])
   jumps.mov set(['video/quicktime'])

Modified: z3c.filetype/trunk/src/z3c/filetype/size.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/size.py	2006-08-30 15:44:42 UTC (rev 69892)
+++ z3c.filetype/trunk/src/z3c/filetype/size.py	2006-08-30 16:27:55 UTC (rev 69893)
@@ -1,30 +1,45 @@
 from zope.size.interfaces import ISized
-from zope.app.file.image import getImageInfo
+
 from zope.size import byteDisplay
-from interfaces.filetypes import IImageFile
+from interfaces import filetypes
 from zope import component, interface
 from zope.app.i18n import ZopeMessageFactory as _
+import os
+import stat
+import struct
 
 class ImageFileSized(object):
+
     interface.implements(ISized)
-    component.adapts(IImageFile)
     
     def __init__(self, image):
         self._image = image
 
+    @property
+    def bytes(self):
+        try:
+            return len(self._image.data)
+        except TypeError:
+            data = self._image.data
+            return int(os.fstat(data.fileno())[stat.ST_SIZE])
+        raise NotImplementedError
+    
     def sizeForSorting(self):
         '''See `ISized`'''
-        return ('byte', self._image.getSize())
+        return ('byte', self.bytes)
 
+    def getImageSize(self):
+        raise NotImplementedError
+
     def sizeForDisplay(self):
         '''See `ISized`'''
-        t, w, h = getImageInfo(self._image.data.read(256))
+
+        w, h = self.getImageSize()
         if w < 0:
             w = '?'
         if h < 0:
             h = '?'
-        bytes = self._image.getSize()
-        byte_size = byteDisplay(bytes)
+        byte_size = byteDisplay(self.bytes)
         mapping = byte_size.mapping
         if mapping is None:
             mapping = {}
@@ -32,3 +47,83 @@
         #TODO the way this message id is defined, it won't be picked up by
         # i18nextract and never show up in message catalogs
         return _(byte_size + ' ${width}x${height}', mapping=mapping)
+
+
+class GIFFileSized(ImageFileSized):
+
+    interface.implements(ISized)
+    component.adapts(filetypes.IGIFFile)
+
+    def getImageSize(self):
+        data = self._image.data
+        data.seek(0)
+        data = data.read(24)
+        size = len(data)
+        width = -1
+        height = -1
+        if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
+            # Check to see if content_type is correct
+            w, h = struct.unpack("<HH", data[6:10])
+            width = int(w)
+            height = int(h)
+        return width, height
+    
+class PNGFileSized(ImageFileSized):
+
+    interface.implements(ISized)
+    component.adapts(filetypes.IPNGFile)
+    
+    def getImageSize(self):
+        data = self._image.data
+        data.seek(0)
+        data = data.read(24)
+        size = len(data)
+        height = -1
+        width = -1
+        # See PNG 2. Edition spec (http://www.w3.org/TR/PNG/)
+        # Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
+        # and finally the 4-byte width, height
+        if ((size >= 24) and data.startswith('\211PNG\r\n\032\n')
+            and (data[12:16] == 'IHDR')):
+            w, h = struct.unpack(">LL", data[16:24])
+            width = int(w)
+            height = int(h)
+        # Maybe this is for an older PNG version.
+        elif (size >= 16) and data.startswith('\211PNG\r\n\032\n'):
+            w, h = struct.unpack(">LL", data[8:16])
+            width = int(w)
+            height = int(h)
+        return width, height
+
+class JPGFileSized(ImageFileSized):
+
+    interface.implements(ISized)
+    component.adapts(filetypes.IJPGFile)
+    
+    def getImageSize(self):
+        data = self._image.data
+        data.seek(2)
+        size = self.bytes
+        height = -1
+        width = -1
+        b = data.read(1)
+        try:
+            w = -1
+            h = -1
+            while (b and ord(b) != 0xDA):
+                while (ord(b) != 0xFF): b = data.read(1)
+                while (ord(b) == 0xFF): b = data.read(1)
+                if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
+                    data.read(3)
+                    h, w = struct.unpack(">HH", data.read(4))
+                    break
+                else:
+                    data.read(int(struct.unpack(">H", data.read(2))[0])-2)
+                b = data.read(1)
+            width = int(w)
+            height = int(h)
+        except struct.error:
+            pass
+        except ValueError:
+            pass
+        return width, height

Added: z3c.filetype/trunk/src/z3c/filetype/testdata/IMG_0504.JPG
===================================================================
(Binary files differ)


Property changes on: z3c.filetype/trunk/src/z3c/filetype/testdata/IMG_0504.JPG
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream



More information about the Checkins mailing list