Index: setup.py
===================================================================
--- setup.py    (.../trunk/sK1) (revision 560)
+++ setup.py    (.../branches/hackontest/sK1)   (revision 560)
@@ -188,6 +188,14 @@
                       libraries=['freetype'],
                       extra_compile_args=["-Wall"])

+       pycms_src=src_path+'extentions/pycms/'
+       pycms_module = Extension('sk1.app.modules.pyCMSdll',
+                       define_macros = [('MAJOR_VERSION', '0'),
+                                               ('MINOR_VERSION', '1')],
+                       sources = [pycms_src+'pyCMSdll.c'],
+                       libraries=['lcms'],
+                       extra_compile_args=["-Wall"])
+
       pax_src=src_path+'extentions/pax/'
       pax_include_dirs=['/usr/include/cairo']
       pax_include_dirs.extend(tcl_include_dirs)
@@ -294,7 +302,7 @@

                       ext_modules = [filter_module, type1mod_module, skread_module,
                                               pstokenize_module, skmod_module, paxtkinter_module,
-                                               pax_module, tkpng_module, ft2_module])
+                                               pax_module, tkpng_module, ft2_module, pycms_module])



Index: src/app/plugins/Filters/sk1saver.py
===================================================================
--- src/app/plugins/Filters/sk1saver.py (.../trunk/sK1) (revision 560)
+++ src/app/plugins/Filters/sk1saver.py (.../branches/hackontest/sK1)   (revision 560)
@@ -537,7 +537,7 @@
                               from streamfilter import Base64Encode
                               write('bm(%d)\n' % id(image))
                               file = Base64Encode(self.file)
-                               image.image.save(file, 'PPM')
+                               image.orig_image.save(file, 'IM')
                               file.close()
                               write('-\n')
                       else:
Index: src/app/managers/colormanager.py
===================================================================
--- src/app/managers/colormanager.py    (.../trunk/sK1) (revision 560)
+++ src/app/managers/colormanager.py    (.../branches/hackontest/sK1)   (revision 560)
@@ -19,6 +19,8 @@
               import sys
               print "Cannot find Python binding for LittleCMS!"
               sys.exit(1)
+
+import pyCMS

class ColorManager:
       rgb_monitor=None
@@ -30,6 +32,7 @@
       hCMYK=None
       hMONITOR=None
       colors_pool=[]
+       image_pool=[]

       def __init__(self):
               self.refresh_profiles()
@@ -37,13 +40,23 @@
       def add_to_pool(self,color):
               self.colors_pool.append(color)

+       def add_to_image_pool(self,image):
+               self.image_pool.append(image)
+
       def remove_from_pool(self,color):
               self.colors_pool.remove(color)

+       def remove_from_image_pool(self,image):
+               self.image_pool.remove(image)
+
       def update(self):
               for color in self.colors_pool:
                       color.update()
+
+               for image in self.image_pool:
+                       image.update()

+
       def refresh_profiles(self):
               if app.config.preferences.user_rgb_profile and os.path.isfile(app.config.preferences.user_rgb_profile):
                       rgb_file=app.config.user_rgb_profile
@@ -160,7 +173,15 @@
               cmsCloseProfile(self.hRGB)
               cmsCloseProfile(self.hMONITOR)

+       def ImageRGBtoCMYK(self, image):
+               rgb_profile=os.path.join(app.config.sk_icc,app.config.preferences.default_rgb_profile)
+               cmyk_profile=os.path.join(app.config.sk_icc,app.config.preferences.default_cmyk_profile)
+               return pyCMS.profileToProfile(image, rgb_profile, cmyk_profile, outputMode = "CMYK")

+       def ImageCMYKtoRGB(self, image):
+               rgb_profile=os.path.join(app.config.sk_icc,app.config.preferences.default_rgb_profile)
+               cmyk_profile=os.path.join(app.config.sk_icc,app.config.preferences.default_cmyk_profile)
+               return pyCMS.profileToProfile(image, cmyk_profile, rgb_profile, outputMode = "RGB")



@@ -169,5 +190,4 @@



-

