~ubuntu-branches/ubuntu/wily/python-imaging/wily

« back to all changes in this revision

Viewing changes to .pc/git-updates.diff/PIL/ImageCms.py

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-01-31 20:49:20 UTC
  • mfrom: (27.1.1 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20130131204920-b5zshy6vgfvdionl
Tags: 1.1.7+1.7.8-1ubuntu1
Rewrite build dependencies to allow cross builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# The Python Imaging Library.
 
3
# $Id$
 
4
#
 
5
# optional color managment support, based on Kevin Cazabon's PyCMS
 
6
# library.
 
7
#
 
8
# History:
 
9
# 2009-03-08 fl   Added to PIL.
 
10
#
 
11
# Copyright (C) 2002-2003 Kevin Cazabon
 
12
# Copyright (c) 2009 by Fredrik Lundh
 
13
#
 
14
# See the README file for information on usage and redistribution.  See
 
15
# below for the original description.
 
16
#
 
17
 
 
18
DESCRIPTION = """
 
19
pyCMS
 
20
 
 
21
    a Python / PIL interface to the littleCMS ICC Color Management System
 
22
    Copyright (C) 2002-2003 Kevin Cazabon
 
23
    kevin@cazabon.com
 
24
    http://www.cazabon.com
 
25
 
 
26
    pyCMS home page:  http://www.cazabon.com/pyCMS
 
27
    littleCMS home page:  http://www.littlecms.com
 
28
    (littleCMS is Copyright (C) 1998-2001 Marti Maria)
 
29
 
 
30
    Originally released under LGPL.  Graciously donated to PIL in
 
31
    March 2009, for distribution under the standard PIL license
 
32
 
 
33
    The pyCMS.py module provides a "clean" interface between Python/PIL and
 
34
    pyCMSdll, taking care of some of the more complex handling of the direct
 
35
    pyCMSdll functions, as well as error-checking and making sure that all
 
36
    relevant data is kept together.
 
37
 
 
38
    While it is possible to call pyCMSdll functions directly, it's not highly
 
39
    recommended.
 
40
 
 
41
    Version History:
 
42
 
 
43
        0.1.0 pil mod   March 10, 2009
 
44
 
 
45
                        Renamed display profile to proof profile. The proof
 
46
                        profile is the profile of the device that is being
 
47
                        simulated, not the profile of the device which is
 
48
                        actually used to display/print the final simulation
 
49
                        (that'd be the output profile) - also see LCMSAPI.txt
 
50
                        input colorspace -> using 'renderingIntent' -> proof
 
51
                        colorspace -> using 'proofRenderingIntent' -> output
 
52
                        colorspace
 
53
 
 
54
                        Added LCMS FLAGS support.
 
55
                        Added FLAGS["SOFTPROOFING"] as default flag for
 
56
                        buildProofTransform (otherwise the proof profile/intent
 
57
                        would be ignored).
 
58
 
 
59
        0.1.0 pil       March 2009 - added to PIL, as PIL.ImageCms
 
60
 
 
61
        0.0.2 alpha     Jan 6, 2002
 
62
 
 
63
                        Added try/except statements arount type() checks of
 
64
                        potential CObjects... Python won't let you use type()
 
65
                        on them, and raises a TypeError (stupid, if you ask me!)
 
66
 
 
67
                        Added buildProofTransformFromOpenProfiles() function.
 
68
                        Additional fixes in DLL, see DLL code for details.
 
69
 
 
70
        0.0.1 alpha     first public release, Dec. 26, 2002
 
71
 
 
72
    Known to-do list with current version (of Python interface, not pyCMSdll):
 
73
 
 
74
        none
 
75
 
 
76
"""
 
77
 
 
78
VERSION = "0.1.0 pil"
 
79
 
 
80
# --------------------------------------------------------------------.
 
81
 
 
82
import Image
 
83
import _imagingcms
 
84
 
 
85
core = _imagingcms
 
86
 
 
87
#
 
88
# intent/direction values
 
89
 
 
90
INTENT_PERCEPTUAL = 0
 
91
INTENT_RELATIVE_COLORIMETRIC = 1
 
92
INTENT_SATURATION = 2
 
93
INTENT_ABSOLUTE_COLORIMETRIC = 3
 
94
 
 
95
DIRECTION_INPUT = 0
 
96
DIRECTION_OUTPUT = 1
 
97
DIRECTION_PROOF = 2
 
98
 
 
99
#
 
100
# flags
 
101
 
 
102
FLAGS = {
 
103
    "MATRIXINPUT": 1,
 
104
    "MATRIXOUTPUT": 2,
 
105
    "MATRIXONLY": (1|2),
 
106
    "NOWHITEONWHITEFIXUP": 4, # Don't hot fix scum dot
 
107
    "NOPRELINEARIZATION": 16, # Don't create prelinearization tables on precalculated transforms (internal use)
 
108
    "GUESSDEVICECLASS": 32, # Guess device class (for transform2devicelink)
 
109
    "NOTCACHE": 64, # Inhibit 1-pixel cache
 
110
    "NOTPRECALC": 256,
 
111
    "NULLTRANSFORM": 512, # Don't transform anyway
 
112
    "HIGHRESPRECALC": 1024, # Use more memory to give better accurancy
 
113
    "LOWRESPRECALC": 2048, # Use less memory to minimize resouces
 
114
    "WHITEBLACKCOMPENSATION": 8192,
 
115
    "BLACKPOINTCOMPENSATION": 8192,
 
116
    "GAMUTCHECK": 4096, # Out of Gamut alarm
 
117
    "SOFTPROOFING": 16384, # Do softproofing
 
118
    "PRESERVEBLACK": 32768, # Black preservation
 
119
    "NODEFAULTRESOURCEDEF": 16777216, # CRD special
 
120
    "GRIDPOINTS": lambda n: ((n) & 0xFF) << 16 # Gridpoints
 
121
}
 
122
 
 
123
_MAX_FLAG = 0
 
124
for flag in FLAGS.values():
 
125
    if isinstance(flag, type(0)):
 
126
        _MAX_FLAG = _MAX_FLAG | flag
 
127
 
 
128
# --------------------------------------------------------------------.
 
129
# Experimental PIL-level API
 
130
# --------------------------------------------------------------------.
 
131
 
 
132
##
 
133
# Profile.
 
134
 
 
135
class ImageCmsProfile:
 
136
 
 
137
    def __init__(self, profile):
 
138
        # accepts a string (filename), a file-like object, or a low-level
 
139
        # profile object
 
140
        if Image.isStringType(profile):
 
141
            self._set(core.profile_open(profile), profile)
 
142
        elif hasattr(profile, "read"):
 
143
            self._set(core.profile_fromstring(profile.read()))
 
144
        else:
 
145
            self._set(profile) # assume it's already a profile
 
146
 
 
147
    def _set(self, profile, filename=None):
 
148
        self.profile = profile
 
149
        self.filename = filename
 
150
        if profile:
 
151
            self.product_name = profile.product_name
 
152
            self.product_info = profile.product_info
 
153
        else:
 
154
            self.product_name = None
 
155
            self.product_info = None
 
156
 
 
157
##
 
158
# Transform.  This can be used with the procedural API, or with the
 
159
# standard {@link Image.point} method.
 
160
 
 
161
class ImageCmsTransform(Image.ImagePointHandler):
 
162
 
 
163
    def __init__(self, input, output, input_mode, output_mode,
 
164
                 intent=INTENT_PERCEPTUAL,
 
165
                 proof=None, proof_intent=INTENT_ABSOLUTE_COLORIMETRIC, flags=0):
 
166
        if proof is None:
 
167
            self.transform = core.buildTransform(
 
168
                input.profile, output.profile,
 
169
                input_mode, output_mode,
 
170
                intent,
 
171
                flags
 
172
                )
 
173
        else:
 
174
            self.transform = core.buildProofTransform(
 
175
                input.profile, output.profile, proof.profile,
 
176
                input_mode, output_mode,
 
177
                intent, proof_intent,
 
178
                flags
 
179
                )
 
180
        # Note: inputMode and outputMode are for pyCMS compatibility only
 
181
        self.input_mode = self.inputMode = input_mode
 
182
        self.output_mode = self.outputMode = output_mode
 
183
 
 
184
    def point(self, im):
 
185
        return self.apply(im)
 
186
 
 
187
    def apply(self, im, imOut=None):
 
188
        im.load()
 
189
        if imOut is None:
 
190
            imOut = Image.new(self.output_mode, im.size, None)
 
191
        result = self.transform.apply(im.im.id, imOut.im.id)
 
192
        return imOut
 
193
 
 
194
    def apply_in_place(self, im):
 
195
        im.load()
 
196
        if im.mode != self.output_mode:
 
197
            raise ValueError("mode mismatch") # wrong output mode
 
198
        result = self.transform.apply(im.im.id, im.im.id)
 
199
        return im
 
200
 
 
201
##
 
202
# (experimental) Fetches the profile for the current display device.
 
203
# Returns None if the profile is not known.
 
204
 
 
205
def get_display_profile(handle=None):
 
206
    import sys
 
207
    if sys.platform == "win32":
 
208
        import ImageWin
 
209
        if isinstance(handle, ImageWin.HDC):
 
210
            profile = core.get_display_profile_win32(handle, 1)
 
211
        else:
 
212
            profile = core.get_display_profile_win32(handle or 0)
 
213
    else:
 
214
        try:
 
215
            get = _imagingcms.get_display_profile
 
216
        except AttributeError:
 
217
            return None
 
218
        else:
 
219
            profile = get()
 
220
    return ImageCmsProfile(profile)
 
221
 
 
222
# --------------------------------------------------------------------.
 
223
# pyCMS compatible layer
 
224
# --------------------------------------------------------------------.
 
225
 
 
226
##
 
227
# (pyCMS) Exception class.  This is used for all errors in the pyCMS API.
 
228
 
 
229
class PyCMSError(Exception):
 
230
    pass
 
231
 
 
232
##
 
233
# (pyCMS) Applies an ICC transformation to a given image, mapping from
 
234
# inputProfile to outputProfile.
 
235
 
 
236
def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PERCEPTUAL, outputMode=None, inPlace=0, flags=0):
 
