~ubuntu-branches/ubuntu/raring/python-imaging/raring-updates

« 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-03-20 16:44:01 UTC
  • mfrom: (2.1.13 experimental)
  • Revision ID: package-import@ubuntu.com-20130320164401-ptf6m0ttg4zw72az
Tags: 1.1.7+2.0.0-1
Pillow 2.0.0 release.

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