\ No newline at end of file
Index: src/app/managers/pyCMS.py
===================================================================
--- src/app/managers/pyCMS.py   (.../trunk/sK1) (revision 0)
+++ src/app/managers/pyCMS.py   (.../branches/hackontest/sK1)   (revision 560)
@@ -0,0 +1,825 @@
+"""
+pyCMS
+
+    a Python / PIL interface to the littleCMS ICC Color Management System
+    Copyright (C) 2002-2003 Kevin Cazabon
+    [email protected]
+    http://www.cazabon.com
+
+    pyCMS home page:  http://www.cazabon.com/pyCMS
+    littleCMS home page:  http://www.littlecms.com
+    (littleCMS is Copyright (C) 1998-2001 Marti Maria)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+    The pyCMS.py module provides a "clean" interface between Python/PIL and
+    pyCMSdll, taking care of some of the more complex handling of the direct
+    pyCMSdll functions, as well as error-checking and making sure that all
+    relevant data is kept together.
+
+    While it is possible to call pyCMSdll functions directly, it's not highly
+    recommended.
+
+
+    Version History:
+        0.0.2 alpha     Jan 6, 2002
+
+                        Added try/except statements arount type() checks of
+                        potential CObjects... Python won't let you use type()
+                        on them, and raises a TypeError (stupid, if you ask me!)
+
+                        Added buildProofTransformFromOpenProfiles() function.
+                        Additional fixes in DLL, see DLL code for details.
+
+        0.0.1 alpha     first public release, Dec. 26, 2002
+
+    Known to-do list with current version (of Python interface, not pyCMSdll):
+
+        none
+
+"""
+
+#######################################################################
+# version
+#######################################################################
+VERSION = "0.0.2 alpha"
+
+
+#######################################################################
+# imports
+#######################################################################
+import pyCMSdll
+import os
+import Image
+
+#######################################################################
+# constants
+#######################################################################
+TRUE =                          1
+FALSE =                         None
+
+INTENT_PERCEPTUAL =             0
+INTENT_RELATIVE_COLORIMETRIC =  1
+INTENT_SATURATION =             2
+INTENT_ABSOLUTE_COLORIMETRIC =  3
+
+DIRECTION_INPUT =               0
+DIRECTION_OUTPUT =              1
+DIRECTION_PROOF =               2
+
+#######################################################################
+# classes
+#######################################################################
+# classes are used for PyCMSTransform and PyCMSProfile so that data
+# such as input and output mode can follow the object after creation,
+# and be easily retrieved when needed.
+
+class PyCMSError(Exception):
+    pass
+
+class PyCMSTransform:
+    def __init__(self, transform = None, inputMode = None, outputMode = None):
+        self.transform = transform
+        self.inputMode = inputMode
+        self.outputMode = outputMode
+
+class PyCMSProfile:
+    def __init__(self, profile = None):
+        self.profile = profile
+
+
+#######################################################################
+# functions
+#######################################################################
+def versions ():
+    """
+    pyCMS.versions()
+
+    Returns a tuple of (pyCMSVersion, littleCMSVersion, pythonVersion,
+        PILVersion).
+
+    However, don't trust these values 100%, because they're currently
+    configured manually in pyCMSdll.c before building the DLL.
+    """
+
+    return pyCMSdll.versions()
+
+def about ():
+    """
+    pyCMS.about()
+
+    Returns a string containing information about pyCMSdll.dll, including
+    copyright and license information.
+    """
+
+    return pyCMSdll.about()
+
+def copyright ():
+    """
+    pyCMS.copyright()
+
+    Returns a string containing information about pyCMSdll.dll, including
+    copyright and license information.
+    """
+
+    return pyCMSdll.copyright()
+
+def profileToProfile (im, inputProfile, outputProfile, renderingIntent = INTENT_PERCEPTUAL, outputMode = None, inPlace = FALSE):
+    """
+    pyCMS.profileToProfile(im, inputProfile, outputProfile,
+        [renderingIntent], [outputMode], [inPlace])
+
+    Returns either None or a new PIL image object, depending on value of
+    inPlace (see below).
+
+    im = an open PIL image object (i.e. Image.new(...) or
+        Image.open(...), etc.)
+    inputProfile = string, as a valid filename path to the ICC input
+        profile you wish to use for this image
+    outputProfile = string, as a valid filename path to the ICC output
+        profile you wish to use for this image
+    renderingIntent = integer (0-3) specifying the rendering intent you
+        wish to use for the transform
+        INTENT_PERCEPTUAL =           0 (DEFAULT) (pyCMS.INTENT_PERCEPTUAL)
+        INTENT_RELATIVE_COLORIMETRIC =1 (pyCMS.INTENT_RELATIVE_COLORIMETRIC)
+        INTENT_SATURATION =           2 (pyCMS.INTENT_SATURATION)
+        INTENT_ABSOLUTE_COLORIMETRIC =3 (pyCMS.INTENT_ABSOLUTE_COLORIMETRIC)
+
+        see the pyCMS documentation for details on rendering intents and
+        what they do.
+    outputMode = a valid PIL mode for the output image (i.e. "RGB", "CMYK",
+        etc.).  Note: if rendering the image "inPlace", outputMode MUST be
+        the same mode as the input, or omitted completely.  If omitted, the
+        outputMode will be the same as the mode of the input image (im.mode)
+    inPlace = BOOL (1 = TRUE, None or 0 = FALSE).  If TRUE, the original
+        image is modified in-place, and None is returned.  If FALSE
+        (default), a new Image object is returned with the transform
+        applied.
+
+    If the input or output profiles specified are not valid filenames, a
+    PyCMSError will be raised.  If inPlace == TRUE and outputMode != im.mode,
+    a PyCMSError will be raised.  If an error occurs during application of
+    the profiles, a PyCMSError will be raised.  If outputMode is not a mode
+    supported by the outputProfile (or by pyCMS), a PyCMSError will be
+    raised.
+
+    This function applies an ICC transformation to im from inputProfile's
+    color space to outputProfile's color space using the specified rendering
+    intent to decide how to handle out-of-gamut colors.
+
+    OutputMode can be used to specify that a color mode conversion is to
+    be done using these profiles, but the specified profiles must be able
+    to handle that mode.  I.e., if converting im from RGB to CMYK using
+    profiles, the input profile must handle RGB data, and the output
+    profile must handle CMYK data.
+
+    """
+    if not os.path.isfile(inputProfile):
+        raise PyCMSError, "Invalid input profile path provided: %s" %inputProfile
+    if not os.path.isfile(outputProfile):
+        raise PyCMSError, "Invalid output profile path provided: %s" %outputProfile
+
+    if outputMode == None:
+        outputMode = im.mode
+
+    if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
+        raise PyCMSError, "renderingIntent must be an integer between 0 and 3"
+
+    if inPlace == TRUE and im.mode != outputMode:
+        raise PyCMSError, "Cannot transform image in place, im.mode and output mode are different (%s vs. %s)" %(im.mode, outputMode)
+
+    if inPlace == TRUE:
+        imOut = im
+    else:
+        imOut = Image.new(outputMode, im.size)
+
+    im.load() #make sure it's loaded, or it may not have a .im attribute!
+
+    result = pyCMSdll.profileToProfile(im.im.id, imOut.im.id, inputProfile, outputProfile, renderingIntent)
+
+    if result == 0:
+        if inPlace == TRUE:
+            return None
+        else:
+            return imOut
+
+    elif result == -1:
+        raise PyCMSError, "Error occurred in pyCMSdll.profileToProfile()"
+
+    else:
+        raise PyCMSError, result
+
+def getOpenProfile (profileFilename):
+    """
+    pyCMS.getOpenProfile(profileFilename)
+
+    Returns a PyCMSProfile class object.
+
+    profileFilename = string, as a valid filename path to the ICC profile
+        you wish to open
+
+    The PyCMSProfile object can be passed back into pyCMS for use in creating
+    transforms and such (as in pyCMS.buildTransformFromOpenProfiles()).
+
+    If profileFilename is not a vaild filename for an ICC profile, a
+    PyCMSError will be raised.
+
+    """
+    if not os.path.isfile(profileFilename):
+        raise PyCMSError, "Invalid profile path provided: %s" %profileFilename
+
+    result = pyCMSdll.getOpenProfile (profileFilename)
+
+    try:
+        if type(result) == type("string"):
+            raise PyCMSError, result
+    except TypeError:
+        pass
+
+    return PyCMSProfile(result)
+
+def buildTransform (inputProfile, outputProfile, inMode, outMode, renderingIntent = INTENT_PERCEPTUAL):
+    """
+    pyCMS.buildTransform(inputProfile, outputProfile, inMode, outMode,
+        [renderingIntent])
+
+    Returns a PyCMSTransform class object.
+
+    inputProfile = string, as a valid filename path to the ICC input
+        profile you wish to use for this transform
+    outputProfile = string, as a valid filename path to the ICC output
+        profile you wish to use for this transform
+    inMode = string, as a valid PIL mode that the appropriate profile also
+        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
+    outMode = string, as a valid PIL mode that the appropriate profile also
+        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
+    renderingIntent = integer (0-3) specifying the rendering intent you
+        wish to use for the transform
+        INTENT_PERCEPTUAL =           0 (DEFAULT) (pyCMS.INTENT_PERCEPTUAL)
+        INTENT_RELATIVE_COLORIMETRIC =1 (pyCMS.INTENT_RELATIVE_COLORIMETRIC)
+        INTENT_SATURATION =           2 (pyCMS.INTENT_SATURATION)
+        INTENT_ABSOLUTE_COLORIMETRIC =3 (pyCMS.INTENT_ABSOLUTE_COLORIMETRIC)
+        see the pyCMS documentation for details on rendering intents and
+        what they do.
+
+    If the input or output profiles specified are not valid filenames, a
+    PyCMSError will be raised.  If an error occurs during creation of the
+    transform, a PyCMSError will be raised.
+
+    If inMode or outMode are not a mode supported by the outputProfile (or
+    by pyCMS), a PyCMSError will be raised.
+
+    This function builds and returns an ICC transform from the inputProfile
+    to the outputProfile using the renderingIntent to determine what to do
+    with out-of-gamut colors.  It will ONLY work for converting images that
+    are in inMode to images that are in outMode color format (PIL mode,
+    i.e. "RGB", "RGBA", "CMYK", etc.).
+
+    Building the transform is a fair part of the overhead in
+    pyCMS.profileToProfile(), so if you're planning on converting multiple
+    images using the same input/output settings, this can save you time.
+    Once you have a transform object, it can be used with
+    pyCMS.applyProfile() to convert images without the need to re-compute
+    the lookup table for the transform.
+
+    The reason pyCMS returns a class object rather than a handle directly
+    to the transform is that it needs to keep track of the PIL input/output
+    modes that the transform is meant for.  These attributes are stored in
+    the "inMode" and "outMode" attributes of the object (which can be
+    manually overridden if you really want to, but I don't know of any
+    time that would be of use, or would even work).
+
+    """
+    if not os.path.isfile(inputProfile):
+        raise PyCMSError, "Invalid input profile path provided: %s" %inputProfile
+    if not os.path.isfile(outputProfile):
+        raise PyCMSError, "Invalid output profile path provided: %s" %outputProfile
+
+    if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
+        raise PyCMSError, "renderingIntent must be an integer between 0 and 3"
+
+    result = pyCMSdll.buildTransform (inputProfile, outputProfile, inMode, outMode, renderingIntent)
+
+    try:
+        if type(result) == type("string"):
+            raise PyCMSError, result
+    except TypeError:
+        pass
+
+    return PyCMSTransform(result, inMode, outMode)
+
+def buildProofTransform (inputProfile, outputProfile, displayProfile, inMode, outMode, renderingIntent = INTENT_PERCEPTUAL, displayRenderingIntent = INTENT_PERCEPTUAL):
+    """
+    pyCMS.buildProofTransform(inputProfile, outputProfile, displayProfile,
+        inMode, outMode, [renderingIntent], [displayRenderingIntent])
+
+    Returns a PyCMSTransform class object.
+
+    inputProfile = string, as a valid filename path to the ICC input
+        profile you wish to use for this transform
+    outputProfile = string, as a valid filename path to the ICC output
+        profile you wish to use for this transform
+    displayProfile = string, as a valid filename path to the ICC display
+        (monitor, usually) profile you wish to use for this transform
+    inMode = string, as a valid PIL mode that the appropriate profile also
+        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
+    outMode = string, as a valid PIL mode that the appropriate profile also
+        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
+    renderingIntent = integer (0-3) specifying the rendering intent you
+        wish to use for the input->output (simulated) transform
+        INTENT_PERCEPTUAL =           0 (DEFAULT) (pyCMS.INTENT_PERCEPTUAL)
+        INTENT_RELATIVE_COLORIMETRIC =1 (pyCMS.INTENT_RELATIVE_COLORIMETRIC)
+        INTENT_SATURATION =           2 (pyCMS.INTENT_SATURATION)
+        INTENT_ABSOLUTE_COLORIMETRIC =3 (pyCMS.INTENT_ABSOLUTE_COLORIMETRIC)
+        see the pyCMS documentation for details on rendering intents and
+        what they do.
+    displayRenderingIntent = integer (0-3) specifying the rendering intent
+        you wish to use for (input/output simulation)->display transform
+        INTENT_PERCEPTUAL =           0 (DEFAULT) (pyCMS.INTENT_PERCEPTUAL)
+        INTENT_RELATIVE_COLORIMETRIC =1 (pyCMS.INTENT_RELATIVE_COLORIMETRIC)
+        INTENT_SATURATION =           2 (pyCMS.INTENT_SATURATION)
+        INTENT_ABSOLUTE_COLORIMETRIC =3 (pyCMS.INTENT_ABSOLUTE_COLORIMETRIC)
+        see the pyCMS documentation for details on rendering intents and
+        what they do.
+
+    If the input, output, or display profiles specified are not valid
+    filenames, a PyCMSError will be raised.
+
+    If an error occurs during creation of the transform, a PyCMSError will
+    be raised.
+
+    If inMode or outMode are not a mode supported by the outputProfile
+    (or by pyCMS), a PyCMSError will be raised.
+
+    This function builds and returns an ICC transform from the inputProfile
+    to the displayProfile, but tries to simulate the result that would be
+    obtained on the outputProfile device using renderingIntent and
+    displayRenderingIntent to determine what to do with out-of-gamut
+    colors.  This is known as "soft-proofing".  It will ONLY work for
+    converting images that are in inMode to images that are in outMode
+    color format (PIL mode, i.e. "RGB", "RGBA", "CMYK", etc.).
+
+    Usage of the resulting transform object is exactly the same as with
+    pyCMS.buildTransform().
+
+    Proof profiling is generally used when using a "proof" device to get a
+    good idea of what the final printed/displayed image would look like on
+    the outputProfile device when it's quicker and easier to use the
+    display device for judging color.  Generally, this means that
+    displayDevice is a monitor, or a dye-sub printer (etc.), and the output
+    device is something more expensive, complicated, or time consuming
+    (making it difficult to make a real print for color judgement purposes).
+
+    Soft-proofing basically functions by limiting the color gamut on the
+    display device to the gamut availabile on the output device.  However,
+    when the final output device has a much wider gamut than the display
+    device, you may obtain marginal results.
+
+    """
+    if not os.path.isfile(inputProfile):
+        raise PyCMSError, "Invalid input profile path provided: %s" %inputProfile
+    if not os.path.isfile(outputProfile):
+        raise PyCMSError, "Invalid output profile path provided: %s" %outputProfile
+    if not os.path.isfile(displayProfile):
+        raise PyCMSError, "Invalid display profile path provided: %s" %displayProfile
+
+    if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
+        raise PyCMSError, "renderingIntent must be an integer between 0 and 3"
+
+    result = pyCMSdll.buildProofTransform (inputProfile, outputProfile, displayProfile, inMode, outMode, renderingIntent, displayRenderingIntent)
+
+    try:
+        if type(result) == type("string"):
+            raise PyCMSError, result
+    except TypeError:
+        pass
+
+    return PyCMSTransform(result, inMode, outMode)
+
+def buildTransformFromOpenProfiles (inputProfile, outputProfile, inMode, outMode, renderingIntent = INTENT_PERCEPTUAL):
+    """
+    pyCMS.buildTransformFromOpenProfiles(inputProfile, outputProfile,
+        inMode, outMode, [renderingIntent])
+
+    Returns a PyCMSTransform class object
+
+    inputProfile = a valid PyCMSProfile class object
+    outputProfile = a valid PyCMSProfile class object
+    inMode = string, as a valid PIL mode that the appropriate profile also
+        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
+    outMode = string, as a valid PIL mode that the appropriate profile also
+        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
+    renderingIntent = integer (0-3) specifying the rendering intent you
+        wish to use for the transform
+        INTENT_PERCEPTUAL =           0 (DEFAULT) (pyCMS.INTENT_PERCEPTUAL)
+        INTENT_RELATIVE_COLORIMETRIC =1 (pyCMS.INTENT_RELATIVE_COLORIMETRIC)
+        INTENT_SATURATION =           2 (pyCMS.INTENT_SATURATION)
+        INTENT_ABSOLUTE_COLORIMETRIC =3 (pyCMS.INTENT_ABSOLUTE_COLORIMETRIC)
+        see the pyCMS documentation for details on rendering intents and
+        what they do.
+
+    This function operates exactly the same as pyCMS.buildTransform()
+    except that the inputProfile and outputProfile arguments must be valid
+    PyCMSProfile objects rather than filenames.  Use this function to
+    create pre-calculated transforms from open PyCMSProfiles (such as
+    profiles created on-the-fly using pyCMS.createProfile(), or [in the
+    future] profiles extracted from image files.
+
+    """
+
+    if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
+        raise PyCMSError, "renderingIntent must be an integer between 0 and 3"
+
+    result = pyCMSdll.buildTransformFromOpenProfiles (inputProfile.profile, outputProfile.profile, inMode, outMode, renderingIntent)
+
+    try:
+        if type(result) == type("string"):
+            raise PyCMSError, result
+    except TypeError:
+        pass
+
+    return PyCMSTransform(result, inMode, outMode)
+
+def buildProofTransformFromOpenProfiles (inputProfile, outputProfile, displayProfile, inMode, outMode, renderingIntent = INTENT_PERCEPTUAL, displayRenderingIntent = INTENT_PERCEPTUAL):
+    """
+    pyCMS.buildProofTransformFromOpenProfiles(inputProfile, outputProfile,
+        displayProfile, inMode, outMode, [renderingIntent],
+        [displayRenderingIntent])
+
+    Returns a PyCMSTransform class object
+
+    inputProfile = a valid PyCMSProfile class object
+    outputProfile = a valid PyCMSProfile class object
+    displayProfile = a valid PyCMSProfile class object
+    inMode = string, as a valid PIL mode that the appropriate profile also
+        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
+    outMode = string, as a valid PIL mode that the appropriate profile also
+        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
+    renderingIntent = integer (0-3) specifying the rendering intent you
+        wish to use for the transform
+        INTENT_PERCEPTUAL =           0 (DEFAULT) (pyCMS.INTENT_PERCEPTUAL)
+        INTENT_RELATIVE_COLORIMETRIC =1 (pyCMS.INTENT_RELATIVE_COLORIMETRIC)
+        INTENT_SATURATION =           2 (pyCMS.INTENT_SATURATION)
+        INTENT_ABSOLUTE_COLORIMETRIC =3 (pyCMS.INTENT_ABSOLUTE_COLORIMETRIC)
+        see the pyCMS documentation for details on rendering intents and
+        what they do.
+    displayRenderingIntent = integer (0-3) specifying the rendering intent you
+        wish to use for the transform
+        INTENT_PERCEPTUAL =           0 (DEFAULT) (pyCMS.INTENT_PERCEPTUAL)
+        INTENT_RELATIVE_COLORIMETRIC =1 (pyCMS.INTENT_RELATIVE_COLORIMETRIC)
+        INTENT_SATURATION =           2 (pyCMS.INTENT_SATURATION)
+        INTENT_ABSOLUTE_COLORIMETRIC =3 (pyCMS.INTENT_ABSOLUTE_COLORIMETRIC)
+        see the pyCMS documentation for details on rendering intents and
+        what they do.
+    This function operates exactly the same as pyCMS.buildProofTransform()
+    except that the profile arguments must be valid
+    PyCMSProfile objects rather than filenames.  Use this function to
+    create pre-calculated proof transforms from open PyCMSProfiles (such as
+    profiles created on-the-fly using pyCMS.createProfile(), or [in the
+    future] profiles extracted from image files.
+
+    """
+
+    if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3) or type(displayRenderingIntent) != type(1) or not (0 <= displayRenderingIntent <=3):
+        raise PyCMSError, "renderingIntent must be an integer between 0 and 3"
+
+    result = pyCMSdll.buildProofTransformFromOpenProfiles (inputProfile.profile, outputProfile.profile, displayProfile.profile, inMode, outMode, renderingIntent, displayRenderingIntent)
+
+    try:
+        if type(result) == type("string"):
+            raise PyCMSError, result
+
+    except TypeError:
+        pass
+
+    return PyCMSTransform(result, inMode, outMode)
+
+def applyTransform (im, transform, inPlace = FALSE):
+    """
+    pyCMS.applyTransform(im, transform, [inPlace])
+
+    Returns either None, or a new PIL Image object, depending on the value
+        of inPlace (see below)
+
+    im = a PIL Image object, and im.mode must be the same as the inMode
+        supported by the transform.
+    transform = a valid PyCMSTransform class object
+    inPlace = BOOL (1 == TRUE, 0 or None == FALSE).  If TRUE, im is
+        modified in place and None is returned, if FALSE, a new Image
+        object with the transform applied is returned (and im is not
+        changed).  The default is FALSE.
+
+    If im.mode != transform.inMode, a PyCMSError is raised.
+
+    If inPlace == TRUE and transform.inMode != transform.outMode, a
+    PyCMSError is raised.
+
+    If im.mode, transfer.inMode, or transfer.outMode is not supported by
+    pyCMSdll or the profiles you used for the transform, a PyCMSError is
+    raised.
+
+    If an error occurs while the transform is being applied, a PyCMSError
+    is raised.
+
+    This function applies a pre-calculated transform (from
+    pyCMS.buildTransform() or pyCMS.buildTransformFromOpenProfiles()) to an
+    image.  The transform can be used for multiple images, saving
+    considerable calcuation time if doing the same conversion multiple times.
+
+    If you want to modify im in-place instead of receiving a new image as
+    the return value, set inPlace to TRUE.  This can only be done if
+    transform.inMode and transform.outMode are the same, because we can't
+    change the mode in-place (the buffer sizes for some modes are
+    different).  The  default behavior is to return a new Image object of
+    the same dimensions in mode transform.outMode.
+
+    """
+    if im.mode != transform.inputMode:
+        raise PyCMSError, "Image mode does not match profile input mode (%s vs %s)" %(im.mode, transform.inMode)
+
+    if inPlace == TRUE:
+        if transform.inputMode != transform.outputMode:
+            raise PyCMSError, "Cannot transform image in place, input mode and output mode are different (%s vs. %s)" %(transform.inMode, transform.outMode)
+        imOut = im
+    else:
+        imOut = Image.new(transform.outputMode, im.size)
+
+    im.load() #make sure it's loaded, or it may not have an .im attribute!
+
+    result = pyCMSdll.applyTransform (im.im.id, imOut.im.id, transform.transform)
+
+    if result == 0:
+        if inPlace == TRUE:
+            return None
+        else:
+            return imOut
+
+    elif result == -1:
+        raise PyCMSError, "Error occurred in pyCMSdll.applyTransform()"
+
+    else:
+        raise PyCMSError, result
+
+def createProfile (colorSpace, colorTemp = -1):
+    """
+    pyCMS.createProfile(colorSpace, [colorTemp])
+
+    Returns a PyCMSProfile class object
+
+    colorSpace = string, the color space of the profile you wish to create.
+        Currently only "LAB", "XYZ", and "sRGB" are supported.
+    colorTemp = positive integer for the white point for the profile, in
+        degrees Kelvin (i.e. 5000, 6500, 9600, etc.).  The default is for
+        D50 illuminant if omitted (5000k).  colorTemp is ONLY applied to
+        LAB profiles, and is ignored for XYZ and sRGB.
+
+    If colorSpace not in ["LAB", "XYZ", "sRGB"], a PyCMSError is raised
+
+    If using LAB and colorTemp != a positive integer, a PyCMSError is raised.
+
+    If an error occurs while creating the profile, a PyCMSError is raised.
+
+    Use this function to create common profiles on-the-fly instead of
+    having to supply a profile on disk and knowing the path to it.  It
+    returns a normal PyCMSProfile object that can be passed to
+    pyCMS.buildTransformFromOpenProfiles() to create a transform to apply
+    to images.
+
+    """
+    if colorSpace not in ["LAB", "XYZ", "sRGB"]:
+        raise PyCMSError, "Color space not supported for on-the-fly profile creation (%s)" %colorSpace
+
+    if colorSpace == "LAB":
+        if type(colorTemp) == type(5000.0):
+            colorTemp = int(colorTemp + 0.5)
+        if type (colorTemp) != type (5000):
+            raise PyCMSError, "Color temperature must be a positive integer, \"%s\" not valid" %colorTemp
+
+    result = pyCMSdll.createProfile (colorSpace, colorTemp)
+
+    try:
+        if type(result) == type("string"):
+            raise PyCMSError, result
+
+        else:
+            return PyCMSProfile(result)
+    except TypeError:
+        # you can't use type() on a PyCObject... argh!
+        return PyCMSProfile(result)
+
+def getProfileName (profile):
+    """
+    pyCMS.getProfileName(profile)
+
+    Returns a string containing the internal name of the profile as stored
+        in an ICC tag.
+
+    profile = EITHER a valid PyCMSProfile object, OR a string of the
+        filename of an ICC profile.
+
+    If profile isn't a valid PyCMSProfile object or filename to a profile,
+    a PyCMSError is raised If an error occurs while trying to obtain the
+    name tag, a PyCMSError is raised.
+
+    Use this function to obtain the INTERNAL name of the profile (stored
+    in an ICC tag in the profile itself), usually the one used when the
+    profile was originally created.  Sometimes this tag also contains
+    additional information supplied by the creator.
+
+    """
+    try:
+        if type(profile) != type("string"):
+            profile = profile.profile
+        elif (not os.path.isfile(profile)):
+            raise PyCMSError, "Invalid  profile path provided: %s" %profile
+
+    except TypeError:
+        # you can't use type() on a PyCObject... argh!
+        profile = profile.profile
+
+    result = pyCMSdll.getProfileName(profile)
+
+    if len(result) > 7 and result[:7] == "ERROR: ":
+        raise PyCMSError, result
+
+    else:
+        return result
+
+def getProfileInfo (profile):
+    """
+    pyCMS.getProfileInfo(profile)
+
+    Returns a string containing the internal profile information stored in
+        an ICC tag.
+
+    profile = EITHER a valid PyCMSProfile object, OR a string of the
+        filename of an ICC profile.
+
+    If profile isn't a valid PyCMSProfile object or filename to a profile,
+    a PyCMSError is raised.
+
+    If an error occurs while trying to obtain the info tag, a PyCMSError
+    is raised
+
+    Use this function to obtain the information stored in the profile's
+    info tag.  This often contains details about the profile, and how it
+    was created, as supplied by the creator.
+
+    """
+    try:
+        if type(profile) != type("string"):
+            profile = profile.profile
+        elif (not os.path.isfile(profile)):
+            raise PyCMSError, "Invalid  profile path provided: %s" %profile
+
+    except TypeError:
+        # you can't use type() on a PyCObject... argh!
+        profile = profile.profile
+
+    result = pyCMSdll.getProfileInfo(profile)
+
+    if len(result) > 7 and result[:7] == "ERROR: ":
+        raise PyCMSError, result
+
+    else:
+        return result
+
+def getDefaultIntent (profile):
+    """
+    pyCMS.getDefaultIntent(profile)
+
+    Returns integer 0-3 specifying the default rendering intent for this
+        profile.
+        INTENT_PERCEPTUAL =           0 (DEFAULT) (pyCMS.INTENT_PERCEPTUAL)
+        INTENT_RELATIVE_COLORIMETRIC =1 (pyCMS.INTENT_RELATIVE_COLORIMETRIC)
+        INTENT_SATURATION =           2 (pyCMS.INTENT_SATURATION)
+        INTENT_ABSOLUTE_COLORIMETRIC =3 (pyCMS.INTENT_ABSOLUTE_COLORIMETRIC)
+        see the pyCMS documentation for details on rendering intents and
+        what they do.
+
+    profile = EITHER a valid PyCMSProfile object, OR a string of the
+        filename of an ICC profile.
+
+    If profile isn't a valid PyCMSProfile object or filename to a profile,
+    a PyCMSError is raised.
+
+    If an error occurs while trying to obtain the default intent, a
+    PyCMSError is raised.
+
+    Use this function to determine the default (and usually best optomized)
+    rendering intent for this profile.  Most profiles support multiple
+    rendering intents, but are intended mostly for one type of conversion.
+    If you wish to use a different intent than returned, use
+    pyCMS.isIntentSupported() to verify it will work first.
+    """
+    try:
+        if type(profile) != type("string"):
+            profile = profile.profile
+        elif (not os.path.isfile(profile)):
+            raise PyCMSError, "Invalid  profile path provided: %s" %profile
+
+    except TypeError:
+        # you can't use type() on a PyCObject... argh!
+        profile = profile.profile
+
+    result = pyCMSdll.getDefaultIntent(profile)
+
+    try:
+        if type(result) == type("string"):
+            raise PyCMSError, result
+        else:
+            return result
+
+    except TypeError:
+        # you can't use type() on a PyCObject... argh!
+        return result
+
+def isIntentSupported (profile, intent, direction):
+    """
+    pyCMS.isIntentSupported(profile, intent, direction)
+
+    Returns 1 if the intent/direction are supported, -1 if they are not.
+
+    profile = EITHER a valid PyCMSProfile object, OR a string of the
+        filename of an ICC profile.
+    intent = integer (0-3) specifying the rendering intent you wish to use
+        with this profile
+        INTENT_PERCEPTUAL =           0 (DEFAULT) (pyCMS.INTENT_PERCEPTUAL)
+        INTENT_RELATIVE_COLORIMETRIC =1 (pyCMS.INTENT_RELATIVE_COLORIMETRIC)
+        INTENT_SATURATION =           2 (pyCMS.INTENT_SATURATION)
+        INTENT_ABSOLUTE_COLORIMETRIC =3 (pyCMS.INTENT_ABSOLUTE_COLORIMETRIC)
+        see the pyCMS documentation for details on rendering intents and
+        what they do.
+    direction = integer specifing if the profile is to be used for input,
+        output, or display/proof
+        INPUT =               0 (or use pyCMS.DIRECTION_INPUT)
+        OUTPUT =              1 (or use pyCMS.DIRECTION_OUTPUT)
+        PROOF (or display) =  2 (or use pyCMS.DIRECTION_PROOF)
+
+    Use this function to verify that you can use your desired
+    renderingIntent with profile, and that profile can be used for the
+    input/output/display profile as you desire.
+
+    Some profiles are created specifically for one "direction", can cannot
+    be used for others.  Some profiles can only be used for certain
+    rendering intents... so it's best to either verify this before trying
+    to create a transform with them (using this function), or catch the
+    potential PyCMSError that will occur if they don't support the modes
+    you select.
+
+    """
+    try:
+        if type(profile) != type("string"):
+            profile = profile.profile
+        elif (not os.path.isfile(profile)):
+            raise PyCMSError, "Invalid  profile path provided: %s" %profile
+
+    except TypeError:
+        # you can't use type() on a PyCObject... argh!
+        profile = profile.profile
+
+    result = pyCMSdll.isIntentSupported(profile, intent, direction)
+
+    try:
+        if type(result) == type("string"):
+            raise PyCMSError, result
+
+        else:
+            return result
+
+    except TypeError:
+        # you can't use type() on a PyCObject... argh!
+        return result
+
+if __name__ == "__main__":
+    # create a cheap manual from the __doc__ strings for the functions above
+
+    import pyCMS
+    import string
+    print __doc__
+
+    for f in dir(pyCMS):
+        print "="*80
+        print "%s" %f
+
+        try:
+            exec ("doc = pyCMS.%s.__doc__" %(f))
+            if string.find(doc, "pyCMS") >= 0:
+                # so we don't get the __doc__ string for imported modules
+                print doc
+        except AttributeError:
+            pass
+
\ No newline at end of file
Index: src/app/Graphics/document.py
===================================================================
--- src/app/Graphics/document.py        (.../trunk/sK1) (revision 560)
+++ src/app/Graphics/document.py        (.../branches/hackontest/sK1)   (revision 560)
@@ -1973,18 +1973,19 @@
               return self.selection.GetObjectMethod(aclass, method)

       def CurrentObjectCompatible(self, aclass):