237
    """
 
238
    ImageCms.profileToProfile(im, inputProfile, outputProfile,
 
239
        [renderingIntent], [outputMode], [inPlace])
 
240
 
 
241
    Returns either None or a new PIL image object, depending on value of
 
242
    inPlace (see below).
 
243
 
 
244
    im = an open PIL image object (i.e. Image.new(...) or
 
245
        Image.open(...), etc.)
 
246
    inputProfile = string, as a valid filename path to the ICC input
 
247
        profile you wish to use for this image, or a profile object
 
248
    outputProfile = string, as a valid filename path to the ICC output
 
249
        profile you wish to use for this image, or a profile object
 
250
    renderingIntent = integer (0-3) specifying the rendering intent you
 
251
        wish to use for the transform
 
252
        INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
 
253
        INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
 
254
        INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
 
255
        INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
 
256
 
 
257
        see the pyCMS documentation for details on rendering intents and
 
258
        what they do.
 
259
    outputMode = a valid PIL mode for the output image (i.e. "RGB", "CMYK",
 
260
        etc.).  Note: if rendering the image "inPlace", outputMode MUST be
 
261
        the same mode as the input, or omitted completely.  If omitted, the
 
262
        outputMode will be the same as the mode of the input image (im.mode)
 
263
    inPlace = BOOL (1 = TRUE, None or 0 = FALSE).  If TRUE, the original
 
264
        image is modified in-place, and None is returned.  If FALSE
 
265
        (default), a new Image object is returned with the transform
 
266
        applied.
 
267
    flags = integer (0-...) specifying additional flags
 
268
 
 
269
    If the input or output profiles specified are not valid filenames, a
 
270
    PyCMSError will be raised.  If inPlace == TRUE and outputMode != im.mode,
 
271
    a PyCMSError will be raised.  If an error occurs during application of
 
272
    the profiles, a PyCMSError will be raised.  If outputMode is not a mode
 
273
    supported by the outputProfile (or by pyCMS), a PyCMSError will be
 
274
    raised.
 
275
 
 
276
    This function applies an ICC transformation to im from inputProfile's
 
277
    color space to outputProfile's color space using the specified rendering
 
278
    intent to decide how to handle out-of-gamut colors.
 
279
 
 
280
    OutputMode can be used to specify that a color mode conversion is to
 
281
    be done using these profiles, but the specified profiles must be able
 
282
    to handle that mode.  I.e., if converting im from RGB to CMYK using
 
283
    profiles, the input profile must handle RGB data, and the output
 
284
    profile must handle CMYK data.
 
285
 
 
286
    """
 
