FpxImagePlugin.py :  » GUI » Python-Image-Library » Imaging-1.1.7 » PIL » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » GUI » Python Image Library 
Python Image Library » Imaging 1.1.7 » PIL » FpxImagePlugin.py
#
# THIS IS WORK IN PROGRESS
#
# The Python Imaging Library.
# $Id$
#
# FlashPix support for PIL
#
# History:
# 97-01-25 fl   Created (reads uncompressed RGB images only)
#
# Copyright (c) Secret Labs AB 1997.
# Copyright (c) Fredrik Lundh 1997.
#
# See the README file for information on usage and redistribution.
#


__version__ = "0.1"


import Image, ImageFile
from OleFileIO import *


# we map from colour field tuples to (mode, rawmode) descriptors
MODES = {
    # opacity
    (0x00007ffe): ("A", "L"),
    # monochrome
    (0x00010000,): ("L", "L"),
    (0x00018000, 0x00017ffe): ("RGBA", "LA"),
    # photo YCC
    (0x00020000, 0x00020001, 0x00020002): ("RGB", "YCC;P"),
    (0x00028000, 0x00028001, 0x00028002, 0x00027ffe): ("RGBA", "YCCA;P"),
    # standard RGB (NIFRGB)
    (0x00030000, 0x00030001, 0x00030002): ("RGB","RGB"),
    (0x00038000, 0x00038001, 0x00038002, 0x00037ffe): ("RGBA","RGBA"),
}

#
# --------------------------------------------------------------------

def _accept(prefix):
    return prefix[:8] == MAGIC

##
# Image plugin for the FlashPix images.

class FpxImageFile(ImageFile.ImageFile):

    format = "FPX"
    format_description = "FlashPix"

    def _open(self):
        #
        # read the OLE directory and see if this is a likely
        # to be a FlashPix file

        try:
            self.ole = OleFileIO(self.fp)
        except IOError:
            raise SyntaxError, "not an FPX file; invalid OLE file"

        if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B":
            raise SyntaxError, "not an FPX file; bad root CLSID"

        self._open_index(1)

    def _open_index(self, index = 1):
        #
        # get the Image Contents Property Set

        prop = self.ole.getproperties([
            "Data Object Store %06d" % index,
            "\005Image Contents"
        ])

        # size (highest resolution)

        self.size = prop[0x1000002], prop[0x1000003]

        size = max(self.size)
        i = 1
        while size > 64:
            size = size / 2
            i = i + 1
        self.maxid = i - 1

        # mode.  instead of using a single field for this, flashpix
        # requires you to specify the mode for each channel in each
        # resolution subimage, and leaves it to the decoder to make
        # sure that they all match.  for now, we'll cheat and assume
        # that this is always the case.

        id = self.maxid << 16

        s = prop[0x2000002|id]

        colors = []
        for i in range(i32(s, 4)):
            # note: for now, we ignore the "uncalibrated" flag
            colors.append(i32(s, 8+i*4) & 0x7fffffff)

        self.mode, self.rawmode = MODES[tuple(colors)]

        # load JPEG tables, if any
        self.jpeg = {}
        for i in range(256):
            id = 0x3000001|(i << 16)
            if prop.has_key(id):
                self.jpeg[i] = prop[id]

        # print len(self.jpeg), "tables loaded"

        self._open_subimage(1, self.maxid)

    def _open_subimage(self, index = 1, subimage = 0):
        #
        # setup tile descriptors for a given subimage

        stream = [
            "Data Object Store %06d" % index,
            "Resolution %04d" % subimage,
            "Subimage 0000 Header"
        ]

        fp = self.ole.openstream(stream)

        # skip prefix
        p = fp.read(28)

        # header stream
        s = fp.read(36)

        size = i32(s, 4), i32(s, 8)
        tilecount = i32(s, 12)
        tilesize = i32(s, 16), i32(s, 20)
        channels = i32(s, 24)
        offset = i32(s, 28)
        length = i32(s, 32)

        # print size, self.mode, self.rawmode

        if size != self.size:
            raise IOError, "subimage mismatch"

        # get tile descriptors
        fp.seek(28 + offset)
        s = fp.read(i32(s, 12) * length)

        x = y = 0
        xsize, ysize = size
        xtile, ytile = tilesize
        self.tile = []

        for i in range(0, len(s), length):

            compression = i32(s, i+8)

            if compression == 0:
                self.tile.append(("raw", (x,y,x+xtile,y+ytile),
                        i32(s, i) + 28, (self.rawmode)))

            elif compression == 1:

                # FIXME: the fill decoder is not implemented
                self.tile.append(("fill", (x,y,x+xtile,y+ytile),
                        i32(s, i) + 28, (self.rawmode, s[12:16])))

            elif compression == 2:

                internal_color_conversion = ord(s[14])
                jpeg_tables = ord(s[15])
                rawmode = self.rawmode

                if internal_color_conversion:
                    # The image is stored as usual (usually YCbCr).
                    if rawmode == "RGBA":
                        # For "RGBA", data is stored as YCbCrA based on
                        # negative RGB. The following trick works around
                        # this problem :
                        jpegmode, rawmode = "YCbCrK", "CMYK"
                    else:
                        jpegmode = None # let the decoder decide

                else:
                    # The image is stored as defined by rawmode
                    jpegmode = rawmode

                self.tile.append(("jpeg", (x,y,x+xtile,y+ytile),
                        i32(s, i) + 28, (rawmode, jpegmode)))

                # FIXME: jpeg tables are tile dependent; the prefix
                # data must be placed in the tile descriptor itself!

                if jpeg_tables:
                    self.tile_prefix = self.jpeg[jpeg_tables]

            else:
                raise IOError, "unknown/invalid compression"

            x = x + xtile
            if x >= xsize:
                x, y = 0, y + ytile
                if y >= ysize:
                    break # isn't really required

        self.stream = stream
        self.fp = None

    def load(self):

        if not self.fp:
            self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"])

        ImageFile.ImageFile.load(self)

#
# --------------------------------------------------------------------

Image.register_open("FPX", FpxImageFile, _accept)

Image.register_extension("FPX", ".fpx")
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.