-               obj = self.CurrentObject()
+               obj = self.CurrentObject()
               if obj is not None:
                       if aclass.is_Editor:
-                               return isinstance(obj, aclass.EditedClass)
+                               return obj.__class__.__name__== aclass.EditedClass.__name__
                       else:
-                               return isinstance(obj, aclass)
+                               return obj.__class__.__name__== aclass.__name__
               return 0

       # XXX the following methods for blend groups, path text, clones and
       # bezier objects should perhaps be implemented in their respective
       # modules (and then somehow grafted onto the document class?)

+
       def CanBlend(self):
               info = self.selection.GetInfo()
               if len(info) == 2:
@@ -2210,8 +2211,79 @@
                                       self.abort_transaction()
                       finally:
                               self.end_transaction()
+       #
+       #  IMAGES MANAGMENT
+       #
+
+############
+       def CanBeRGB(self):
+               from image import RGB_IMAGE, RGBA_IMAGE
+               obj = self.CurrentObject()
+               if obj:
+                       if obj.is_Image:
+                               if obj.data.image_mode==RGB_IMAGE or obj.data.image_mode==RGBA_IMAGE:
+                                       return 0
+                               else:
+                                       return 1
+               return 0

+       def CanBeCMYK(self):
+               from image import CMYK_IMAGE
+               obj = self.CurrentObject()
+               if obj:
+                       if obj.is_Image and not obj.data.image_mode==CMYK_IMAGE:
+                                       return 1
+               return 0

+       def CanBeGrayscale(self):
+               from image import GRAYSCALE_IMAGE
+               obj = self.CurrentObject()
+               if obj:
+                       if obj.is_Image and not obj.data.image_mode==GRAYSCALE_IMAGE:
+                                       return 1
+               return 0
+
+       def CanBeBW(self):
+               from image import BW_IMAGE
+               obj = self.CurrentObject()
+               if obj:
+                       if obj.is_Image and not obj.data.image_mode==BW_IMAGE:
+                                       return 1
+               return 0
+
+       def ConvertImage(self, mode):
+               obj = self.CurrentObject()
+               self.CallObjectMethod(obj.__class__, _("Convert Image"), 'Convert', mode)
+#              obj.Convert(mode)
+               self.SelectNone()
+               self.SelectObject(obj)
+
+       def CanEmbed(self):
+               obj = self.CurrentObject()
+               if obj:
+                       if obj.is_Image and obj.CanEmbed():
+                               return obj.CanEmbed()
+               return 0
+
+       def Embed(self):
+               obj = self.CurrentObject()
+               obj.Embed()
+               self.SelectNone()
+               self.SelectObject(obj)
+
+       def CanInvert(self):
+               obj = self.CurrentObject()
+               if obj:
+                       if obj.is_Image and obj.IsEmbedded():
+                               return 1
+               return 0
+
+       def Invert(self):
+               obj = self.CurrentObject()
+               self.CallObjectMethod(obj.__class__, _("Invert Image"), 'InvertImage')
+               app.mw.canvas.ForceRedraw()
+
+
       #
       #  PAGES MANAGMENT
       #
Index: src/app/Graphics/color.py
===================================================================
--- src/app/Graphics/color.py   (.../trunk/sK1) (revision 560)
+++ src/app/Graphics/color.py   (.../branches/hackontest/sK1)   (revision 560)
@@ -98,7 +98,6 @@
       def __del__(self):
               if colormanager is not None:
                       colormanager.remove_from_pool(self)
-                       print "REMOVED"

       def getScreenColor(self):
               pass
Index: src/app/Graphics/image.py
===================================================================
--- src/app/Graphics/image.py   (.../trunk/sK1) (revision 560)
+++ src/app/Graphics/image.py   (.../branches/hackontest/sK1)   (revision 560)
@@ -21,41 +21,85 @@
# memory.
#

-import os
+import os, app
from types import StringType

import PIL.Image, PIL.ImageChops

-from app import _, RegisterCommands
+from app import _, RegisterCommands, colormanager
from app.UI.command import AddCmd

from external import ExternalData, get_cached, ExternalGraphics

+RGB_IMAGE=_('RGB')
+RGBA_IMAGE=_('RGBA')
+GRAYSCALE_IMAGE=_('Greyscale')
+CMYK_IMAGE=_('CMYK')
+BW_IMAGE=_('Monochrome')
+UNSUPPORTED=_('UNSUPPORTED')
+
class ImageData(ExternalData):

       attributes = {'mode':0, 'size':0, 'im':0, 'info':0}
+       cached =0
+
+       def __init__(self, image, filename = '', cache = 1):
+               self.orig_image=image.copy()

-       def __init__(self, image, filename = '', cache = 1):
-               # convert image to mode 'L' or 'RGB' if necessary
-               if image.mode not in ('RGB', 'RGBA', 'L'):
-                       if image.mode == '1':
-                               mode = 'L'
-                       else:
-                               mode = 'RGB'
-                       image = image.convert(mode)
+               if image.mode=='1':
+                       self.image_mode=BW_IMAGE
+               elif image.mode=='L':
+                       self.image_mode=GRAYSCALE_IMAGE
+               elif image.mode=='RGB':
+                       self.image_mode=RGB_IMAGE
+               elif image.mode=='RGBA':
+                       self.image_mode=RGBA_IMAGE
+               elif image.mode=='CMYK':
+                       self.image_mode=CMYK_IMAGE
+                       colormanager.add_to_image_pool(self)
+                       self.cached=1
               else:
+                       self.image_mode=UNSUPPORTED
+
+               if image.mode not in ('RGB', 'RGBA'):
+                       if image.mode=='CMYK':
+                               if app.config.preferences.use_cms:
+                                       self.image=colormanager.ImageCMYKtoRGB(image)
+                               else:
+                                       self.image = image.convert('RGB')
+                       else:
+                               self.image = image.convert('RGB')
+               else:
                       image.load()
-               self.image = image
+                       self.image = image
+
+               if self.image_mode==UNSUPPORTED:
+                       self.orig_image=self.image.copy()
+                       self.image_mode=RGB_IMAGE
+
               ExternalData.__init__(self, filename, cache)
+
+       def __del__(self):
+               if self.cached and colormanager is not None:
+                       colormanager.remove_from_image_pool(self)

       def __getattr__(self, attr):
               if self.attributes.has_key(attr):
                       return getattr(self.image, attr)
               raise AttributeError, attr
+
+       def update(self):
+               if app.config.preferences.use_cms:
+                       if self.image_mode==CMYK_IMAGE:
+                               self.image=colormanager.ImageCMYKtoRGB(self.orig_image)
+                       else:
+                               self.image = self.orig_image.convert('RGB')
+               else:
+                       self.image = self.orig_image.convert('RGB')

       def AsEmbedded(self):
               if self.filename:
-                       return ImageData(self.image)
+                       return ImageData(self.orig_image)
               else:
                       return self

@@ -66,16 +110,23 @@
               return self.size

       def Image(self):
-               return self.image
+               print 'Image provided'
+               return self.orig_image

       def Convert(self, mode):
-               if mode != self.image.mode:
-                       return ImageData(self.image.convert(mode))
+               if mode != self.orig_image.mode:
+                       if app.config.preferences.use_cms:
+                               if mode=='RGB'and self.orig_image.mode=='CMYK':
+                                       return ImageData(colormanager.ImageCMYKtoRGB(self.orig_image))
+                               if mode=='CMYK'and self.orig_image.mode=='RGB':
+                                       return ImageData(colormanager.ImageRGBtoCMYK(self.orig_image))
+                       else:
+                               return ImageData(self.orig_image.convert(mode))
               else:
                       return self

       def Invert(self):
-               return ImageData(PIL.ImageChops.invert(self.image))
+               return ImageData(PIL.ImageChops.invert(self.orig_image))



@@ -96,30 +147,25 @@

       commands = ExternalGraphics.commands[:]