287
 
 
288
    if outputMode is None:
 
289
        outputMode = im.mode
 
290
 
 
291
    if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
 
292
        raise PyCMSError("renderingIntent must be an integer between 0 and 3")
 
293
 
 
294
    if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
 
295
        raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
 
296
 
 
297
    try:
 
298
        if not isinstance(inputProfile, ImageCmsProfile):
 
299
            inputProfile = ImageCmsProfile(inputProfile)
 
300
        if not isinstance(outputProfile, ImageCmsProfile):
 
301
            outputProfile = ImageCmsProfile(outputProfile)
 
302
        transform = ImageCmsTransform(
 
303
            inputProfile, outputProfile, im.mode, outputMode, renderingIntent, flags=flags
 
304
            )
 
305
        if inPlace:
 
306
            transform.apply_in_place(im)
 
307
            imOut = None
 
308
        else:
 
309
            imOut = transform.apply(im)
 
310
    except (IOError, TypeError, ValueError), v:
 
311
        raise PyCMSError(v)
 
312
 
 
313
    return imOut
 
314
 
 
315
##
 
316
# (pyCMS) Opens an ICC profile file.
 
317
 
 
318
def getOpenProfile(profileFilename):
 
319
    """
 
320
    ImageCms.getOpenProfile(profileFilename)
 
321
 
 
322
    Returns a CmsProfile class object.
 
323
 
 
324
    profileFilename = string, as a valid filename path to the ICC profile
 
325
        you wish to open, or a file-like object.
 
326
 
 
327
    The PyCMSProfile object can be passed back into pyCMS for use in creating
 
328
    transforms and such (as in ImageCms.buildTransformFromOpenProfiles()).
 
329
 
 
330
    If profileFilename is not a vaild filename for an ICC profile, a
 
331
    PyCMSError will be raised.
 
332
 
 
333
    """
 
