~ubuntu-branches/debian/squeeze/python-imaging/squeeze

« back to all changes in this revision

Viewing changes to PIL/PngImagePlugin.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-11-20 19:22:59 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20091120192259-n3iy0f17n5akogom
Tags: 1.1.7-1
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#
2
2
# The Python Imaging Library.
3
 
# $Id: PngImagePlugin.py 2203 2004-12-19 14:32:32Z fredrik $
 
3
# $Id$
4
4
#
5
5
# PNG support code
6
6
#
20
20
# 2004-08-31 fl   Do basic sanity check on chunk identifiers (0.8)
21
21
# 2004-09-20 fl   Added PngInfo chunk container
22
22
# 2004-12-18 fl   Added DPI read support (based on code by Niki Spahiev)
 
23
# 2008-08-13 fl   Added tRNS support for RGB images
 
24
# 2009-03-06 fl   Support for preserving ICC profiles (by Florian Hoech)
 
25
# 2009-03-08 fl   Added zTXT support (from Lowell Alleman)
 
26
# 2009-03-29 fl   Read interlaced PNG files (from Conrado Porto Lopes Gouvua)
23
27
#
24
 
# Copyright (c) 1997-2004 by Secret Labs AB
 
28
# Copyright (c) 1997-2009 by Secret Labs AB
25
29
# Copyright (c) 1996 by Fredrik Lundh
26
30
#
27
31
# See the README file for information on usage and redistribution.
28
32
#
29
33
 
30
 
__version__ = "0.8.2"
 
34
__version__ = "0.9"
31
35
 
32
36
import re, string
33
37
 
34
 
import Image, ImageFile, ImagePalette
 
38
import Image, ImageFile, ImagePalette, zlib
35
39
 
36
40
 
37
41
def i16(c):
170
174
 
171
175
        # local copies of Image attributes
172
176
        self.im_info = {}
 
177
        self.im_text = {}
173
178
        self.im_size = (0,0)
174
179
        self.im_mode = None
175
180
        self.im_tile = None
176
181
        self.im_palette = None
177
182
 
 
183
    def chunk_iCCP(self, pos, len):
 
184
 
 
185
        # ICC profile
 
186
        s = ImageFile._safe_read(self.fp, len)
 
187
        # according to PNG spec, the iCCP chunk contains:
 
188
        # Profile name  1-79 bytes (character string)
 
189
        # Null separator        1 byte (null character)
 
190
        # Compression method    1 byte (0)
 
191
        # Compressed profile    n bytes (zlib with deflate compression)
 
192
        i = string.find(s, chr(0))
 
193
        if Image.DEBUG:
 
194
            print "iCCP profile name", s[:i]
 
195
            print "Compression method", ord(s[i])
 
196
        comp_method = ord(s[i])
 
197
        if comp_method != 0:
 
198
            raise SyntaxError("Unknown compression method %s in iCCP chunk" % comp_method)
 
199
        try:
 
200
            icc_profile = zlib.decompress(s[i+2:])
 
201
        except zlib.error:
 
202
            icc_profile = None # FIXME
 
203
        self.im_info["icc_profile"] = icc_profile
 
204
        return s
 
205
 
178
206
    def chunk_IHDR(self, pos, len):
179
207
 
180
208
        # image header
220
248
                self.im_info["transparency"] = i
221
249
        elif self.im_mode == "L":
222
250
            self.im_info["transparency"] = i16(s)
 
251
        elif self.im_mode == "RGB":
 
252
            self.im_info["transparency"] = i16(s), i16(s[2:]), i16(s[4:])
223
253
        return s
224
254
 
225
255
    def chunk_gAMA(self, pos, len):
251
281
        except ValueError:
252
282
            k = s; v = "" # fallback for broken tEXt tags
253
283
        if k:
254
 
            self.im_info[k] = v
255
 
        return s
256
 
 
 
284
            self.im_info[k] = self.im_text[k] = v
 
285
        return s
 
286
 
 
287
    def chunk_zTXt(self, pos, len):
 
288
 
 
289
        # compressed text
 
290
        s = ImageFile._safe_read(self.fp, len)
 
291
        k, v = string.split(s, "\0", 1)
 
292
        comp_method = ord(v[0])
 
293
        if comp_method != 0:
 
294
            raise SyntaxError("Unknown compression method %s in zTXt chunk" % comp_method)
 
295
        import zlib
 
296
        self.im_info[k] = self.im_text[k] = zlib.decompress(v[1:])
 
297
        return s
257
298
 
258
299
# --------------------------------------------------------------------
259
300
# PNG reader
307
348
        self.mode = self.png.im_mode
308
349
        self.size = self.png.im_size
309
350
        self.info = self.png.im_info
 
351
        self.text = self.png.im_text # experimental
310
352
        self.tile = self.png.im_tile
311
353
 
312
354
        if self.png.im_palette:
334
376
        "internal: prepare to read PNG file"
335
377
 
336
378
        if self.info.get("interlace"):
337
 
            raise IOError("cannot read interlaced PNG files")
 
379
            self.decoderconfig = self.decoderconfig + (1,)
338
380
 
339
381
        ImageFile.ImageFile.load_prepare(self)
340
382
 
488
530
        elif im.mode == "L":
489
531
            transparency = max(0, min(65535, im.encoderinfo["transparency"]))
490
532
            chunk(fp, "tRNS", o16(transparency))
 
533
        elif im.mode == "RGB":
 
534
            red, green, blue = im.encoderinfo["transparency"]
 
535
            chunk(fp, "tRNS", o16(red) + o16(green) + o16(blue))
491
536
        else:
492
 
            raise IOError, "cannot use transparency for this mode"
 
537
            raise IOError("cannot use transparency for this mode")
493
538
 
494
539
    if 0:
495
540
        # FIXME: to be supported some day
507
552
        for cid, data in info.chunks:
508
553
            chunk(fp, cid, data)
509
554
 
 
555
    # ICC profile writing support -- 2008-06-06 Florian Hoech
 
556
    if im.info.has_key("icc_profile"):
 
557
        # ICC profile
 
558
        # according to PNG spec, the iCCP chunk contains:
 
559
        # Profile name  1-79 bytes (character string)
 
560
        # Null separator        1 byte (null character)
 
561
        # Compression method    1 byte (0)
 
562
        # Compressed profile    n bytes (zlib with deflate compression)
 
563
        try:
 
564
            import ICCProfile
 
565
            p = ICCProfile.ICCProfile(im.info["icc_profile"])
 
566
            name = p.tags.desc.get("ASCII", p.tags.desc.get("Unicode", p.tags.desc.get("Macintosh", p.tags.desc.get("en", {}).get("US", "ICC Profile")))).encode("latin1", "replace")[:79]
 
567
        except ImportError:
 
568
            name = "ICC Profile"
 
569
        data = name + "\0\0" + zlib.compress(im.info["icc_profile"])
 
570
        chunk(fp, "iCCP", data)
 
571
 
510
572
    ImageFile._save(im, _idat(fp, chunk), [("zip", (0,0)+im.size, 0, rawmode)])
511
573
 
512
574
    chunk(fp, "IEND", "")