-       def __init__(self, image = None, imagefile = '', trafo = None,
-                                       duplicate = None):
+       def __init__(self, image = None, imagefile = '', trafo = None, duplicate = None):
               if duplicate is None:
                       if not image:
                               if not imagefile:
                                       raise ValueError, 'Image must be instantiated with'\
                                                                               ' either image or imagefile'
                               image = load_image(imagefile)
-               ExternalGraphics.__init__(self, image, trafo,
-                                                                       duplicate = duplicate)
+               ExternalGraphics.__init__(self, image, trafo, duplicate = duplicate)
+               self.Embed()

       def DrawShape(self, device, rect = None, clip = 0):
               device.DrawImage(self.data, self.trafo, clip)

       def Info(self):
+               mode=self.data.image_mode
               width, height = self.data.Size()
               x, y = self.trafo.offset()
-               if self.IsEmbedded():
-                       return _("Embedded Image %(width)d x %(height)d "
-                                               "at (%(x)d, %(y)d)") % locals()
-               else:
-                       filename = os.path.basename(self.data.Filename())
-                       return _("Linked Image `%(filename)s' %(width)d x %(height)d "
-                                               "at (%(x)d, %(y)d)") % locals()
+               return _("Embedded %(mode)s image %(width)d x %(height)d "
+                                       "at (%(x)d, %(y)d)") % locals()

       def SaveToFile(self, file):
               file.Image(self.data, self.trafo)
@@ -132,20 +178,28 @@

       def Embed(self):
               return self.SetData(self.data.AsEmbedded())
-       AddCmd(commands, 'EmbedImage', _("Embed Image"), Embed,
-                       sensitive_cb = 'CanEmbed')
+
+       def InvertImage(self):
+               return self.SetData(self.data.Invert())
+
+       def Convert(self, image_mode):
+               undo = (self.SetData, self.data)
+               if image_mode==RGB_IMAGE:
+                       self.SetData(self.data.Convert('RGB'))
+               if image_mode==RGBA_IMAGE:
+                       self.SetData(self.data.Convert('RGB'))
+               if image_mode==GRAYSCALE_IMAGE:
+                       self.SetData(self.data.Convert('L'))
+               if image_mode==CMYK_IMAGE:
+                       self.SetData(self.data.Convert('CMYK'))
+               if image_mode==BW_IMAGE:
+                       self.SetData(self.data.Convert('1'))
+               return undo

       def CallImageFunction(self, function, args = ()):
               if type(args) != type(()):
                       args = (args,)
               data = apply(getattr(self.data, function), args)
               return self.SetData(data)
-       AddCmd(commands, 'GrayscaleImage', _("Grayscale Image"),
-                       CallImageFunction, args = ('Convert', 'L'))
-       AddCmd(commands, 'InvertImage', _("Invert Image"), CallImageFunction,
-                       args = 'Invert')

-       context_commands = ('EmbedImage', 'GrayscaleImage', 'InvertImage')

-RegisterCommands(Image)
-
Index: src/app/UI/pluginpanels/find_replace_plugin.py
===================================================================
--- src/app/UI/pluginpanels/find_replace_plugin.py      (.../trunk/sK1) (revision 0)
+++ src/app/UI/pluginpanels/find_replace_plugin.py      (.../branches/hackontest/sK1)   (revision 560)
@@ -0,0 +1,143 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2008 by Darya Shumilina
+#
+# This library is covered by GNU Library General Public License.
+# For more info see COPYRIGHTS file in sK1 root directory.
+
+import re
+
+from ppanel import PluginPanel
+
+from app import _
+import app
+from app.Graphics import document, text
+
+from Ttk import LabelFrame, TFrame, TLabel, TCheckbutton, TButton
+from app.UI.ttk_ext import TEntryExt
+from Tkinter import RIGHT, BOTTOM, BOTH, TOP, X, E, W, Y, LEFT, StringVar, BooleanVar, DISABLED, NORMAL
+
+from app.UI.lengthvar import create_length_entry
+
+class FindReplacePanel(PluginPanel):
+       name='Find and Replace'
+       title = _("Find and Replace")
+
+       def init(self, master):
+               PluginPanel.init(self, master)
+               top = self.panel
+
+               top = TFrame(top, borderwidth=2, style='FlatFrame')
+               top.pack(side = TOP, expand = 1, fill = X)
+
+               button_frame = TFrame(top, borderwidth=2, style='FlatFrame')
+               button_frame.pack(side = BOTTOM, fill = BOTH, expand = 1)
+
+               button=TButton(button_frame,text=_('Apply'), command=self.replace)
+               button.pack(side = TOP)
+
+               #----------------------------------------------------------
+               main_frame = TFrame(top, style='FlatFrame', borderwidth=3)
+               main_frame.pack(side = TOP, fill=X)
+
+               self.find_var = StringVar(top);
+               self.find_var.set('')
+               findField = TEntryExt(main_frame, textvariable=self.find_var)
+               findField.pack(side = RIGHT)
+
+               label = TLabel(main_frame, style='FlatLabel', text = _("Find: "))
+               label.pack(side = RIGHT, anchor = E)
+               #---------------------------------------------------------
+               main_frame = TFrame(top, style='FlatFrame', borderwidth=3)
+               main_frame.pack(side = TOP, fill=X)
+
+
+               self.replace_var = StringVar(top);
+               self.replace_var.set('')
+               replaceField = TEntryExt(main_frame, textvariable=self.replace_var)
+               replaceField.pack(side = RIGHT)
+
+               label = TLabel(main_frame, style='FlatLabel', text = _("Replace to: "))
+               label.pack(side = RIGHT, anchor = E)
+
+               main_frame = TFrame(top, style='FlatFrame', borderwidth=3)
+               main_frame.pack(side = TOP)
+               #---------------------------------------------------------
+               parametersFrameLabel=LabelFrame(top, text=' Parameters ', borderwidth=2, relief='groove', pady=4, padx=4)
+
+               parametersFrameLabel.pack(side = TOP, fill=X, pady=4, padx=2)
+
+               parametersFrame = TFrame(parametersFrameLabel, style='FlatFrame')
+
+               self.var_case_sensitive = BooleanVar(top)
+               self.case_sensitive_check = TCheckbutton(parametersFrame, text = _("Case sensitive"), variable = self.var_case_sensitive)
+               self.case_sensitive_check.pack(side = TOP, anchor=W, padx=5)
+
+               self.var_whole_word = BooleanVar(top)
+               self.whole_word_check = TCheckbutton(parametersFrame, text = _("Whole word"), variable = self.var_whole_word)
+               self.whole_word_check.pack(side = TOP, anchor=W, padx=5)
+
+               self.var_regexp = BooleanVar(top)
+               self.regexpCheck = TCheckbutton(parametersFrame, text = _("RegExp search"), variable = self.var_regexp, command=self.disable_enable_action)
+               self.regexpCheck.pack(side = TOP, anchor=W, padx=5)
+
+               parametersFrame.pack(side=TOP, fill=X, pady=2)
+################################################################
+       def replace_text(self,objects, toReplace, replaceTo):
+               for object in objects:
+                       if object.is_Text:
+
+                               if self.var_regexp.get():
+                                       p=re.compile(toReplace)
+                                       text=p.sub(replaceTo, object.text)
+                                       app.mw.document.SelectObject(object)
+                                       app.mw.document.CallObjectMethod(object.__class__,_('Text Replace'),'SetText',text)
+                                       continue
+
+                               if self.var_whole_word.get():
+                                       if not self.var_case_sensitive.get():
+                                               if object.text.lower()==toReplace.lower():
+                                                       text=replaceTo
+                                                       app.mw.document.SelectObject(object)
+                                                       app.mw.document.CallObjectMethod(object.__class__,_('Text Replace'),'SetText',text)
+                                       else:
+                                               if object.text==toReplace:
+                                                       text=replaceTo
+                                                       app.mw.document.SelectObject(object)
+                                                       app.mw.document.CallObjectMethod(object.__class__,_('Text Replace'),'SetText',text)
+
+                               else:
+                                       if object.text.lower().find(toReplace.lower(), 0, len(object.text)) != -1:
+                                               if not self.var_case_sensitive.get():
+                                                       text=object.text.lower().replace(toReplace.lower(), replaceTo)
+                                               else:
+                                                       text=object.text.replace(toReplace, replaceTo)
+                                               app.mw.document.SelectObject(object)
+                                               app.mw.document.CallObjectMethod(object.__class__,_('Text Replace'),'SetText',text)
+
+                       if object.is_Group:
+                               self.replace_text(object.objects)
+################################################################
+       def replace(self):
+               textObjects=[]
+               textToReplace=self.find_var.get().decode('utf-8')
+               replaceTo=self.replace_var.get().decode('utf-8')
+
+               for layer in app.mw.document.layers:
+                       self.replace_text(layer.objects, textToReplace, replaceTo)
+               app.mw.canvas.ForceRedraw()
+################################################################
+       def disable_enable_action(self):
+               if self.case_sensitive_check['state'] != DISABLED and self.whole_word_check['state'] != DISABLED:
+                       self.case_sensitive_check['state'] = DISABLED
+                       self.whole_word_check['state'] = DISABLED
+               else:
+                       self.case_sensitive_check['state'] = NORMAL
+                       self.whole_word_check['state'] = NORMAL
+################################################################
+       def whole_word_action(self):
+               pass
+################################################################
+
+instance=FindReplacePanel()
+app.extentions_plugins.append(instance)
Index: src/app/UI/pluginpanels/__init__.py
===================================================================
--- src/app/UI/pluginpanels/__init__.py (.../trunk/sK1) (revision 560)
+++ src/app/UI/pluginpanels/__init__.py (.../branches/hackontest/sK1)   (revision 560)
@@ -1,3 +1,4 @@
import align_plugin
import grid_plugin, guidelines_plugin
-import resize_plugin, move_plugin, rotate_plugin
\ No newline at end of file
+import resize_plugin, move_plugin, rotate_plugin
+import find_replace_plugin
\ No newline at end of file
Index: src/app/UI/pluginpanels/ppanel.py
===================================================================
--- src/app/UI/pluginpanels/ppanel.py   (.../trunk/sK1) (revision 560)
+++ src/app/UI/pluginpanels/ppanel.py   (.../branches/hackontest/sK1)   (revision 560)
@@ -87,26 +87,11 @@
               return self.document.HasSelection()

       def subscribe_receivers(self):
-               for info in self.receivers:
-                       apply(self.document.Subscribe,
-                                       (info[0], getattr(self, info[1])) + info[2:])
+               pass

       def unsubscribe_receivers(self):
-               for info in self.receivers:
-                       apply(self.document.Unsubscribe,
-                                       (info[0], getattr(self, info[1])) + info[2:])
-
+               pass

-       def subscribe_receivers(self):
-               for info in self.receivers:
-                       apply(self.document.Subscribe,
-                                       (info[0], getattr(self, info[1])) + info[2:])
-
-       def unsubscribe_receivers(self):
-               for info in self.receivers:
-                       apply(self.document.Unsubscribe,
-                                       (info[0], getattr(self, info[1])) + info[2:])
-
       def SetDocument(self, doc):
               if self.document:
                       self.unsubscribe_receivers()
Index: src/app/UI/canvas.py
===================================================================
--- src/app/UI/canvas.py        (.../trunk/sK1) (revision 560)
+++ src/app/UI/canvas.py        (.../branches/hackontest/sK1)   (revision 560)
@@ -304,8 +304,8 @@
                       if self.context_menu_items[-1] != None:
                               # insert a separator if necessary
                               self.context_menu_items.append(None)
-                       self.context_menu_items = self.context_menu_items \
-                                                                               + list(aclass.context_commands)
+#                      self.context_menu_items = self.context_menu_items \
+#                                                                              + list(aclass.context_commands)

               self.commands = cmds
               self.object_keymap = None
@@ -720,7 +720,6 @@
                                               x, y, button, state)
                       if self.context_commands is None:
                               self.build_context_commands()
-
                       items = []
                       last = None
                       for cmd in self.context_commands:
Index: src/app/UI/command.py
===================================================================
--- src/app/UI/command.py       (.../trunk/sK1) (revision 560)
+++ src/app/UI/command.py       (.../branches/hackontest/sK1)   (revision 560)
@@ -72,7 +72,6 @@
               return changed

       def get_sensitive(self):
-               #print 'get_sensitive', self
               if self.sensitive_cb:
                       method = self.get_method(self.sensitive_cb)
                       if method:
Index: src/app/UI/context/image_panel.py
===================================================================
--- src/app/UI/context/image_panel.py   (.../trunk/sK1) (revision 0)
+++ src/app/UI/context/image_panel.py   (.../branches/hackontest/sK1)   (revision 560)
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2008 by Igor E. Novikov
+#
+# This library is covered by GNU Library General Public License.
+# For more info see COPYRIGHTS file in sK1 root directory.
+
+
+from app.UI.tkext import ToolbarButton
+from app.conf.const import CHANGED
+from Tkinter import LEFT, DoubleVar, StringVar, RIGHT
+from subpanel import CtxSubPanel
+from app import  _, config, PolyBezier, CreatePath, Point
+import tooltips
+from app.UI.lengthvar import LengthVar
+from app.conf.const import SELECTION
+
+class ImagePanel(CtxSubPanel):
+
+       name='ImagePanel'
+
+       def __init__(self, parent):
+               CtxSubPanel.__init__(self, parent)
+               self.builded=0
+               self.doc.Subscribe(SELECTION, self.update)
+
+       def build_dlg(self):
+               if not self.builded:
+                       cmds = self.mw.commands
+
+                       b = ToolbarButton(self.panel, command=cmds.Convert_to_CMYK, style='Toolbutton', image='context_image_cmyk')
+                       tooltips.AddDescription(b, _('Convert to CMYK'))
+                       b.pack(side = LEFT)
+
+                       b = ToolbarButton(self.panel, command=cmds.Convert_to_RGB, style='Toolbutton', image='context_image_rgb')
+                       tooltips.AddDescription(b, _('Convert to RGB'))
+                       b.pack(side = LEFT)
+
+                       b = ToolbarButton(self.panel, command=cmds.Convert_to_Grayscale, style='Toolbutton', image='context_image_gray')
+                       tooltips.AddDescription(b, _('Convert to Grayscale'))
+                       b.pack(side = LEFT)
+
+                       b = ToolbarButton(self.panel, command=cmds.Convert_to_BW, style='Toolbutton', image='context_image_bw')
+                       tooltips.AddDescription(b, _('Convert to B&W'))
+                       b.pack(side = LEFT)
+
+                       self.builded=1
+
+       def update(self,*arg):
+               if not self.mw.canvas is None:
+                       self.build_dlg()
+
+
Index: src/app/UI/context/ctxPanel.py
===================================================================
--- src/app/UI/context/ctxPanel.py      (.../trunk/sK1) (revision 560)
+++ src/app/UI/context/ctxPanel.py      (.../branches/hackontest/sK1)   (revision 560)
@@ -16,6 +16,7 @@
from unit_panel import UnitPanel
from jump_panel import JumpPanel
from page_panel import PagePanel
+from image_panel import ImagePanel
from group_panel import GroupPanel, CombinePanel, ToCurvePanel
from text_prop_panel import TextPropPanel
from textalign_panel import TextAlignPanel
@@ -40,6 +41,7 @@
forSimpleText=['TextPropPanel','FontPanel','TextAlignPanel','ToCurvePanel']
forGroup=['ResizePanel','UnitPanel','FlipPanel', 'RotatePanel', 'GroupPanel', 'CombinePanel', 'ToCurvePanel']
forNodes=['ResizePanel','UnitPanel', 'CombinePanel','NodeEditPanel']
+forImage=['ResizePanel','UnitPanel','FlipPanel', 'RotatePanel', 'ImagePanel']


class ContexPanel(Publisher):
@@ -100,6 +102,8 @@
                                       self.changeContent(forGroup)
                               elif obj_type==SIMPLE_TEXT:
                                       self.changeContent(forSimpleText)
+                               elif obj_type==IMAGE:
+                                       self.changeContent(forImage)
                               else:
                                       self.changeContent(forObject)
                       else:
@@ -109,6 +113,8 @@
                                       self.changeContent(forSimpleText)
                               elif obj_type==BEZIER:
                                       self.changeContent(forNodes)
+                               elif obj_type==IMAGE:
+                                       self.changeContent(forImage)
                               else:
                                       self.changeContent(forObject)
               else:
@@ -134,4 +140,4 @@

PanelList=[PagePanel, ResizePanel, GuidesPanel, RotatePanel, JumpPanel,
               TextPropPanel, TextAlignPanel, FlipPanel, UnitPanel, GroupPanel,
-               FontPanel,CombinePanel, ToCurvePanel, NodeEditPanel]
\ No newline at end of file
+               FontPanel,CombinePanel, ToCurvePanel, NodeEditPanel, ImagePanel]
\ No newline at end of file
Index: src/app/UI/tkext.py
===================================================================
--- src/app/UI/tkext.py (.../trunk/sK1) (revision 560)
+++ src/app/UI/tkext.py (.../branches/hackontest/sK1)   (revision 560)
@@ -196,7 +196,7 @@
#                      self['image']=self.image
#              else:
#                      self['image']='menu_icon_mask'
-               AutoUpdate.SetSensitive(self, on)
+               AutoUpdate.SetSensitive(self, on)


       def clean_up(self):
Index: src/app/UI/mainwindow.py
===================================================================
--- src/app/UI/mainwindow.py    (.../trunk/sK1) (revision 560)
+++ src/app/UI/mainwindow.py    (.../branches/hackontest/sK1)   (revision 560)
@@ -39,6 +39,7 @@
                       UpdatedTButton
import tkext
from context import ctxPanel
+from app.Graphics.image import RGB_IMAGE, RGBA_IMAGE, GRAYSCALE_IMAGE, CMYK_IMAGE,BW_IMAGE

from command import CommandClass, Keymap, Commands
from math import floor, ceil
@@ -885,7 +886,17 @@
       AddDocCmd('FillNone', _("No Fill"), 'AddStyle', args = EmptyFillStyle)
       AddDocCmd('LineNone', _("No Line"), 'AddStyle', args = EmptyLineStyle)
       AddDocCmd('UpdateStyle', _("Update Style"), 'UpdateDynamicStyleSel')
+

+
+       AddDocCmd('Convert_to_CMYK', _("Convert to CMYK"), 'ConvertImage', args = CMYK_IMAGE, sensitive_cb ='CanBeCMYK')
+       AddDocCmd('Convert_to_RGB', _("Convert to RGB"), 'ConvertImage', args = RGB_IMAGE, sensitive_cb ='CanBeRGB')
+       AddDocCmd('Convert_to_Grayscale', _("Convert to Grayscale"), 'ConvertImage', args = GRAYSCALE_IMAGE, sensitive_cb ='CanBeGrayscale')
+       AddDocCmd('Convert_to_BW', _("Convert to B&W"), 'ConvertImage', args = BW_IMAGE, sensitive_cb ='CanBeBW')
+
+       AddDocCmd('Invert', _("Invert Image"), 'Invert', sensitive_cb ='CanInvert')
+       AddDocCmd('Embed', _("Embed Image"), 'Embed', sensitive_cb ='CanEmbed')
+
################### Menu build ############################
       def build_menu(self):
               mbar = self.mbar
@@ -895,6 +906,7 @@
               AppendMenu(mbar, _("Layout"), self.make_layout_menu(), 0)
               AppendMenu(mbar, _("Arrange"), self.make_arrange_menu(), 0)
               AppendMenu(mbar, _("Effects"), self.make_effects_menu(), 4)
+               AppendMenu(mbar, _("Bitmaps"), self.make_bitmaps_menu(), 0)
#              AppendMenu(mbar, _("Curve"), self.make_curve_menu(), 1)
               AppendMenu(mbar, _("Style"), self.make_style_menu(), 1)
#              AppendMenu(mbar, _("Script"), self.make_script_menu(), 0)
@@ -1099,6 +1111,18 @@
                                       None,
                                       self.commands.ConvertToCurve])

+       def make_bitmaps_menu(self):
+               cmds = self.commands
+               return map(MakeCommand,
+                                       [cmds.Convert_to_CMYK,
+                                       cmds.Convert_to_RGB,
+                                       cmds.Convert_to_Grayscale,
+                                       cmds.Convert_to_BW,
+                                       None,
+                                       cmds.Invert,
+                                       None,
+                                       cmds.Embed])
+
       def make_style_menu(self):
               return map(MakeCommand,
                                       [self.commands.FillNone,
@@ -1453,7 +1477,7 @@
                               is_eps = eps.IsEpsFileStart(file.read(256))
                               file.close()
                               dir, name = os.path.split(filename)
-                               config.preferences.image_dir = dir
+                               config.preferences.dir_for_bitmap_import = dir
                               if is_eps:
                                       imageobj = eps.EpsImage(filename = sysfilename)
                               else:
Index: src/extentions/pycms/ImPlatform.h
===================================================================
--- src/extentions/pycms/ImPlatform.h   (.../trunk/sK1) (revision 0)
+++ src/extentions/pycms/ImPlatform.h   (.../branches/hackontest/sK1)   (revision 560)
@@ -0,0 +1,72 @@
+/*
+ * The Python Imaging Library
+ * $Id: ImPlatform.h 2134 2004-10-06 08:55:20Z fredrik $
+ *
+ * platform declarations for the imaging core library
+ *
+ * Copyright (c) Fredrik Lundh 1995-2003.
+ */
+
+#include "Python.h"
+
+/* Check that we have an ANSI compliant compiler */
+#ifndef HAVE_PROTOTYPES
+#error Sorry, this library requires support for ANSI prototypes.
+#endif
+#ifndef STDC_HEADERS
+#error Sorry, this library requires ANSI header files.
+#endif
+
+#if defined(_MSC_VER)
+#ifndef WIN32
+#define WIN32
+#endif
+/* VC++ 4.0 is a bit annoying when it comes to precision issues (like
+   claiming that "float a = 0.0;" would lead to loss of precision).  I
+   don't like to see warnings from my code, but since I still want to
+   keep it readable, I simply switch off a few warnings instead of adding
+   the tons of casts that VC++ seem to require.  This code is compiled
+   with numerous other compilers as well, so any real errors are likely
+   to be catched anyway. */
+#pragma warning(disable: 4244) /* conversion from 'float' to 'int' */
+#endif
+
+#if defined(_MSC_VER)
+#define inline __inline
+#elif !defined(USE_INLINE)
+#define inline
+#endif
+
+#if SIZEOF_SHORT == 2
+#define        INT16 short
+#elif SIZEOF_INT == 2
+#define        INT16 int
+#else
+#define        INT16 short /* most things works just fine anyway... */
+#endif
+
+#if SIZEOF_SHORT == 4
+#define        INT32 short
+#elif SIZEOF_INT == 4
+#define        INT32 int
+#elif SIZEOF_LONG == 4
+#define        INT32 long
+#else
+#error Cannot find required 32-bit integer type
+#endif
+
+#if SIZEOF_LONG == 8
+#define        INT64 long
+#elif SIZEOF_LONG_LONG == 8
+#define        INT64 long
+#endif
+
+/* assume IEEE; tweak if necessary (patches are welcome) */
+#define        FLOAT32 float
+#define        FLOAT64 double
+
+#define        INT8  signed char
+#define        UINT8 unsigned char
+
+#define        UINT16 unsigned INT16
+#define        UINT32 unsigned INT32

Property changes on: src/extentions/pycms/ImPlatform.h
___________________________________________________________________
Name: svn:eol-style
  + native

Index: src/extentions/pycms/Imaging.h
===================================================================
--- src/extentions/pycms/Imaging.h      (.../trunk/sK1) (revision 0)
+++ src/extentions/pycms/Imaging.h      (.../branches/hackontest/sK1)   (revision 560)
@@ -0,0 +1,493 @@
+/*
+ * The Python Imaging Library
+ * $Id: Imaging.h 2308 2005-03-02 12:00:55Z fredrik $
+ *
+ * declarations for the imaging core library
+ *
+ * Copyright (c) 1997-2003 by Secret Labs AB
+ * Copyright (c) 1995-2003 by Fredrik Lundh
+ *
+ * See the README file for information on usage and redistribution.
+ */
+
+
+#include "ImPlatform.h"
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#ifndef M_PI
+#define        M_PI    3.14159265359
+#endif
+
+
+/* -------------------------------------------------------------------- */
+
+/*
+ * Image data organization:
+ *
+ * mode            bytes       byte order
+ * -------------------------------
+ * 1       1           1
+ * L       1           L
+ * P       1           P
+ * I        4           I (32-bit integer, native byte order)
+ * F        4           F (32-bit IEEE float, native byte order)
+ * RGB     4           R, G, B, -
+ * RGBA            4           R, G, B, A
+ * CMYK            4           C, M, Y, K
+ * YCbCr    4          Y, Cb, Cr, -
+ *
+ * experimental modes (incomplete):
+ * LA       4           L, -, -, A
+ * PA       4           P, -, -, A
+ * I;16     2           I (16-bit integer, native byte order)
+ *
+ * "P" is an 8-bit palette mode, which should be mapped through the
+ * palette member to get an output image.  Check palette->mode to
+ * find the corresponding "real" mode.
+ *
+ * For information on how to access Imaging objects from your own C
+ * extensions, see http://www.effbot.org/zone/pil-extending.htm
+ */
+
+/* Handles */
+
+typedef struct ImagingMemoryInstance* Imaging;
+typedef struct ImagingAccessInstance* ImagingAccess;
+typedef struct ImagingHistogramInstance* ImagingHistogram;
+typedef struct ImagingOutlineInstance* ImagingOutline;
+typedef struct ImagingPaletteInstance* ImagingPalette;
+
+/* handle magics (used with PyCObject). */
+#define IMAGING_MAGIC "PIL Imaging"
+#define IMAGING_ACCESS_MAGIC "PIL ImagingAccess"
+
+/* pixel types */
+#define IMAGING_TYPE_UINT8 0
+#define IMAGING_TYPE_INT32 1
+#define IMAGING_TYPE_FLOAT32 2
+#define IMAGING_TYPE_SPECIAL 3 /* check mode for details */
+
+struct ImagingMemoryInstance {
+
+    /* Format */
+    char mode[4+1];    /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK") */
+    int type;          /* Data type (IMAGING_TYPE_*) */
+    int depth;         /* Depth (ignored in this version) */
+    int bands;         /* Number of bands (1, 2, 3, or 4) */
+    int xsize;         /* Image dimension. */
+    int ysize;
+
+    /* Colour palette (for "P" images only) */
+    ImagingPalette palette;
+
+    /* Data pointers */
+    UINT8 **image8;    /* Set for 8-bit images (pixelsize=1). */
+    INT32 **image32;   /* Set for 32-bit images (pixelsize=4). */
+
+    /* Internals */
+    char **image;      /* Actual raster data. */
+    char *block;       /* Set if data is allocated in a single block. */
+
+    int pixelsize;     /* Size of a pixel, in bytes (1, 2 or 4) */
+    int linesize;      /* Size of a line, in bytes (xsize * pixelsize) */
+
+    /* Virtual methods */
+    void (*destroy)(Imaging im);
+
+};
+
+
+#define IMAGING_PIXEL_1(im,x,y) ((im)->image8[(y)][(x)])
+#define IMAGING_PIXEL_L(im,x,y) ((im)->image8[(y)][(x)])
+#define IMAGING_PIXEL_LA(im,x,y) ((im)->image[(y)][(x)*4])
+#define IMAGING_PIXEL_P(im,x,y) ((im)->image8[(y)][(x)])
+#define IMAGING_PIXEL_PA(im,x,y) ((im)->image[(y)][(x)*4])
+#define IMAGING_PIXEL_I(im,x,y) ((im)->image32[(y)][(x)])
+#define IMAGING_PIXEL_F(im,x,y) (((FLOAT32*)(im)->image32[y])[x])
+#define IMAGING_PIXEL_RGB(im,x,y) ((im)->image[(y)][(x)*4])
+#define IMAGING_PIXEL_RGBA(im,x,y) ((im)->image[(y)][(x)*4])
+#define IMAGING_PIXEL_CMYK(im,x,y) ((im)->image[(y)][(x)*4])
+#define IMAGING_PIXEL_YCbCr(im,x,y) ((im)->image[(y)][(x)*4])
+
+#define IMAGING_PIXEL_UINT8(im,x,y) ((im)->image8[(y)][(x)])
+#define IMAGING_PIXEL_INT32(im,x,y) ((im)->image32[(y)][(x)])
+#define IMAGING_PIXEL_FLOAT32(im,x,y) (((FLOAT32*)(im)->image32[y])[x])
+
+#define IMAGING_ACCESS_HEAD\
+    int (*getline)(ImagingAccess access, char *buffer, int y);\
+    void (*destroy)(ImagingAccess access)
+
+struct ImagingAccessInstance {
+    IMAGING_ACCESS_HEAD;
+
+    /* Data members */
+    Imaging im;
+
+};
+
+
+struct ImagingHistogramInstance {
+
+    /* Format */
+    char mode[4+1];    /* Band names (of corresponding source image) */
+    int bands;         /* Number of bands (1, 3, or 4) */
+
+    /* Data */
+    long *histogram;   /* Histogram (bands*256 longs) */
+
+};
+
+
+struct ImagingPaletteInstance {
+
+    /* Format */
+    char mode[4+1];    /* Band names */
+
+    /* Data */
+    UINT8 palette[1024];/* Palette data (same format as image data) */
+
+    INT16* cache;      /* Palette cache (used for predefined palettes) */
+    int keep_cache;    /* This palette will be reused; keep cache */
+
+};
+
+
+/* Objects */
+/* ------- */
+
+extern Imaging ImagingNew(const char* mode, int xsize, int ysize);
+extern Imaging ImagingNew2(const char* mode, Imaging imOut, Imaging imIn);
+extern void    ImagingDelete(Imaging im);
+
+extern Imaging ImagingNewBlock(const char* mode, int xsize, int ysize);
+extern Imaging ImagingNewArray(const char* mode, int xsize, int ysize);
+extern Imaging ImagingNewMap(const char* filename, int readonly,
+                             const char* mode, int xsize, int ysize);
+
+extern Imaging ImagingNewPrologue(const char *mode,
+                                  unsigned xsize, unsigned ysize);
+extern Imaging ImagingNewPrologueSubtype(const char *mode,
+                                  unsigned xsize, unsigned ysize,
+                                  int structure_size);
+extern Imaging ImagingNewEpilogue(Imaging im);
+
+extern void ImagingCopyInfo(Imaging destination, Imaging source);
+
+extern void ImagingHistogramDelete(ImagingHistogram histogram);
+
+extern ImagingAccess ImagingAccessNew(Imaging im);
+extern void          ImagingAccessDelete(ImagingAccess access);
+
+extern ImagingPalette ImagingPaletteNew(const char *mode);
+extern ImagingPalette ImagingPaletteNewBrowser(void);
+extern ImagingPalette ImagingPaletteDuplicate(ImagingPalette palette);
+extern void           ImagingPaletteDelete(ImagingPalette palette);
+
+extern int  ImagingPaletteCachePrepare(ImagingPalette palette);
+extern void ImagingPaletteCacheUpdate(ImagingPalette palette,
+                                     int r, int g, int b);
+extern void ImagingPaletteCacheDelete(ImagingPalette palette);
+
+#define        ImagingPaletteCache(p, r, g, b)\
+    p->cache[(r>>2) + (g>>2)*64 + (b>>2)*64*64]
+
+extern Imaging ImagingQuantize(Imaging im, int colours, int mode, int kmeans);
+
+/* Threading */
+/* --------- */
+
+typedef void* ImagingSectionCookie;
+
+extern void ImagingSectionEnter(ImagingSectionCookie* cookie);
+extern void ImagingSectionLeave(ImagingSectionCookie* cookie);
+
+/* Exceptions */
+/* ---------- */
+
+extern void* ImagingError_IOError(void);
+extern void* ImagingError_MemoryError(void);
+extern void* ImagingError_ModeError(void); /* maps to ValueError by default */
+extern void* ImagingError_Mismatch(void); /* maps to ValueError by default */
+extern void* ImagingError_ValueError(const char* message);
+
+/* Transform callbacks */
+/* ------------------- */
+
+/* standard transforms */
+#define IMAGING_TRANSFORM_AFFINE 0
+#define IMAGING_TRANSFORM_PERSPECTIVE 2
+#define IMAGING_TRANSFORM_QUAD 3
+
+
+/* standard filters */
+#define IMAGING_TRANSFORM_NEAREST 0
+#define IMAGING_TRANSFORM_ANTIALIAS 1
+#define IMAGING_TRANSFORM_BILINEAR 2
+#define IMAGING_TRANSFORM_BICUBIC 3
+
+typedef int (*ImagingTransformMap)(double* X, double* Y,
+                                   int x, int y, void* data);
+typedef int (*ImagingTransformFilter)(void* out, Imaging im,
+                                      double x, double y,
+                                      void* data);
+
+/* Image Manipulation Methods */
+/* -------------------------- */
+
+extern Imaging ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha);
+extern Imaging ImagingCopy(Imaging im);
+extern Imaging ImagingConvert(
+    Imaging im, const char* mode, ImagingPalette palette, int dither);
+extern Imaging ImagingConvertMatrix(Imaging im, const char *mode, float m[]);
+extern Imaging ImagingCrop(Imaging im, int x0, int y0, int x1, int y1);
+extern Imaging ImagingExpand(Imaging im, int x, int y, int mode);
+extern Imaging ImagingFill(Imaging im, const void* ink);
+extern int ImagingFill2(
+    Imaging into, const void* ink, Imaging mask,
+    int x0, int y0, int x1, int y1);
+extern Imaging ImagingFillBand(Imaging im, int band, int color);
+extern Imaging ImagingFillLinearGradient(const char* mode);
+extern Imaging ImagingFillRadialGradient(const char* mode);
+extern Imaging ImagingFilter(
+    Imaging im, int xsize, int ysize, const FLOAT32* kernel,
+    FLOAT32 offset, FLOAT32 divisor);
+extern Imaging ImagingFlipLeftRight(Imaging imOut, Imaging imIn);
+extern Imaging ImagingFlipTopBottom(Imaging imOut, Imaging imIn);
+extern Imaging ImagingGetBand(Imaging im, int band);
+extern int ImagingGetBBox(Imaging im, int bbox[4]);
+typedef struct { int x, y; INT32 count; INT32 pixel; } ImagingColorItem;
+extern ImagingColorItem* ImagingGetColors(Imaging im, int maxcolors,
+    int *colors);
+extern int ImagingGetExtrema(Imaging im, void *extrema);
+extern int ImagingGetProjection(Imaging im, UINT8* xproj, UINT8* yproj);
+extern ImagingHistogram ImagingGetHistogram(
+    Imaging im, Imaging mask, void *extrema);
+extern Imaging ImagingModeFilter(Imaging im, int size);
+extern Imaging ImagingNegative(Imaging im);
+extern Imaging ImagingOffset(Imaging im, int xoffset, int yoffset);
+extern int ImagingPaste(
+    Imaging into, Imaging im, Imaging mask,
+    int x0, int y0, int x1, int y1);
+extern Imaging ImagingPoint(
+    Imaging im, const char* tablemode, const void* table);
+extern Imaging ImagingPointTransform(
+    Imaging imIn, double scale, double offset);
+extern Imaging ImagingPutBand(Imaging im, Imaging imIn, int band);
+extern Imaging ImagingRankFilter(Imaging im, int size, int rank);
+extern Imaging ImagingResize(Imaging imOut, Imaging imIn, int filter);
+extern Imaging ImagingRotate(
+    Imaging imOut, Imaging imIn, double theta, int filter);
+extern Imaging ImagingRotate90(Imaging imOut, Imaging imIn);
+extern Imaging ImagingRotate180(Imaging imOut, Imaging imIn);
+extern Imaging ImagingRotate270(Imaging imOut, Imaging imIn);
+extern Imaging ImagingStretch(Imaging imOut, Imaging imIn, int filter);
+extern Imaging ImagingTransformPerspective(
+    Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1,
+    double a[8], int filter, int fill);
+extern Imaging ImagingTransformAffine(
+    Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1,
+    double a[6], int filter, int fill);
+extern Imaging ImagingTransformQuad(
+    Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1,
+    double a[8], int filter, int fill);
+extern Imaging ImagingTransform(
+    Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1,
+    ImagingTransformMap transform, void* transform_data,
+    ImagingTransformFilter filter, void* filter_data,
+    int fill);
+extern Imaging ImagingCopy2(Imaging imOut, Imaging imIn);
+extern Imaging ImagingConvert2(Imaging imOut, Imaging imIn);
+
+/* Channel operations */
+/* any mode, except "F" */
+extern Imaging ImagingChopLighter(Imaging imIn1, Imaging imIn2);
+extern Imaging ImagingChopDarker(Imaging imIn1, Imaging imIn2);
+extern Imaging ImagingChopDifference(Imaging imIn1, Imaging imIn2);
+extern Imaging ImagingChopMultiply(Imaging imIn1, Imaging imIn2);
+extern Imaging ImagingChopScreen(Imaging imIn1, Imaging imIn2);
+extern Imaging ImagingChopAdd(
+    Imaging imIn1, Imaging imIn2, float scale, int offset);
+extern Imaging ImagingChopSubtract(
+    Imaging imIn1, Imaging imIn2, float scale, int offset);
+extern Imaging ImagingChopAddModulo(Imaging imIn1, Imaging imIn2);
+extern Imaging ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2);
+
+/* "1" images only */
+extern Imaging ImagingChopAnd(Imaging imIn1, Imaging imIn2);
+extern Imaging ImagingChopOr(Imaging imIn1, Imaging imIn2);
+extern Imaging ImagingChopXor(Imaging imIn1, Imaging imIn2);
+
+/* Image measurement */
+extern void ImagingCrack(Imaging im, int x0, int y0);
+
+/* Graphics */
+struct ImagingAffineMatrixInstance {
+    float a[9];
+};
+
+typedef struct ImagingAffineMatrixInstance *ImagingAffineMatrix;
+
+extern int ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1,
+                          int start, int end, const void* ink, int op);
+extern int ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap,
+                             const void* ink, int op);
+extern int ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1,
+                            int start, int end, const void* ink, int fill,
+                            int op);
+extern int ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1,
+                              const void* ink, int fill, int op);
+extern int ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1,
+                          const void* ink, int op);
+extern int ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
+                               const void* ink, int width, int op);
+extern int ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1,
+                               int start, int end, const void* ink, int fill,
+                               int op);
+extern int ImagingDrawPoint(Imaging im, int x, int y, const void* ink, int op);
+extern int ImagingDrawPolygon(Imaging im, int points, int *xy,
+                             const void* ink, int fill, int op);
+extern int ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1,
+                               const void* ink, int fill, int op);
+
+/* Level 2 graphics (WORK IN PROGRESS) */
+extern ImagingOutline ImagingOutlineNew(void);
+extern void ImagingOutlineDelete(ImagingOutline outline);
+
+extern int ImagingDrawOutline(Imaging im, ImagingOutline outline,
+                              const void* ink, int fill, int op);
+
+extern int ImagingOutlineMove(ImagingOutline outline, float x, float y);
+extern int ImagingOutlineLine(ImagingOutline outline, float x, float y);
+extern int ImagingOutlineCurve(ImagingOutline outline, float x1, float y1,
+                                float x2, float y2, float x3, float y3);
+extern int ImagingOutlineTransform(ImagingOutline outline, double a[6]);
+
+extern int ImagingOutlineClose(ImagingOutline outline);
+
+/* Special effects */
+extern Imaging ImagingEffectSpread(Imaging imIn, int distance);
+extern Imaging ImagingEffectNoise(int xsize, int ysize, float sigma);
+extern Imaging ImagingEffectMandelbrot(int xsize, int ysize,
+                                       double extent[4], int quality);
+
+/* Obsolete */
+extern int ImagingToString(Imaging im, int orientation, char *buffer);
+extern int ImagingFromString(Imaging im, int orientation, char *buffer);
+
+
+/* File I/O */
+/* -------- */
+
+/* Built-in drivers */
+extern Imaging ImagingOpenPPM(const char* filename);
+extern int ImagingSavePPM(Imaging im, const char* filename);
+
+/* Utility functions */
+extern UINT32 ImagingCRC32(UINT32 crc, UINT8* buffer, int bytes);
+
+/* Codecs */
+typedef struct ImagingCodecStateInstance *ImagingCodecState;
+typedef int (*ImagingCodec)(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+
+extern int ImagingBitDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingEpsEncode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingFliDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingGifDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingGifEncode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingHexDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+#ifdef HAVE_LIBJPEG
+extern int ImagingJpegDecode(Imaging im, ImagingCodecState state,
+                            UINT8* buffer, int bytes);
+extern int ImagingJpegEncode(Imaging im, ImagingCodecState state,
+                            UINT8* buffer, int bytes);
+#endif
+extern int ImagingLzwDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+#ifdef HAVE_LIBMPEG
+extern int ImagingMpegDecode(Imaging im, ImagingCodecState state,
+                            UINT8* buffer, int bytes);
+#endif
+extern int ImagingMspDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingPackbitsDecode(Imaging im, ImagingCodecState state,
+                                UINT8* buffer, int bytes);
+extern int ImagingPcdDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingPcxDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingPcxEncode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingRawDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingRawEncode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingSunRleDecode(Imaging im, ImagingCodecState state,
+                              UINT8* buffer, int bytes);
+extern int ImagingTgaRleDecode(Imaging im, ImagingCodecState state,
+                              UINT8* buffer, int bytes);
+extern int ImagingXbmDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingXbmEncode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+#ifdef HAVE_LIBZ
+extern int ImagingZipDecode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+extern int ImagingZipEncode(Imaging im, ImagingCodecState state,
+                           UINT8* buffer, int bytes);
+#endif
+
+typedef void (*ImagingShuffler)(UINT8* out, const UINT8* in, int pixels);
+
+/* Public shufflers */
+extern void ImagingPackRGB(UINT8* out, const UINT8* in, int pixels);
+extern void ImagingPackBGR(UINT8* out, const UINT8* in, int pixels);
+extern void ImagingUnpackRGB(UINT8* out, const UINT8* in, int pixels);
+extern void ImagingUnpackBGR(UINT8* out, const UINT8* in, int pixels);
+extern void ImagingUnpackYCC(UINT8* out, const UINT8* in, int pixels);
+extern void ImagingUnpackYCCA(UINT8* out, const UINT8* in, int pixels);
+extern void ImagingUnpackYCbCr(UINT8* out, const UINT8* in, int pixels);
+
+extern void ImagingConvertRGB2YCbCr(UINT8* out, const UINT8* in, int pixels);
+extern void ImagingConvertYCbCr2RGB(UINT8* out, const UINT8* in, int pixels);
+
+extern ImagingShuffler ImagingFindUnpacker(const char* mode,
+                                           const char* rawmode, int* bits_out);
+extern ImagingShuffler ImagingFindPacker(const char* mode,
+                                         const char* rawmode, int* bits_out);
+
+struct ImagingCodecStateInstance {
+    int count;
+    int state;
+    int errcode;
+    int x, y;
+    int ystep;
+    int xsize, ysize, xoff, yoff;
+    ImagingShuffler shuffle;
+    int bits, bytes;
+    UINT8 *buffer;
+    void *context;
+};
+
+/* Errcodes */
+#define        IMAGING_CODEC_END        1
+#define        IMAGING_CODEC_OVERRUN   -1
+#define        IMAGING_CODEC_BROKEN    -2
+#define        IMAGING_CODEC_UNKNOWN   -3
+#define        IMAGING_CODEC_CONFIG    -8
+#define        IMAGING_CODEC_MEMORY    -9
+
+#if defined(__cplusplus)
+}
+#endif

Property changes on: src/extentions/pycms/Imaging.h
___________________________________________________________________
Name: svn:eol-style
  + native

Index: src/extentions/pycms/pyCMSdll.c
===================================================================
--- src/extentions/pycms/pyCMSdll.c     (.../trunk/sK1) (revision 0)
+++ src/extentions/pycms/pyCMSdll.c     (.../branches/hackontest/sK1)   (revision 560)
@@ -0,0 +1,673 @@
+#define COPYRIGHTINFO "\
+pyCMS\n\
+a Python / PIL interface to the littleCMS ICC Color Management System\n\
+Copyright (C) 2002-2003 Kevin Cazabon\n\
[email protected]\n\
+http://www.cazabon.com\n\
+\n\
+pyCMS home page:  http://www.cazabon.com/pyCMS\n\
+littleCMS home page:  http://www.littlecms.com\n\
+(littleCMS is Copyright (C) 1998-2001 Marti Maria)\n\
+\n\
+This library is free software; you can redistribute it and/or\n\
+modify it under the terms of the GNU Lesser General Public\n\
+License as published by the Free Software Foundation; either\n\
+version 2.1 of the License, or (at your option) any later version.\n\
+\n\
+This library is distributed in the hope that it will be useful,\n\
+but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n\
+Lesser General Public License for more details.\n\
+\n\
+You should have received a copy of the GNU Lesser General Public\n\
+License along with this library; if not, write to the Free Software\n\
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\
+"
+
+/////////////////////////////////////////////////////////////////////////////
+// includes
+/////////////////////////////////////////////////////////////////////////////
+#include "Python.h"
+//#include "patchlevel.h" // so we can include the Python version automatically in pyCMSdll.versions()
+#include "lcms.h"
+#include "Imaging.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+// version information: update this before compiling for the versions you're using
+/////////////////////////////////////////////////////////////////////////////
+#define PYCMSVERSION        "0.0.2 alpha"
+#define LITTLECMSVERSION    "1.09b"
+#define PILVERSION          "1.1.3"
+
+//#ifndef PY_MAJOR_VERSION
+  // before 1.5.2b2, these were not supported
+//  #define PY_MAJOR_VERSION 0
+//  #define PY_MINOR_VERSION 0
+//  #define PY_MICRO_VERSION 0
+//#endif
+#define PYTHONVERSION       "2.2.0"
+
+/////////////////////////////////////////////////////////////////////////////
+// version history
+/////////////////////////////////////////////////////////////////////////////
+/*
+0.0.2 alpha:  Minor updates, added interfaces to littleCMS features, Jan 6, 2003
+    - fixed some memory holes in how transforms/profiles were created and passed back to Python
+       due to improper destructor setup for PyCObjects
+    - added buildProofTransformFromOpenProfiles() function
+    - eliminated some code redundancy, centralizing several common tasks with internal functions
+
+0.0.1 alpha:  First public release Dec 26, 2002
+
+*/
+
+/////////////////////////////////////////////////////////////////////////////
+// known to-do list with current version
+/////////////////////////////////////////////////////////////////////////////
+/*
+getDefaultIntent doesn't seem to work properly... whassup??? I'm getting very large int return values instead of 0-3
+getProfileName and getProfileInfo are a bit shaky... work on these to solidify them!
+
+Add comments to code to make it clearer for others to read/understand!!!
+Verify that PILmode->littleCMStype conversion in findLCMStype is correct for all PIL modes (it probably isn't for the more obscure ones)
+
+Add support for reading and writing embedded profiles in JPEG and TIFF files
+Add support for creating custom RGB profiles on the fly
+Add support for checking presence of a specific tag in a profile
+Add support for other littleCMS features as required
+
+*/
+
+
+/////////////////////////////////////////////////////////////////////////////
+// options / configuration
+/////////////////////////////////////////////////////////////////////////////
+// Set the action to take upon error within the CMS module
+// LCMS_ERROR_SHOW      pop-up window showing error, do not close application
+// LCMS_ERROR_ABORT     pop-up window showing error, close the application
+// LCMS_ERROR_IGNORE    ignore the error and continue
+#define cmsERROR_HANDLER LCMS_ERROR_SHOW
+
+
+/////////////////////////////////////////////////////////////////////////////
+// reference
+/////////////////////////////////////////////////////////////////////////////
+/*
+INTENT_PERCEPTUAL                 0
+INTENT_RELATIVE_COLORIMETRIC      1
+INTENT_SATURATION                 2
+INTENT_ABSOLUTE_COLORIMETRIC      3
+*/
+
+
+/////////////////////////////////////////////////////////////////////////////
+// structs
+/////////////////////////////////////////////////////////////////////////////
+typedef struct {
+    PyObject_HEAD
+    Imaging image;
+} ImagingObject;
+
+
+/////////////////////////////////////////////////////////////////////////////
+// internal functions
+/////////////////////////////////////////////////////////////////////////////
+DWORD
+findLCMStype (char* PILmode) {
+  char *errorMsg = NULL;
+
+  if (strcmp(PILmode, "RGB") == 0) {
+    return TYPE_RGBA_8;
+  }
+  else if (strcmp(PILmode, "RGBA") == 0) {
+    return TYPE_RGBA_8;
+  }
+  else if (strcmp(PILmode, "RGBX") == 0) {
+    return TYPE_RGBA_8;
+  }
+  else if (strcmp(PILmode, "RGBA;16B") == 0) {
+    return TYPE_RGBA_16;
+  }
+  else if (strcmp(PILmode, "CMYK") == 0) {
+    return TYPE_CMYK_8;
+  }
+  else if (strcmp(PILmode, "L") == 0) {
+    return TYPE_GRAY_8;
+  }
+  else if (strcmp(PILmode, "L;16") == 0) {
+    return TYPE_GRAY_16;
+  }
+  else if (strcmp(PILmode, "L;16B") == 0) {
+    return TYPE_GRAY_16_SE;
+  }
+  else if (strcmp(PILmode, "YCCA") == 0) {
+    return TYPE_YCbCr_8;
+  }
+  else if (strcmp(PILmode, "YCC") == 0) {
+    return TYPE_YCbCr_8;
+  }
+
+  else {
+    // take a wild guess... but you probably should fail instead.
+    return TYPE_GRAY_8; // so there's no buffer overrun...
+  }
+}
+
+int
+pyCMSdoTransform (Imaging im, Imaging imOut, cmsHTRANSFORM hTransform) {
+  int i;
+
+  if (im->xsize > imOut->xsize) {
+    return -1;
+  }
+  if (im->ysize > imOut->ysize) {
+    return -1;
+  }
+
+  Py_BEGIN_ALLOW_THREADS
+
+  for (i=0; i < im->ysize; i++)
+  {
+    cmsDoTransform(hTransform, im->image[i],
+                              imOut->image[i],
+                              im->xsize);
+  }
+
+  Py_END_ALLOW_THREADS
+
+  return 0;
+}
+
+cmsHTRANSFORM
+_buildTransform (cmsHPROFILE hInputProfile, cmsHPROFILE hOutputProfile, char *sInMode, char *sOutMode, int iRenderingIntent) {
+  cmsHTRANSFORM hTransform;
+
+  cmsErrorAction(cmsERROR_HANDLER);
+
+  Py_BEGIN_ALLOW_THREADS
+
+  // create the transform
+  hTransform = cmsCreateTransform(hInputProfile,
+                                 findLCMStype(sInMode),
+                                 hOutputProfile,
+                                 findLCMStype(sOutMode),
+                                 iRenderingIntent, 0);
+
+  Py_END_ALLOW_THREADS
+
+  return hTransform;
+}
+
+cmsHTRANSFORM
+_buildProofTransform(cmsHPROFILE hInputProfile, cmsHPROFILE hOutputProfile, cmsHPROFILE hDisplayProfile, char *sInMode, char *sOutMode, int iRenderingIntent, int iDisplayIntent) {
+  cmsHTRANSFORM hTransform;
+
+  cmsErrorAction(cmsERROR_HANDLER);
+
+  Py_BEGIN_ALLOW_THREADS
+
+  // create the transform
+  hTransform =  cmsCreateProofingTransform(hInputProfile,
+                          findLCMStype(sInMode),
+                          hOutputProfile,
+                          findLCMStype(sOutMode),
+                          hDisplayProfile,
+                          iRenderingIntent,
+                          iDisplayIntent,
+                          0);
+
+  Py_END_ALLOW_THREADS
+
+  return hTransform;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Python callable functions
+/////////////////////////////////////////////////////////////////////////////
+static PyObject *
+versions (PyObject *self, PyObject *args) {
+  return Py_BuildValue ("ssss", PYCMSVERSION, LITTLECMSVERSION, PYTHONVERSION, PILVERSION);
+}
+
+static PyObject *
+about (PyObject *self, PyObject *args) {
+  return Py_BuildValue("s", COPYRIGHTINFO);
+}
+
+static PyObject *
+copyright (PyObject *self, PyObject *args) {
+  return about(self, args);
+}
+
+static PyObject *
+getOpenProfile(PyObject *self, PyObject *args) {
+  char *sProfile = NULL;
+
+  cmsHPROFILE hProfile;
+
+  if (!PyArg_ParseTuple(args, "s", &sProfile)) {
+   return Py_BuildValue("s", "ERROR: Could not parse argument tuple passed to pyCMSdll.getOpenProfile()");
+  }
+
+  cmsErrorAction(cmsERROR_HANDLER);
+
+  hProfile = cmsOpenProfileFromFile(sProfile, "r");
+
+  return Py_BuildValue("O", PyCObject_FromVoidPtr(hProfile, cmsCloseProfile));
+}
+
+static PyObject *
+buildTransform(PyObject *self, PyObject *args) {
+  char *sInputProfile;
+  char *sOutputProfile;
+  char *sInMode;
+  char *sOutMode;
+  int iRenderingIntent = 0;
+  cmsHPROFILE hInputProfile, hOutputProfile;
+  cmsHTRANSFORM transform;
+
+  if (!PyArg_ParseTuple(args, "ssss|i", &sInputProfile, &sOutputProfile, &sInMode, &sOutMode, &iRenderingIntent)) {
+   return Py_BuildValue("s", "ERROR: Could not parse argument tuple passed to pyCMSdll.buildTransform()");
+  }
+
+  cmsErrorAction(cmsERROR_HANDLER);
+
+  hInputProfile  = cmsOpenProfileFromFile(sInputProfile, "r");
+  hOutputProfile = cmsOpenProfileFromFile(sOutputProfile, "r");
+
+  transform = _buildTransform(hInputProfile, hOutputProfile, sInMode, sOutMode, iRenderingIntent);
+
+  cmsCloseProfile(hInputProfile);
+  cmsCloseProfile(hOutputProfile);
+
+  return PyCObject_FromVoidPtr(transform, cmsDeleteTransform); // this may not be right way to call the destructor...?
+}
+
+static PyObject *
+buildTransformFromOpenProfiles (PyObject *self, PyObject *args) {
+  char *sInMode;
+  char *sOutMode;
+  int iRenderingIntent = 0;
+  void *pInputProfile;
+  void *pOutputProfile;
+  cmsHPROFILE hInputProfile, hOutputProfile;
+  void *hTransformPointer = NULL;
+  cmsHTRANSFORM transform;
+
+  if (!PyArg_ParseTuple(args, "OOss|i", &pInputProfile, &pOutputProfile, &sInMode, &sOutMode, &iRenderingIntent)) {
+   return Py_BuildValue("s", "ERROR: Could not parse argument tuple passed to pyCMSdll.buildTransformFromOpenProfiles()");
+  }
+
+  cmsErrorAction(cmsERROR_HANDLER);
+
+  hInputProfile = (cmsHPROFILE) PyCObject_AsVoidPtr(pInputProfile);
+  hOutputProfile = (cmsHPROFILE) PyCObject_AsVoidPtr(pOutputProfile);
+
+  transform = _buildTransform(hInputProfile, hOutputProfile, sInMode, sOutMode, iRenderingIntent);
+
+  // we don't have to close these profiles... but do we have to decref them?
+
+  return PyCObject_FromVoidPtr(transform, cmsDeleteTransform); // this may not be right way to call the destructor...?
+}
+
+static PyObject *
+buildProofTransform(PyObject *self, PyObject *args) {
+  char *sInputProfile;
+  char *sOutputProfile;
+  char *sDisplayProfile;
+  char *sInMode;
+  char *sOutMode;
+  int iRenderingIntent = 0;
+  int iDisplayIntent = 0;
+  cmsHTRANSFORM transform;
+
+  cmsHPROFILE hInputProfile, hOutputProfile, hDisplayProfile;
+
+  if (!PyArg_ParseTuple(args, "sssss|ii", &sInputProfile, &sOutputProfile, &sDisplayProfile, &sInMode, &sOutMode, &iRenderingIntent, &iDisplayIntent)) {
+   return Py_BuildValue("s", "ERROR: Could not parse argument tuple passed to pyCMSdll.buildProofTransform()");
+  }
+
+  cmsErrorAction(cmsERROR_HANDLER);
+
+  // open the input and output profiles
+  hInputProfile  = cmsOpenProfileFromFile(sInputProfile, "r");
+  hOutputProfile = cmsOpenProfileFromFile(sOutputProfile, "r");
+  hDisplayProfile = cmsOpenProfileFromFile(sDisplayProfile, "r");
+
+  transform = _buildProofTransform(hInputProfile, hOutputProfile, hDisplayProfile, sInMode, sOutMode, iRenderingIntent, iDisplayIntent);
+
+  cmsCloseProfile(hInputProfile);
+  cmsCloseProfile(hOutputProfile);
+  cmsCloseProfile(hDisplayProfile);
+
+  return PyCObject_FromVoidPtr(transform, cmsDeleteTransform); // this may not be right way to call the destructor...?
+
+}
+
+static PyObject *
+buildProofTransformFromOpenProfiles(PyObject *self, PyObject *args) {
+  char *sInMode;
+  char *sOutMode;
+  int iRenderingIntent = 0;
+  int iDisplayIntent = 0;
+  void *pInputProfile;
+  void *pOutputProfile;
+  void *pDisplayProfile;
+  cmsHTRANSFORM transform;
+
+  cmsHPROFILE hInputProfile, hOutputProfile, hDisplayProfile;
+
+  if (!PyArg_ParseTuple(args, "OOOss|ii", &pInputProfile, &pOutputProfile, &pDisplayProfile, &sInMode, &sOutMode, &iRenderingIntent, &iDisplayIntent)) {
+   return Py_BuildValue("s", "ERROR: Could not parse argument tuple passed to pyCMSdll.buildProofTransform()");
+  }
+
+  cmsErrorAction(cmsERROR_HANDLER);
+
+  hInputProfile = (cmsHPROFILE) PyCObject_AsVoidPtr(pInputProfile);
+  hOutputProfile = (cmsHPROFILE) PyCObject_AsVoidPtr(pOutputProfile);
+  hDisplayProfile = (cmsHPROFILE) PyCObject_AsVoidPtr(pDisplayProfile);
+
+  transform = _buildProofTransform(hInputProfile, hOutputProfile, hDisplayProfile, sInMode, sOutMode, iRenderingIntent, iDisplayIntent);
+
+  // we don't have to close these profiles, but do we have to decref them?
+
+  return PyCObject_FromVoidPtr(transform, cmsDeleteTransform); // this may not be right way to call the destructor...?
+}
+
+static PyObject *
+applyTransform(PyObject *self, PyObject *args) {
+  long idIn;
+  long idOut;
+  void *hTransformPointer;
+  cmsHTRANSFORM hTransform;
+  Imaging im;
+  Imaging imOut;
+
+  int result;
+
+  if (!PyArg_ParseTuple(args, "llO", &idIn, &idOut, &hTransformPointer)) {
+    return Py_BuildValue("s", "ERROR: Could not parse the data passed to pyCMSdll.applyTransform()");
+  }
+
+  im = (Imaging) idIn;
+  imOut = (Imaging) idOut;
+
+  cmsErrorAction(cmsERROR_HANDLER);
+
+  hTransform = (cmsHTRANSFORM) PyCObject_AsVoidPtr(hTransformPointer);
+
+  result = pyCMSdoTransform(im, imOut, hTransform);
+
+  return Py_BuildValue("i", result);
+}
+
+static PyObject *
+profileToProfile(PyObject *self, PyObject *args)
+{
+  Imaging im;
+  Imaging imOut;
+  long idIn;
+  long idOut = 0L;
+  char *sInputProfile = NULL;
+  char *sOutputProfile = NULL;
+  int iRenderingIntent = 0;
+  char *inMode;
+  char *outMode;
+  int result;
+  cmsHPROFILE hInputProfile, hOutputProfile;
+  cmsHTRANSFORM hTransform;
+
+  // parse the PyObject arguments, assign to variables accordingly
+  if (!PyArg_ParseTuple(args, "llss|i", &idIn, &idOut, &sInputProfile, &sOutputProfile, &iRenderingIntent)) {
+      return Py_BuildValue("s", "ERROR: Could not parse the argument tuple passed to pyCMSdll.profileToProfile()");
+  }
+
+  im = (Imaging) idIn;
+
+  if (idOut != 0L) {
+    imOut = (Imaging) idOut;
+  }
+
+  cmsErrorAction(cmsERROR_HANDLER);
+
+  // Check the modes of imIn and imOut to set the color type for the transform
+  // Note that the modes do NOT have to be the same, as long as they are each
+  //    supported by the relevant profile specified
+
+  inMode = im->mode;
+  if (idOut == 0L) {
+    outMode = inMode;
+  }
+  else {
+    outMode = imOut->mode;
+  }
+
+  // open the input and output profiles
+  hInputProfile  = cmsOpenProfileFromFile(sInputProfile, "r");
+  hOutputProfile = cmsOpenProfileFromFile(sOutputProfile, "r");
+
+  // create the transform
+  hTransform = _buildTransform(hInputProfile, hOutputProfile, inMode, outMode, iRenderingIntent);
+
+  // apply the transform to imOut (or directly to im in place if idOut is not supplied)
+  if (idOut != 0L) {
+    result = pyCMSdoTransform (im, imOut, hTransform);
+  }
+  else {
+    result = pyCMSdoTransform (im, im, hTransform);
+  }
+
+  // free the transform and profiles
+  cmsDeleteTransform(hTransform);
+  cmsCloseProfile(hInputProfile);
+  cmsCloseProfile(hOutputProfile);
+
+  // return 0 on success, -1 on failure
+  return Py_BuildValue("i", result);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Python-Callable On-The-Fly profile creation functions
+//////////////////////////////////////////////////////////////////////////////
+static PyObject *
+createProfile(PyObject *self, PyObject *args)
+{
+  char *sColorSpace;
+  cmsHPROFILE hProfile;
+  int iColorTemp = 0;
+  LPcmsCIExyY whitePoint = NULL;
+  int result;
+
+  if (!PyArg_ParseTuple(args, "s|i", &sColorSpace, &iColorTemp)) {
+      return Py_BuildValue("s", "ERROR: Could not parse the argument tuple passed to pyCMSdll.createProfile()");
+  }
+
+  cmsErrorAction(cmsERROR_HANDLER);
+
+  if (strcmp(sColorSpace, "LAB") == 0) {
+    if (iColorTemp > 0) {
+      result = cmsWhitePointFromTemp(iColorTemp, whitePoint);
+      if (result == FALSE) {
+        return Py_BuildValue("s", "ERROR: Could not calculate white point from color temperature provided, must be integer in degrees Kelvin");
+      }
+      hProfile = cmsCreateLabProfile(whitePoint);
+    }
+    else {
+      hProfile = cmsCreateLabProfile(NULL);
+    }
+  }
+  else if (strcmp(sColorSpace, "XYZ") == 0) {
+    hProfile = cmsCreateXYZProfile();
+  }
+  else if (strcmp(sColorSpace, "sRGB") == 0) {
+    hProfile = cmsCreate_sRGBProfile();
+  }
+  else {
+    return Py_BuildValue("s", "ERROR: Color space requested is not valid for built-in profiles");
+  }
+
+  return Py_BuildValue("O", PyCObject_FromVoidPtr(hProfile, cmsCloseProfile));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Python callable profile information functions
+//////////////////////////////////////////////////////////////////////////////
+static PyObject *
+getProfileName(PyObject *self, PyObject *args)
+{
+  // I've had some intermittant problems with this function and getProfileInfo... look at them closer
+  char *sProfile;
+  char name[1024];
+
+  int closeProfile = FALSE;
+
+  cmsHPROFILE hProfile;
+
+  if (!PyArg_ParseTuple(args, "s", &sProfile)) {
+    if (!PyArg_ParseTuple(args, "O", &hProfile)) {
+      return Py_BuildValue("s", "ERROR: Could not parse the argument tuple passed to pyCMSdll.getProfileName()");
+    }
+  }
+  else {
+    hProfile = cmsOpenProfileFromFile(sProfile, "r");
+    closeProfile = TRUE;
+  }
+
+  // is there a better way to do this?  I can't seem to work with the const char* return value otherwise
+  sprintf(name, "%s\n", cmsTakeProductName(hProfile));
+
+  if (closeProfile == TRUE) {
+    cmsCloseProfile(hProfile);
+  }
+
+  return Py_BuildValue("s", name);
+}
+
+static PyObject *
+getProfileInfo(PyObject *self, PyObject *args)
+{
+  char *sProfile;
+  char info[4096];
+  int closeProfile = FALSE;
+
+  cmsHPROFILE hProfile;
+
+  if (!PyArg_ParseTuple(args, "s", &sProfile)) {
+    if (!PyArg_ParseTuple(args, "O", &hProfile)) {
+      return Py_BuildValue("s", "ERROR: Could not parse the argument tuple passed to pyCMSdll.getProfileInfo()");
+    }
+  }
+  else {
+    hProfile = cmsOpenProfileFromFile(sProfile, "r");
+    closeProfile = TRUE;
+  }
+
+  // is there a better way to do this?  I can't seem to work with the const char* return value otherwise
+  sprintf(info, "%s\n", cmsTakeProductInfo(hProfile));
+
+  if (closeProfile == TRUE) {
+    cmsCloseProfile(hProfile);
+  }
+
+  return Py_BuildValue("s", info);
+}
+
+static PyObject *
+getDefaultIntent(PyObject *self, PyObject *args)
+{
+  char *sProfile;
+  int intent = 0;
+  int closeProfile = FALSE;
+
+  cmsHPROFILE hProfile;
+
+  if (!PyArg_ParseTuple(args, "s", &sProfile)) {
+    if (!PyArg_ParseTuple(args, "O", &hProfile)) {
+      return Py_BuildValue("s", "ERROR: Could not parse the argument tuple passed to pyCMSdll.getDefaultIntent()");
+    }
+  }
+  else {
+    hProfile = cmsOpenProfileFromFile(sProfile, "r");
+    closeProfile = TRUE;
+  }
+
+  intent =  cmsTakeRenderingIntent(hProfile);
+
+  if (closeProfile == TRUE) {
+    cmsCloseProfile(hProfile);
+  }
+
+  return Py_BuildValue("i", intent);
+}
+
+static PyObject *
+isIntentSupported(PyObject *self, PyObject *args)
+{
+  char *sProfile;
+  int iIntent;
+  int iDirection;
+  int closeProfile = FALSE;
+
+  int result;
+
+  cmsHPROFILE hProfile;
+
+  if (!PyArg_ParseTuple(args, "sii", &sProfile, &iIntent, &iDirection)) {
+    if (!PyArg_ParseTuple(args, "Oii", &hProfile, &iIntent, &iDirection)) {
+      return Py_BuildValue("s", "ERROR: Could not parse the argument tuple passed to pyCMSdll.isIntentSupported()");
+    }
+  }
+  else {
+    hProfile = cmsOpenProfileFromFile(sProfile, "r");
+    closeProfile = TRUE;
+  }
+
+  result =  cmsIsIntentSupported(hProfile, iIntent, iDirection);
+
+  if (closeProfile == TRUE) {
+    cmsCloseProfile(hProfile);
+  }
+
+  if (result == TRUE) {
+    return Py_BuildValue("i", 1);
+  }
+  else {
+    return Py_BuildValue("i", -1);
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Python interface setup
+/////////////////////////////////////////////////////////////////////////////
+static PyMethodDef pyCMSdll_methods[] = {
+  // pyCMS info
+  {"versions", versions, 1, "pyCMSdll.versions() returs tuple of pyCMSversion, littleCMSversion, pythonVersion that it was compiled with (don't trust this 100%, they must be set manually in the source code for now)"},
+  {"about", about, 1, "pyCMSdll.about() returns info about pyCMSdll"},
+  {"copyright", copyright, 1, "pyCMSdll.copyright() returns info about pyCMSdll"},
+
+  // profile and transform functions
+  {"profileToProfile", profileToProfile, 1, "pyCMSdll.profileToProfile (idIn, idOut, InputProfile, OutputProfile, [RenderingIntent]) returns 0 on success, -1 on failure.  If idOut is the same as idIn, idIn is modified in place, otherwise the results are applied to idOut"},
+  {"getOpenProfile", getOpenProfile, 1, "pyCMSdll.getOpenProfile (profileName) returns a handle to an open pyCMS profile that can be used to build a transform"},
+  {"buildTransform", buildTransform, 1, "pyCMSdll.buildTransform (InputProfile, OutputProfile, InMode, OutMode, [RenderingIntent]) returns a handle to a pre-computed ICC transform that can be used for processing multiple images, saving calculation time"},
+  {"buildProofTransform", buildProofTransform, 1, "pyCMSdll.buildProofTransform (InputProfile, OutputProfile, DisplayProfile, InMode, OutMode, [RenderingIntent], [DisplayRenderingIntent]) returns a handle to a pre-computed soft-proofing (simulating the output device capabilities on the display device) ICC transform that can be used for processing multiple images, saving calculation time"},
+  {"buildProofTransformFromOpenProfiles", buildProofTransformFromOpenProfiles, 1, "pyCMSdll.buildProofTransformFromOpenProfiles(InputProfile, OutputProfile, DisplayProfile, InMode, OutMode, [RenderingIntent], [DisplayRenderingIntent]) returns a handle to a pre-computed soft-proofing transform.  Profiles should be HANDLES, not pathnames."},
+  {"applyTransform", applyTransform, 1, "pyCMSdll.applyTransform (idIn, idOut, hTransform) applys a pre-calcuated transform (from pyCMSdll.buildTransform) to an image.  If idIn and idOut are the same, it modifies the image in place, otherwise the new image is built in idOut.  Returns 0 on success, -1 on failure"},
+  {"buildTransformFromOpenProfiles", buildTransformFromOpenProfiles, 1, "pyCMSdll.buildTransformFromOpenProfiles (InputProfile, OutputProfile, InMode, OutMode, RenderingIntent) returns a handle to a pre-computed ICC transform that can be used for processing multiple images, saving calculation time"},
+
+  // on-the-fly profile creation functions
+  {"createProfile", createProfile, 1, "pyCMSdll.createProfile (colorSpace, [colorTemp]) returns a handle to an open profile created on the fly.  colorSpace can be 'LAB', 'XYZ', or 'xRGB'.  If using LAB, you can specify a white point color temperature, or let it default to D50 (5000K)"},
+
+  // profile info functions
+  {"getProfileName", getProfileName, 1, "pyCMSdll.getProfileName (profile) returns the internal name of the profile"},
+  {"getProfileInfo", getProfileInfo, 1, "pyCMSdll.getProfileInfo (profile) returns additional information about the profile"},
+  {"getDefaultIntent", getDefaultIntent, 1, "pyCMSdll.getDefaultIntent (profile) returns the default rendering intent of the profile (as an integer)"},
+  {"isIntentSupported", isIntentSupported, 1, "pyCMSdll.isIntentSupported (profile, intent, direction) returns 1 if profile supports that intent, -1 if it doesnt.  Direction is what the profile is being used for: INPUT = 0, OUTPUT = 1, PROOF = 2"},
+
+  {NULL, NULL}
+};
+
+void initpyCMSdll(void)
+{
+  Py_InitModule("pyCMSdll", pyCMSdll_methods);
+}

Property changes on: src/extentions/pycms/pyCMSdll.c
___________________________________________________________________
Name: svn:eol-style
  + native

Index: src/share/icons/CrystalSVG/context/context_image_gray_disabled.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = image/png

Property changes on: src/share/icons/CrystalSVG/context/context_image_gray_disabled.png
___________________________________________________________________
Name: svn:mime-type
  + image/png

Index: src/share/icons/CrystalSVG/context/context_image_gray.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = image/png

Property changes on: src/share/icons/CrystalSVG/context/context_image_gray.png
___________________________________________________________________
Name: svn:mime-type
  + image/png

Index: src/share/icons/CrystalSVG/context/context_image_cmyk.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = image/png

Property changes on: src/share/icons/CrystalSVG/context/context_image_cmyk.png
___________________________________________________________________
Name: svn:mime-type
  + image/png

Index: src/share/icons/CrystalSVG/context/context_image_cmyk_disabled.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = image/png

Property changes on: src/share/icons/CrystalSVG/context/context_image_cmyk_disabled.png
___________________________________________________________________
Name: svn:mime-type
  + image/png

Index: src/share/icons/CrystalSVG/context/context_image_bw_disabled.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = image/png

Property changes on: src/share/icons/CrystalSVG/context/context_image_bw_disabled.png
___________________________________________________________________
Name: svn:mime-type
  + image/png

Index: src/share/icons/CrystalSVG/context/context_image_rgb_disabled.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = image/png

Property changes on: src/share/icons/CrystalSVG/context/context_image_rgb_disabled.png
___________________________________________________________________
Name: svn:mime-type
  + image/png

Index: src/share/icons/CrystalSVG/context/context_image_bw.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = image/png

Property changes on: src/share/icons/CrystalSVG/context/context_image_bw.png
___________________________________________________________________
Name: svn:mime-type
  + image/png

Index: src/share/icons/CrystalSVG/context/context_image_rgb.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = image/png

Property changes on: src/share/icons/CrystalSVG/context/context_image_rgb.png
___________________________________________________________________
Name: svn:mime-type
  + image/png

Index: setup.cfg
===================================================================
--- setup.cfg   (.../trunk/sK1) (revision 560)
+++ setup.cfg   (.../branches/hackontest/sK1)   (revision 560)
@@ -2,5 +2,5 @@
release = 0
packager = Igor Novikov <[email protected]>
provides = sk1
-requires = python-imaging libtcl8.5 libtk8.5 python-lcms python-reportlab
+requires = python-imaging libtcl8.5 libtk8.5 python-lcms python-reportlab liblcms