334
 
 
335
    try:
 
336
        return ImageCmsProfile(profileFilename)
 
337
    except (IOError, TypeError, ValueError), v:
 
338
        raise PyCMSError(v)
 
339
 
 
340
##
 
341
# (pyCMS) Builds an ICC transform mapping from the inputProfile to the
 
342
# outputProfile.  Use applyTransform to apply the transform to a given
 
343
# image.
 
344
 
 
345
def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, flags=0):
 
346
    """
 
347
    ImageCms.buildTransform(inputProfile, outputProfile, inMode, outMode,
 
348
        [renderingIntent])
 
349
 
 
350
    Returns a CmsTransform class object.
 
351
 
 
352
    inputProfile = string, as a valid filename path to the ICC input
 
353
        profile you wish to use for this transform, or a profile object
 
354
    outputProfile = string, as a valid filename path to the ICC output
 
355
        profile you wish to use for this transform, or a profile object
 
356
    inMode = string, as a valid PIL mode that the appropriate profile also
 
357
        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
 
358
    outMode = string, as a valid PIL mode that the appropriate profile also
 
359
        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
 
360
    renderingIntent = integer (0-3) specifying the rendering intent you
 
361
        wish to use for the transform
 
362
        INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
 
363
        INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
 
364
        INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
 
365
        INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
 
366
        see the pyCMS documentation for details on rendering intents and
 
367
        what they do.
 
368
    flags = integer (0-...) specifying additional flags
 
369
 
 
370
    If the input or output profiles specified are not valid filenames, a
 
371
    PyCMSError will be raised.  If an error occurs during creation of the
 
372
    transform, a PyCMSError will be raised.
 
373
 
 
374
    If inMode or outMode are not a mode supported by the outputProfile (or
 
375
    by pyCMS), a PyCMSError will be raised.
 
376
 
 
377
    This function builds and returns an ICC transform from the inputProfile
 
378
    to the outputProfile using the renderingIntent to determine what to do
 
379
    with out-of-gamut colors.  It will ONLY work for converting images that
 
380
    are in inMode to images that are in outMode color format (PIL mode,
 
381
    i.e. "RGB", "RGBA", "CMYK", etc.).
 
382
 
 
383
    Building the transform is a fair part of the overhead in
 
384
    ImageCms.profileToProfile(), so if you're planning on converting multiple
 
385
    images using the same input/output settings, this can save you time.
 
386
    Once you have a transform object, it can be used with
 
387
    ImageCms.applyProfile() to convert images without the need to re-compute
 
388
    the lookup table for the transform.
 
389
 
 
390
    The reason pyCMS returns a class object rather than a handle directly
 
391
    to the transform is that it needs to keep track of the PIL input/output
 
392
    modes that the transform is meant for.  These attributes are stored in
 
393
    the "inMode" and "outMode" attributes of the object (which can be
 
394
    manually overridden if you really want to, but I don't know of any
 
395
    time that would be of use, or would even work).
 
396
 
 
397
    """
 
398
 
 
399
    if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
 
400
        raise PyCMSError("renderingIntent must be an integer between 0 and 3")
 
401
 
 
402
    if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
 
403
        raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
 
404
 
 
405
    try:
 
406
        if not isinstance(inputProfile, ImageCmsProfile):
 
407
            inputProfile = ImageCmsProfile(inputProfile)
 
408
        if not isinstance(outputProfile, ImageCmsProfile):
 
409
            outputProfile = ImageCmsProfile(outputProfile)
 
410
        return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags)
 
411
    except (IOError, TypeError, ValueError), v:
 
412
        raise PyCMSError(v)
 
413
 
 
414
##
 
415
# (pyCMS) Builds an ICC transform mapping from the inputProfile to the
 
416
# outputProfile, but tries to simulate the result that would be
 
417
# obtained on the proofProfile device.
 
418
 
 
419
def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, proofRenderingIntent=INTENT_ABSOLUTE_COLORIMETRIC, flags=FLAGS["SOFTPROOFING"]):
 
420
    """
 
421
    ImageCms.buildProofTransform(inputProfile, outputProfile, proofProfile,
 
422
        inMode, outMode, [renderingIntent], [proofRenderingIntent])
 
423
 
 
424
    Returns a CmsTransform class object.
 
425
 
 
426
    inputProfile = string, as a valid filename path to the ICC input
 
427
        profile you wish to use for this transform, or a profile object
 
428
    outputProfile = string, as a valid filename path to the ICC output
 
429
        (monitor, usually) profile you wish to use for this transform,
 
430
        or a profile object
 
431
    proofProfile = string, as a valid filename path to the ICC proof
 
432
        profile you wish to use for this transform, or a profile object
 
433
    inMode = string, as a valid PIL mode that the appropriate profile also
 
434
        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
 
435
    outMode = string, as a valid PIL mode that the appropriate profile also
 
436
        supports (i.e. "RGB", "RGBA", "CMYK", etc.)
 
437
    renderingIntent = integer (0-3) specifying the rendering intent you
 
438
        wish to use for the input->proof (simulated) transform
 
439
        INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
 
440
        INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
 
441
        INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
 
442
        INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
 
443
        see the pyCMS documentation for details on rendering intents and
 
444
        what they do.
 
445
    proofRenderingIntent = integer (0-3) specifying the rendering intent
 
446
        you wish to use for proof->output transform
 
447
        INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
 
448
        INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
 
449
        INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
 
450
        INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
 
451
        see the pyCMS documentation for details on rendering intents and
 
452
        what they do.
 
453
    flags = integer (0-...) specifying additional flags
 
454
 
 
455
    If the input, output, or proof profiles specified are not valid
 
456
    filenames, a PyCMSError will be raised.
 
457
 
 
458
    If an error occurs during creation of the transform, a PyCMSError will
 
459
    be raised.
 
460
 
 
461
    If inMode or outMode are not a mode supported by the outputProfile
 
462
    (or by pyCMS), a PyCMSError will be raised.
 
463
 
 
464
    This function builds and returns an ICC transform from the inputProfile
 
465
    to the outputProfile, but tries to simulate the result that would be
 
466
    obtained on the proofProfile device using renderingIntent and
 
467
    proofRenderingIntent to determine what to do with out-of-gamut
 
468
    colors.  This is known as "soft-proofing".  It will ONLY work for
 
469
    converting images that are in inMode to images that are in outMode
 
470
    color format (PIL mode, i.e. "RGB", "RGBA", "CMYK", etc.).
 
471
 
 
472
    Usage of the resulting transform object is exactly the same as with
 
473
    ImageCms.buildTransform().
 
474
 
 
475
    Proof profiling is generally used when using an output device to get a
 
476
    good idea of what the final printed/displayed image would look like on
 
477
    the proofProfile device when it's quicker and easier to use the
 
478
    output device for judging color.  Generally, this means that the
 
479
    output device is a monitor, or a dye-sub printer (etc.), and the simulated
 
480
    device is something more expensive, complicated, or time consuming
 
481
    (making it difficult to make a real print for color judgement purposes).
 
482
 
 
483
    Soft-proofing basically functions by adjusting the colors on the
 
484
    output device to match the colors of the device being simulated. However,
 
485
    when the simulated device has a much wider gamut than the output
 
486
    device, you may obtain marginal results.
 
487
 
 
488
    """
 
489
 
 
490
    if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
 
491
        raise PyCMSError("renderingIntent must be an integer between 0 and 3")
 
492
 
 
493
    if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
 
494
        raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
 
495
 
 
496
    try:
 
497
        if not isinstance(inputProfile, ImageCmsProfile):
 
498
            inputProfile = ImageCmsProfile(inputProfile)
 
499
        if not isinstance(outputProfile, ImageCmsProfile):
 
500
            outputProfile = ImageCmsProfile(outputProfile)
 
501
        if not isinstance(proofProfile, ImageCmsProfile):
 
502
            proofProfile = ImageCmsProfile(proofProfile)
 
503
        return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, proofProfile, proofRenderingIntent, flags)
 
504
    except (IOError, TypeError, ValueError), v:
 
505
        raise PyCMSError(v)
 
506
 
 
507
buildTransformFromOpenProfiles = buildTransform
 
508
buildProofTransformFromOpenProfiles = buildProofTransform
 
509
 
 
510
##
 
511
# (pyCMS) Applies a transform to a given image.
 
512
 
 
513
def applyTransform(im, transform, inPlace=0):
 
514
    """
 
515
    ImageCms.applyTransform(im, transform, [inPlace])
 
516
 
 
517
    Returns either None, or a new PIL Image object, depending on the value
 
518
        of inPlace (see below)
 
519
 
 
520
    im = a PIL Image object, and im.mode must be the same as the inMode
 
521
        supported by the transform.
 
522
    transform = a valid CmsTransform class object
 
523
    inPlace = BOOL (1 == TRUE, 0 or None == FALSE).  If TRUE, im is
 
524
        modified in place and None is returned, if FALSE, a new Image
 
525
        object with the transform applied is returned (and im is not
 
526
        changed).  The default is FALSE.
 
527
 
 
528
    If im.mode != transform.inMode, a PyCMSError is raised.
 
529
 
 
530
    If inPlace == TRUE and transform.inMode != transform.outMode, a
 
531
    PyCMSError is raised.
 
532
 
 
533
    If im.mode, transfer.inMode, or transfer.outMode is not supported by
 
534
    pyCMSdll or the profiles you used for the transform, a PyCMSError is
 
535
    raised.
 
536
 
 
537
    If an error occurs while the transform is being applied, a PyCMSError
 
538
    is raised.
 
539
 
 
540
    This function applies a pre-calculated transform (from
 
541
    ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles()) to an
 
542
    image.  The transform can be used for multiple images, saving
 
543
    considerable calcuation time if doing the same conversion multiple times.
 
544
 
 
545
    If you want to modify im in-place instead of receiving a new image as
 
546
    the return value, set inPlace to TRUE.  This can only be done if
 
547
    transform.inMode and transform.outMode are the same, because we can't
 
548
    change the mode in-place (the buffer sizes for some modes are
 
549
    different).  The  default behavior is to return a new Image object of
 
550
    the same dimensions in mode transform.outMode.
 
551
 
 
552
    """
 
553
 
 
554
    try:
 
555
        if inPlace:
 
556
            transform.apply_in_place(im)
 
557
            imOut = None
 
558
        else:
 
559
            imOut = transform.apply(im)
 
560
    except (TypeError, ValueError), v:
 
561
        raise PyCMSError(v)
 
562
 
 
563
    return imOut
 
564
 
 
565
##
 
566
# (pyCMS) Creates a profile.
 
567
 
 
568
def createProfile(colorSpace, colorTemp=-1):
 
569
    """
 
570
    ImageCms.createProfile(colorSpace, [colorTemp])
 
571
 
 
572
    Returns a CmsProfile class object
 
573
 
 
574
    colorSpace = string, the color space of the profile you wish to create.
 
575
        Currently only "LAB", "XYZ", and "sRGB" are supported.
 
576
    colorTemp = positive integer for the white point for the profile, in
 
577
        degrees Kelvin (i.e. 5000, 6500, 9600, etc.).  The default is for
 
578
        D50 illuminant if omitted (5000k).  colorTemp is ONLY applied to
 
579
        LAB profiles, and is ignored for XYZ and sRGB.
 
580
 
 
581
    If colorSpace not in ["LAB", "XYZ", "sRGB"], a PyCMSError is raised
 
582
 
 
583
    If using LAB and colorTemp != a positive integer, a PyCMSError is raised.
 
584
 
 
585
    If an error occurs while creating the profile, a PyCMSError is raised.
 
586
 
 
587
    Use this function to create common profiles on-the-fly instead of
 
588
    having to supply a profile on disk and knowing the path to it.  It
 
589
    returns a normal CmsProfile object that can be passed to
 
590
    ImageCms.buildTransformFromOpenProfiles() to create a transform to apply
 
591
    to images.
 
592
 
 
593
    """
 
594
    if colorSpace not in ["LAB", "XYZ", "sRGB"]:
 
595
        raise PyCMSError("Color space not supported for on-the-fly profile creation (%s)" % colorSpace)
 
596
 
 
597
    if colorSpace == "LAB":
 
598
        if type(colorTemp) == type(5000.0):
 
599
            colorTemp = int(colorTemp + 0.5)
 
600
        if type (colorTemp) != type (5000):
 
601
            raise PyCMSError("Color temperature must be a positive integer, \"%s\" not valid" % colorTemp)
 
602
 
 
603
    try:
 
604
        return core.createProfile(colorSpace, colorTemp)
 
605
    except (TypeError, ValueError), v:
 
606
        raise PyCMSError(v)
 
607
 
 
608
##
 
609
# (pyCMS) Gets the internal product name for the given profile.
 
610
 
 
611
def getProfileName(profile):
 
612
    """
 
613
    ImageCms.getProfileName(profile)
 
614
 
 
615
    Returns a string containing the internal name of the profile as stored
 
616
        in an ICC tag.
 
617
 
 
618
    profile = EITHER a valid CmsProfile object, OR a string of the
 
619
        filename of an ICC profile.
 
620
 
 
621
    If profile isn't a valid CmsProfile object or filename to a profile,
 
622
    a PyCMSError is raised If an error occurs while trying to obtain the
 
623
    name tag, a PyCMSError is raised.
 
624
 
 
625
    Use this function to obtain the INTERNAL name of the profile (stored
 
626
    in an ICC tag in the profile itself), usually the one used when the
 
627
    profile was originally created.  Sometimes this tag also contains
 
628
    additional information supplied by the creator.
 
629
 
 
630
    """
 
631
    try:
 
632
        # add an extra newline to preserve pyCMS compatibility
 
633
        if not isinstance(profile, ImageCmsProfile):
 
634
            profile = ImageCmsProfile(profile)
 
635
        return profile.profile.product_name + "\n"
 
636
    except (AttributeError, IOError, TypeError, ValueError), v:
 
637
        raise PyCMSError(v)
 
638
 
 
639
##
 
640
# (pyCMS) Gets the internal product information for the given profile.
 
641
 
 
642
def getProfileInfo(profile):
 
643
    """
 
644
    ImageCms.getProfileInfo(profile)
 
645
 
 
646
    Returns a string containing the internal profile information stored in
 
647
        an ICC tag.
 
648
 
 
649
    profile = EITHER a valid CmsProfile object, OR a string of the
 
650
        filename of an ICC profile.
 
651
 
 
652
    If profile isn't a valid CmsProfile object or filename to a profile,
 
653
    a PyCMSError is raised.
 
654
 
 
655
    If an error occurs while trying to obtain the info tag, a PyCMSError
 
656
    is raised
 
657
 
 
658
    Use this function to obtain the information stored in the profile's
 
659
    info tag.  This often contains details about the profile, and how it
 
660
    was created, as supplied by the creator.
 
661
 
 
662
    """
 
663
    try:
 
664
        if not isinstance(profile, ImageCmsProfile):
 
665
            profile = ImageCmsProfile(profile)
 
666
        # add an extra newline to preserve pyCMS compatibility
 
667
        return profile.product_info + "\n"
 
668
    except (AttributeError, IOError, TypeError, ValueError), v:
 
669
        raise PyCMSError(v)
 
670
 
 
671
##
 
672
# (pyCMS) Gets the default intent name for the given profile.
 
673
 
 
674
def getDefaultIntent(profile):
 
675
    """
 
676
    ImageCms.getDefaultIntent(profile)
 
677
 
 
678
    Returns integer 0-3 specifying the default rendering intent for this
 
679
        profile.
 
680
        INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
 
681
        INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
 
682
        INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
 
683
        INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
 
684
        see the pyCMS documentation for details on rendering intents and
 
685
        what they do.
 
686
 
 
687
    profile = EITHER a valid CmsProfile object, OR a string of the
 
688
        filename of an ICC profile.
 
689
 
 
690
    If profile isn't a valid CmsProfile object or filename to a profile,
 
691
    a PyCMSError is raised.
 
692
 
 
693
    If an error occurs while trying to obtain the default intent, a
 
694
    PyCMSError is raised.
 
695
 
 
696
    Use this function to determine the default (and usually best optomized)
 
697
    rendering intent for this profile.  Most profiles support multiple
 
698
    rendering intents, but are intended mostly for one type of conversion.
 
699
    If you wish to use a different intent than returned, use
 
700
    ImageCms.isIntentSupported() to verify it will work first.
 
701
    """
 
702
    try:
 
703
        if not isinstance(profile, ImageCmsProfile):
 
704
            profile = ImageCmsProfile(profile)
 
705
        return profile.profile.rendering_intent
 
706
    except (AttributeError, IOError, TypeError, ValueError), v:
 
707
        raise PyCMSError(v)
 
708
 
 
709
##
 
710
# (pyCMS) Checks if a given intent is supported.
 
711
 
 
712
def isIntentSupported(profile, intent, direction):
 
713
    """
 
714
    ImageCms.isIntentSupported(profile, intent, direction)
 
715
 
 
716
    Returns 1 if the intent/direction are supported, -1 if they are not.
 
717
 
 
718
    profile = EITHER a valid CmsProfile object, OR a string of the
 
719
        filename of an ICC profile.
 
720
    intent = integer (0-3) specifying the rendering intent you wish to use
 
721
        with this profile
 
722
        INTENT_PERCEPTUAL =           0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
 
723
        INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
 
724
        INTENT_SATURATION =           2 (ImageCms.INTENT_SATURATION)
 
725
        INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
 
726
        see the pyCMS documentation for details on rendering intents and
 
727
        what they do.
 
728
    direction = integer specifing if the profile is to be used for input,
 
729
        output, or proof
 
730
        INPUT =               0 (or use ImageCms.DIRECTION_INPUT)
 
731
        OUTPUT =              1 (or use ImageCms.DIRECTION_OUTPUT)
 
732
        PROOF =               2 (or use ImageCms.DIRECTION_PROOF)
 
733
 
 
734
    Use this function to verify that you can use your desired
 
735
    renderingIntent with profile, and that profile can be used for the
 
736
    input/output/proof profile as you desire.
 
737
 
 
738
    Some profiles are created specifically for one "direction", can cannot
 
739
    be used for others.  Some profiles can only be used for certain
 
740
    rendering intents... so it's best to either verify this before trying
 
741
    to create a transform with them (using this function), or catch the
 
742
    potential PyCMSError that will occur if they don't support the modes
 
743
    you select.
 
744
 
 
745
    """
 
746
    try:
 
747
        if not isinstance(profile, ImageCmsProfile):
 
748
            profile = ImageCmsProfile(profile)
 
749
        # FIXME: I get different results for the same data w. different
 
750
        # compilers.  Bug in LittleCMS or in the binding?
 
751
        if profile.profile.is_intent_supported(intent, direction):
 
752
            return 1
 
753
        else:
 
754
            return -1
 
755
    except (AttributeError, IOError, TypeError, ValueError), v:
 
756
        raise PyCMSError(v)
 
757
 
 
758
##
 
759
# (pyCMS) Fetches versions.
 
760
 
 
761
def versions():
 
762
    import sys
 
763
    return (
 
764
        VERSION, core.littlecms_version, sys.version.split()[0], Image.VERSION
 
765
        )
 
766
 
 
767
# --------------------------------------------------------------------
 
768
 
 
769
if __name__ == "__main__":
 
770
    # create a cheap manual from the __doc__ strings for the functions above
 
771
 
 
772
    import ImageCms
 
773
    import string
 
774
    print __doc__
 
775
 
 
776
    for f in dir(pyCMS):
 
777
        print "="*80
 
778
        print "%s" %f
 
779
 
 
780
        try:
 
781
            exec ("doc = ImageCms.%s.__doc__" %(f))
 
782
            if string.find(doc, "pyCMS") >= 0:
 
783
                # so we don't get the __doc__ string for imported modules
 
784
                print doc
 
785
        except AttributeError:
 
786
            pass