Commit 74fdc747 authored by Shane Hathaway's avatar Shane Hathaway

Refactored a little. Now the image type and dimensions detection is a

separate function.
parent 9da95a3e
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
############################################################################## ##############################################################################
"""Image object""" """Image object"""
__version__='$Revision: 1.122 $'[11:-2] __version__='$Revision: 1.123 $'[11:-2]
import Globals, string, struct, content_types import Globals, string, struct, content_types
from OFS.content_types import guess_content_type from OFS.content_types import guess_content_type
...@@ -443,6 +443,64 @@ def manage_addImage(self, id, file, title='', precondition='', content_type='', ...@@ -443,6 +443,64 @@ def manage_addImage(self, id, file, title='', precondition='', content_type='',
REQUEST.RESPONSE.redirect('%s/manage_main' % url) REQUEST.RESPONSE.redirect('%s/manage_main' % url)
return id return id
def getImageInfo(data):
data = str(data)
size = len(data)
height = -1
width = -1
content_type = ''
# handle GIFs
if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
# Check to see if content_type is correct
content_type = 'image/gif'
w, h = struct.unpack("<HH", data[6:10])
width = int(w)
height = int(h)
# See PNG v1.2 spec (http://www.cdrom.com/pub/png/spec/)
# Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
# and finally the 4-byte width, height
elif ((size >= 24) and (data[:8] == '\211PNG\r\n\032\n')
and (data[12:16] == 'IHDR')):
content_type = 'image/png'
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[:8] == '\211PNG\r\n\032\n'):
# Check to see if we have the right content type
content_type = 'image/png'
w, h = struct.unpack(">LL", data[8:16])
width = int(w)
height = int(h)
# handle JPEGs
elif (size >= 2) and (data[:2] == '\377\330'):
content_type = 'image/jpeg'
jpeg = StringIO(data)
jpeg.read(2)
b = jpeg.read(1)
try:
while (b and ord(b) != 0xDA):
while (ord(b) != 0xFF): b = jpeg.read(1)
while (ord(b) == 0xFF): b = jpeg.read(1)
if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
jpeg.read(3)
h, w = struct.unpack(">HH", jpeg.read(4))
break
else:
jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
b = jpeg.read(1)
width = int(w)
height = int(h)
except: pass
return content_type, width, height
class Image(File): class Image(File):
"""Image objects can be GIF, PNG or JPEG and have the same methods """Image objects can be GIF, PNG or JPEG and have the same methods
as File objects. Images also have a string representation that as File objects. Images also have a string representation that
...@@ -503,68 +561,14 @@ class Image(File): ...@@ -503,68 +561,14 @@ class Image(File):
self.size=size self.size=size
self.data=data self.data=data
data=str(data)
ct, width, height = getImageInfo(data)
# handle GIFs if ct:
if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'): content_type = ct
# Check to see if content_type is correct if width >= 0 and height >= 0:
if content_type != 'image/gif': self.width = width
content_type = 'image/gif' self.height = height
w, h = struct.unpack("<HH", data[6:10])
self.width=str(int(w))
self.height=str(int(h))
# handle JPEGs
elif (size >= 2) and (data[:2] == '\377\330'):
jpeg=StringIO(data)
jpeg.read(2)
b=jpeg.read(1)
try:
while (b and ord(b) != 0xDA):
while (ord(b) != 0xFF): b = jpeg.read(1)
while (ord(b) == 0xFF): b = jpeg.read(1)
if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
jpeg.read(3)
h, w = struct.unpack(">HH", jpeg.read(4))
break
else:
jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
b = jpeg.read(1)
self.width=str(int(w))
self.height=str(int(h))
except: pass
# Check to see if we have the right content type
if content_type != 'image/jpeg':
content_type = 'image/jpeg'
# handle PNGs
# Someone says this is the right thing:
# Re: PNG v1.2 spec (http://www.cdrom.com/pub/png/spec/)
# Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
# and finally the 4-byte width, height
elif (size >= 24) and (data[:8] == '\211PNG\r\n\032\n') \
and (data[12:16] == 'IHDR'):
# Check to see if we have the right content type
if content_type != 'image/png':
content_type = 'image/png'
w, h = struct.unpack(">LL", data[16:24])
self.width=str(int(w))
self.height=str(int(h))
# But we had this before. I have no clue, so I'll keep both. :)
# Maybe this is for an older PNG version.
elif (size >= 16) and (data[:8] == '\x89PNG\r\n\x1a\n'):
# Check to see if we have the right content type
if content_type != 'image/png':
content_type = 'image/png'
w, h = struct.unpack(">LL", data[8:16])
self.width=str(int(w))
self.height=str(int(h))
# Now we should have the correct content type, or still None # Now we should have the correct content type, or still None
if content_type is not None: self.content_type = content_type if content_type is not None: self.content_type = content_type
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment