~ubuntu-branches/ubuntu/vivid/ghostscript/vivid-security

« back to all changes in this revision

Viewing changes to lcms2/utils/matlab/icctrans.c

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2013-08-09 20:01:36 UTC
  • mfrom: (1.1.37)
  • Revision ID: package-import@ubuntu.com-20130809200136-amb6zrr7hnjb5jq9
Tags: 9.08~rc1~dfsg-0ubuntu1
* New upstream release
   - Ghostscript 9.08rc1.
   - We are using the system's liblcms2 and libopenjpeg now.
* debian/patches/020130401-852e545-pxl-xl-driver-produced-drawing-commands-without-setting-color-space.patch:
  Removed patch backported from upstream.
* debian/patches/ojdk-8007925+8007926.patch,
  debian/patches/ojdk-8007927.patch,
  debian/patches/ojdk-8007929.patch,
  debian/patches/ojdk-8009654.patch: Removed patches on build in liblcms2, we
  use the system's liblcms2 now.
* debian/patches/2001_docdir_fix_for_debian.patch: Manually updated to new
  upstream source code.
* debian/patches/2003_support_multiarch.patch: Refreshed with quilt.
* debian/control: Added build dependencies on liblcms2-dev and
  libopenjpeg-dev.
* debian/rules: Check for removed lcms2/ and openjpeg/ subdirectories in
  the repackaging check again, also set build options for shared liblcms2
  and libopenjpeg libraries.
* debian/rules: Makefile.in and configure.ac are in the root directory of
  the source now and do not need to get linked from base/. Also there is no
  gstoraster and gstopxl CUPS filter in the package any more and no
  "install-cups" make target any more.
* debian/control, debian/rules, debian/ghostscript-cups.install,
  debian/ghostscript-cups.ppd-updater: Removed the ghostscript-cups binary
  package. The files are now provided by cups-filters.
* debian/symbols.common: Updated for new upstream source. Applied patch
  which dpkg-gensymbols generated for debian/libgs9.symbols to this file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
//  Little cms
3
 
//  Copyright (C) 1998-2010 Marti Maria, Ignacio Ruiz de Conejo
4
 
//
5
 
// Permission is hereby granted, free of charge, to any person obtaining 
6
 
// a copy of this software and associated documentation files (the "Software"), 
7
 
// to deal in the Software without restriction, including without limitation 
8
 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, 
9
 
// and/or sell copies of the Software, and to permit persons to whom the Software 
10
 
// is furnished to do so, subject to the following conditions:
11
 
//
12
 
// The above copyright notice and this permission notice shall be included in 
13
 
// all copies or substantial portions of the Software.
14
 
//
15
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
16
 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
17
 
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
18
 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
19
 
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
20
 
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
21
 
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
 
 
23
 
 
24
 
#include "mex.h"
25
 
 
26
 
#include "lcms2.h"
27
 
#include "string.h"
28
 
#include "stdarg.h"
29
 
 
30
 
// xgetopt() interface -----------------------------------------------------
31
 
 
32
 
static int   xoptind;    
33
 
static char *xoptarg; 
34
 
static int   xopterr;  
35
 
static char  *letP;
36
 
static char   SW = '-';
37
 
 
38
 
// ------------------------------------------------------------------------
39
 
 
40
 
 
41
 
static int  Verbose ;                   // Print some statistics
42
 
static char *cInProf;                   // Input profile
43
 
static char *cOutProf;                  // Output profile
44
 
static char *cProofing;                 // Softproofing profile
45
 
 
46
 
 
47
 
static int  Intent;                             // Rendering Intent
48
 
static int  ProofingIntent;             // RI for proof
49
 
 
50
 
static int  PrecalcMode;                // 0 = Not, 1=Normal, 2=Accurate, 3=Fast
51
 
 
52
 
static cmsBool BlackPointCompensation;
53
 
static cmsBool lIsDeviceLink;
54
 
static cmsBool lMultiProfileChain;              // Multiple profile chain
55
 
 
56
 
static cmsHPROFILE hInput, hOutput, hProof;
57
 
static cmsHTRANSFORM hColorTransform;
58
 
static cmsHPROFILE hProfiles[255];
59
 
static int nProfiles;
60
 
 
61
 
static cmsColorSpaceSignature InputColorSpace, OutputColorSpace;
62
 
static int OutputChannels, InputChannels, nBytesDepth;
63
 
 
64
 
 
65
 
// Error. Print error message and abort
66
 
 
67
 
static
68
 
cmsBool FatalError(const char *frm, ...)
69
 
{
70
 
        va_list args;
71
 
        char Buffer[1024];
72
 
 
73
 
        va_start(args, frm);
74
 
        vsprintf(Buffer, frm, args);
75
 
        mexErrMsgTxt(Buffer);   
76
 
        va_end(args);
77
 
 
78
 
        return FALSE;               
79
 
}
80
 
 
81
 
// This is the handler passed to lcms
82
 
 
83
 
static
84
 
void MatLabErrorHandler(cmsContext ContextID, cmsUInt32Number ErrorCode, 
85
 
                                                const char *Text)
86
 
{      
87
 
        mexErrMsgTxt(Text);    
88
 
}
89
 
//
90
 
//  Parse the command line options, System V style.
91
 
//
92
 
 
93
 
static
94
 
void xoptinit()
95
 
{   
96
 
        xoptind = 1;
97
 
        xopterr = 0;
98
 
        letP = NULL;
99
 
}
100
 
 
101
 
 
102
 
static
103
 
int xgetopt(int argc, char *argv[], char *optionS)
104
 
{
105
 
        unsigned char ch;
106
 
        char *optP;
107
 
 
108
 
        if (SW == 0) {
109
 
                SW = '/';
110
 
        }
111
 
 
112
 
        if (argc > xoptind) {
113
 
                if (letP == NULL) {
114
 
                        if ((letP = argv[xoptind]) == NULL ||
115
 
                                *(letP++) != SW)  goto gopEOF;
116
 
                        if (*letP == SW) {
117
 
                                xoptind++;  goto gopEOF;
118
 
                        }
119
 
                }
120
 
                if (0 == (ch = *(letP++))) {
121
 
                        xoptind++;  goto gopEOF;
122
 
                }
123
 
                if (':' == ch  ||  (optP = strchr(optionS, ch)) == NULL)
124
 
                        goto gopError;
125
 
                if (':' == *(++optP)) {
126
 
                        xoptind++;
127
 
                        if (0 == *letP) {
128
 
                                if (argc <= xoptind)  goto  gopError;
129
 
                                letP = argv[xoptind++];
130
 
                        }
131
 
                        xoptarg = letP;
132
 
                        letP = NULL;
133
 
                } else {
134
 
                        if (0 == *letP) {
135
 
                                xoptind++;
136
 
                                letP = NULL;
137
 
                        }
138
 
                        xoptarg = NULL;
139
 
                }
140
 
                return ch;
141
 
        }
142
 
gopEOF:
143
 
        xoptarg = letP = NULL;
144
 
        return EOF;
145
 
 
146
 
gopError:
147
 
        xoptarg = NULL;    
148
 
        if (xopterr)
149
 
                FatalError ("get command line option");
150
 
        return ('?');
151
 
}
152
 
 
153
 
 
154
 
// Return Mathlab type by depth
155
 
 
156
 
static
157
 
size_t SizeOfArrayType(const mxArray *Array)
158
 
{
159
 
 
160
 
        switch (mxGetClassID(Array))  {
161
 
 
162
 
         case mxINT8_CLASS:   return 1;
163
 
         case mxUINT8_CLASS:  return 1;
164
 
         case mxINT16_CLASS:  return 2;
165
 
         case mxUINT16_CLASS: return 2;  
166
 
         case mxSINGLE_CLASS: return 4;
167
 
         case mxDOUBLE_CLASS: return 0; // Special case -- lcms handles double as size=0
168
 
 
169
 
 
170
 
         default:
171
 
                 FatalError("Unsupported data type");
172
 
                 return 0;
173
 
        }
174
 
}
175
 
 
176
 
 
177
 
// Get number of pixels of input array. Supported arrays are 
178
 
// organized as NxMxD, being N and M the size of image and D the
179
 
// number of components.
180
 
 
181
 
static
182
 
size_t GetNumberOfPixels(const mxArray* In)
183
 
{
184
 
        int nDimensions  = mxGetNumberOfDimensions(In); 
185
 
        const int  *Dimensions   = mxGetDimensions(In);
186
 
 
187
 
        switch (nDimensions) {
188
 
 
189
 
                case 1: return 1;                            // It is just a spot color
190
 
                case 2: return Dimensions[0];                // A scanline
191
 
                case 3: return Dimensions[0]*Dimensions[1];  // A image
192
 
 
193
 
                default:
194
 
                        FatalError("Unsupported array of %d dimensions", nDimensions);
195
 
                        return 0;
196
 
        }
197
 
}   
198
 
 
199
 
 
200
 
// Allocates the output array. Copies the input array modifying the pixel
201
 
// definition to match "OutputChannels".
202
 
 
203
 
static
204
 
mxArray* AllocateOutputArray(const mxArray* In, int OutputChannels)
205
 
{       
206
 
 
207
 
        mxArray*        Out                       = mxDuplicateArray(In);   // Make a "deep copy" of Input array 
208
 
        int         nDimensions   = mxGetNumberOfDimensions(In);    
209
 
        const int*      Dimensions    = mxGetDimensions(In);
210
 
        int         InputChannels = Dimensions[nDimensions-1];
211
 
 
212
 
 
213
 
        // Modify pixel size only if needed
214
 
 
215
 
        if (InputChannels != OutputChannels) {
216
 
 
217
 
 
218
 
                int i, NewSize;
219
 
                int *ModifiedDimensions = (int*) mxMalloc(nDimensions * sizeof(int));
220
 
 
221
 
 
222
 
                memmove(ModifiedDimensions, Dimensions, nDimensions * sizeof(int));
223
 
                ModifiedDimensions[nDimensions - 1] = OutputChannels;
224
 
 
225
 
                switch (mxGetClassID(In))  {
226
 
 
227
 
                case mxINT8_CLASS:   NewSize = sizeof(char); break;
228
 
                case mxUINT8_CLASS:  NewSize = sizeof(unsigned char); break;
229
 
                case mxINT16_CLASS:  NewSize = sizeof(short); break;
230
 
                case mxUINT16_CLASS: NewSize = sizeof(unsigned short); break;
231
 
 
232
 
                default:
233
 
                case mxDOUBLE_CLASS: NewSize = sizeof(double); break;
234
 
                }
235
 
 
236
 
 
237
 
                // NewSize = 1;
238
 
                for (i=0; i < nDimensions; i++)
239
 
                        NewSize *= ModifiedDimensions[i];
240
 
 
241
 
 
242
 
                mxSetDimensions(Out, ModifiedDimensions, nDimensions);
243
 
                mxFree(ModifiedDimensions);
244
 
 
245
 
                mxSetPr(Out, mxRealloc(mxGetPr(Out), NewSize));             
246
 
 
247
 
        }
248
 
 
249
 
 
250
 
        return Out;
251
 
}
252
 
 
253
 
 
254
 
 
255
 
// Does create a format descriptor. "Bytes" is the sizeof type in bytes
256
 
//  
257
 
//  Bytes  Meaning
258
 
//  ------ --------
259
 
//   0      Floating point (double)
260
 
//   1      8-bit samples
261
 
//   2      16-bit samples   
262
 
 
263
 
static
264
 
cmsUInt32Number MakeFormatDescriptor(cmsColorSpaceSignature ColorSpace, int Bytes)
265
 
{
266
 
        int IsFloat = (Bytes == 0 || Bytes == 4) ? 1 : 0;
267
 
        int Channels = cmsChannelsOf(ColorSpace);
268
 
        return FLOAT_SH(IsFloat)|COLORSPACE_SH(_cmsLCMScolorSpace(ColorSpace))|BYTES_SH(Bytes)|CHANNELS_SH(Channels)|PLANAR_SH(1);
269
 
}
270
 
 
271
 
 
272
 
// Opens a profile or proper built-in
273
 
 
274
 
static
275
 
cmsHPROFILE OpenProfile(const char* File)
276
 
{   
277
 
 
278
 
        cmsContext ContextID = 0;
279
 
 
280
 
           if (!File) 
281
 
            return cmsCreate_sRGBProfileTHR(ContextID);    
282
 
 
283
 
       if (cmsstrcasecmp(File, "*Lab2") == 0)
284
 
                return cmsCreateLab2ProfileTHR(ContextID, NULL);
285
 
 
286
 
       if (cmsstrcasecmp(File, "*Lab4") == 0)
287
 
                return cmsCreateLab4ProfileTHR(ContextID, NULL);
288
 
 
289
 
       if (cmsstrcasecmp(File, "*Lab") == 0)
290
 
                return cmsCreateLab4ProfileTHR(ContextID, NULL);
291
 
       
292
 
       if (cmsstrcasecmp(File, "*LabD65") == 0) {
293
 
 
294
 
           cmsCIExyY D65xyY;
295
 
           
296
 
           cmsWhitePointFromTemp( &D65xyY, 6504);           
297
 
           return cmsCreateLab4ProfileTHR(ContextID, &D65xyY);
298
 
       }
299
 
 
300
 
       if (cmsstrcasecmp(File, "*XYZ") == 0)
301
 
                return cmsCreateXYZProfileTHR(ContextID);
302
 
 
303
 
       if (cmsstrcasecmp(File, "*Gray22") == 0) {
304
 
 
305
 
           cmsToneCurve* Curve = cmsBuildGamma(ContextID, 2.2);
306
 
           cmsHPROFILE hProfile = cmsCreateGrayProfileTHR(ContextID, cmsD50_xyY(), Curve);
307
 
           cmsFreeToneCurve(Curve);
308
 
           return hProfile;
309
 
       }
310
 
 
311
 
        if (cmsstrcasecmp(File, "*Gray30") == 0) {
312
 
 
313
 
           cmsToneCurve* Curve = cmsBuildGamma(ContextID, 3.0);
314
 
           cmsHPROFILE hProfile = cmsCreateGrayProfileTHR(ContextID, cmsD50_xyY(), Curve);
315
 
           cmsFreeToneCurve(Curve);
316
 
           return hProfile;
317
 
       }
318
 
 
319
 
       if (cmsstrcasecmp(File, "*srgb") == 0)
320
 
                return cmsCreate_sRGBProfileTHR(ContextID);
321
 
 
322
 
       if (cmsstrcasecmp(File, "*null") == 0)
323
 
                return cmsCreateNULLProfileTHR(ContextID);
324
 
 
325
 
       
326
 
       if (cmsstrcasecmp(File, "*Lin2222") == 0) {
327
 
 
328
 
            cmsToneCurve*  Gamma = cmsBuildGamma(0, 2.2);
329
 
            cmsToneCurve*  Gamma4[4];
330
 
            cmsHPROFILE hProfile; 
331
 
 
332
 
            Gamma4[0] = Gamma4[1] = Gamma4[2] = Gamma4[3] = Gamma;
333
 
            hProfile = cmsCreateLinearizationDeviceLink(cmsSigCmykData, Gamma4);
334
 
            cmsFreeToneCurve(Gamma);
335
 
            return hProfile;
336
 
       }
337
 
 
338
 
           
339
 
        return cmsOpenProfileFromFileTHR(ContextID, File, "r");
340
 
}
341
 
 
342
 
 
343
 
static
344
 
cmsUInt32Number GetFlags()
345
 
{
346
 
        cmsUInt32Number dwFlags = 0; 
347
 
 
348
 
        switch (PrecalcMode) {
349
 
 
350
 
        case 0: dwFlags = cmsFLAGS_NOOPTIMIZE; break;
351
 
        case 2: dwFlags = cmsFLAGS_HIGHRESPRECALC; break;
352
 
        case 3: dwFlags = cmsFLAGS_LOWRESPRECALC; break;
353
 
        case 1: break;
354
 
 
355
 
        default: FatalError("Unknown precalculation mode '%d'", PrecalcMode);
356
 
        }
357
 
 
358
 
        if (BlackPointCompensation) 
359
 
                dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
360
 
 
361
 
        return dwFlags;
362
 
}
363
 
 
364
 
// Create transforms
365
 
 
366
 
static
367
 
void OpenTransforms(int argc, char *argv[])
368
 
{
369
 
 
370
 
        cmsUInt32Number dwIn, dwOut, dwFlags;
371
 
 
372
 
 
373
 
        if (lMultiProfileChain) {
374
 
 
375
 
                int i;
376
 
                cmsHTRANSFORM hTmp;
377
 
 
378
 
 
379
 
                nProfiles = argc - xoptind;
380
 
                for (i=0; i < nProfiles; i++) {
381
 
 
382
 
                        hProfiles[i] = OpenProfile(argv[i+xoptind]);
383
 
                }
384
 
 
385
 
 
386
 
                // Create a temporary devicelink 
387
 
 
388
 
                hTmp = cmsCreateMultiprofileTransform(hProfiles, nProfiles, 
389
 
                        0, 0, Intent, GetFlags());
390
 
 
391
 
                hInput = cmsTransform2DeviceLink(hTmp, 4.2, 0);
392
 
                hOutput = NULL;
393
 
                cmsDeleteTransform(hTmp);
394
 
 
395
 
                InputColorSpace  = cmsGetColorSpace(hInput);
396
 
                OutputColorSpace = cmsGetPCS(hInput);        
397
 
                lIsDeviceLink = TRUE;
398
 
 
399
 
        }
400
 
        else
401
 
                if (lIsDeviceLink) {
402
 
 
403
 
                        hInput  = cmsOpenProfileFromFile(cInProf, "r");
404
 
                        hOutput = NULL;
405
 
                        InputColorSpace  = cmsGetColorSpace(hInput);
406
 
                        OutputColorSpace = cmsGetPCS(hInput);
407
 
 
408
 
 
409
 
                }
410
 
                else {
411
 
 
412
 
                        hInput  = OpenProfile(cInProf);
413
 
                        hOutput = OpenProfile(cOutProf);    
414
 
 
415
 
                        InputColorSpace   = cmsGetColorSpace(hInput);
416
 
                        OutputColorSpace  = cmsGetColorSpace(hOutput);
417
 
 
418
 
                        if (cmsGetDeviceClass(hInput) == cmsSigLinkClass ||
419
 
                                cmsGetDeviceClass(hOutput) == cmsSigLinkClass)   
420
 
                                FatalError("Use %cl flag for devicelink profiles!\n", SW);
421
 
 
422
 
                }
423
 
 
424
 
 
425
 
                /*
426
 
 
427
 
                if (Verbose) {
428
 
 
429
 
                mexPrintf("From: %s\n", cmsTakeProductName(hInput));
430
 
                if (hOutput) mexPrintf("To  : %s\n\n", cmsTakeProductName(hOutput));
431
 
 
432
 
                }
433
 
                */
434
 
 
435
 
 
436
 
                OutputChannels = cmsChannelsOf(OutputColorSpace);
437
 
                InputChannels  = cmsChannelsOf(InputColorSpace);
438
 
 
439
 
 
440
 
                dwIn  = MakeFormatDescriptor(InputColorSpace, nBytesDepth);
441
 
                dwOut = MakeFormatDescriptor(OutputColorSpace, nBytesDepth);
442
 
 
443
 
 
444
 
                dwFlags = GetFlags();
445
 
 
446
 
                if (cProofing != NULL) {
447
 
 
448
 
                        hProof = OpenProfile(cProofing);
449
 
                        dwFlags |= cmsFLAGS_SOFTPROOFING;
450
 
                }
451
 
 
452
 
 
453
 
 
454
 
 
455
 
                hColorTransform = cmsCreateProofingTransform(hInput, dwIn, 
456
 
                        hOutput, dwOut, 
457
 
                        hProof, Intent, 
458
 
                        ProofingIntent, 
459
 
                        dwFlags);
460
 
 
461
 
}
462
 
 
463
 
 
464
 
 
465
 
static
466
 
void ApplyTransforms(const mxArray *In, mxArray *Out)
467
 
{   
468
 
        double *Input  = mxGetPr(In); 
469
 
        double *Output = mxGetPr(Out);    
470
 
        size_t nPixels = GetNumberOfPixels(In);;
471
 
 
472
 
        cmsDoTransform(hColorTransform, Input, Output, nPixels );
473
 
 
474
 
}
475
 
 
476
 
 
477
 
static
478
 
void CloseTransforms(void)
479
 
{
480
 
        int i;
481
 
 
482
 
        if (hColorTransform) cmsDeleteTransform(hColorTransform);
483
 
        if (hInput) cmsCloseProfile(hInput);
484
 
        if (hOutput) cmsCloseProfile(hOutput);             
485
 
        if (hProof) cmsCloseProfile(hProof);
486
 
 
487
 
        for (i=0; i < nProfiles; i++)
488
 
                cmsCloseProfile(hProfiles[i]);
489
 
 
490
 
        hColorTransform = NULL; hInput = NULL; hOutput = NULL; hProof = NULL;
491
 
}
492
 
 
493
 
 
494
 
static
495
 
void HandleSwitches(int argc, char *argv[])
496
 
{
497
 
        int  s;
498
 
 
499
 
        xoptinit();
500
 
 
501
 
        while ((s = xgetopt(argc, argv,"C:c:VvbBI:i:O:o:T:t:L:l:r:r:P:p:Mm")) != EOF) {
502
 
 
503
 
 
504
 
                switch (s){
505
 
 
506
 
                case 'b':
507
 
                case 'B': 
508
 
                        BlackPointCompensation = TRUE;
509
 
                        break;
510
 
 
511
 
                case 'c':
512
 
                case 'C':
513
 
                        PrecalcMode = atoi(xoptarg);
514
 
                        if (PrecalcMode < 0 || PrecalcMode > 3)
515
 
                                FatalError("Unknown precalc mode '%d'", PrecalcMode);
516
 
                        break;
517
 
 
518
 
                case 'v':
519
 
                case 'V':
520
 
                        Verbose = TRUE;
521
 
                        break;
522
 
 
523
 
                case 'i':
524
 
                case 'I':
525
 
                        if (lIsDeviceLink)
526
 
                                FatalError("Device-link already specified");
527
 
                        cInProf = xoptarg;
528
 
                        break;
529
 
 
530
 
                case 'o':
531
 
                case 'O':
532
 
                        if (lIsDeviceLink)
533
 
                                FatalError("Device-link already specified"); 
534
 
                        cOutProf = xoptarg;
535
 
                        break;
536
 
 
537
 
                case 't':
538
 
                case 'T':
539
 
                        Intent = atoi(xoptarg);
540
 
                        // if (Intent > 3) Intent = 3;
541
 
                        if (Intent < 0) Intent = 0;
542
 
                        break;
543
 
 
544
 
 
545
 
                case 'l':
546
 
                case 'L': 
547
 
                        cInProf = xoptarg;
548
 
                        lIsDeviceLink = TRUE;
549
 
                        break;
550
 
 
551
 
                case 'p':
552
 
                case 'P':
553
 
                        cProofing = xoptarg;
554
 
                        break;
555
 
 
556
 
 
557
 
 
558
 
                case 'r':
559
 
                case 'R':
560
 
                        ProofingIntent = atoi(xoptarg);
561
 
                        // if (ProofingIntent > 3) ProofingIntent = 3;
562
 
                        if (ProofingIntent < 0) ProofingIntent = 0;
563
 
                        break;
564
 
 
565
 
 
566
 
                case 'm':
567
 
                case 'M':
568
 
                        lMultiProfileChain = TRUE;
569
 
                        break;
570
 
 
571
 
                default:
572
 
                        FatalError("Unknown option.");
573
 
                }
574
 
        }
575
 
 
576
 
        // For multiprofile, need to specify -m
577
 
 
578
 
        if (xoptind < argc) {
579
 
 
580
 
                if (!lMultiProfileChain)
581
 
                        FatalError("Use %cm for multiprofile transforms", SW);
582
 
        }
583
 
 
584
 
}
585
 
 
586
 
 
587
 
 
588
 
// -------------------------------------------------- Print some fancy help
589
 
static
590
 
void PrintHelp(void)
591
 
{
592
 
        mexPrintf("(MX) little cms ColorSpace conversion tool - v2.0\n\n");
593
 
 
594
 
        mexPrintf("usage: icctrans (mVar, flags)\n\n");
595
 
 
596
 
        mexPrintf("mVar : Matlab array.\n");
597
 
        mexPrintf("flags: a string containing one or more of following options.\n\n");
598
 
        mexPrintf("\t%cv - Verbose\n", SW);
599
 
        mexPrintf("\t%ci<profile> - Input profile (defaults to sRGB)\n", SW);
600
 
        mexPrintf("\t%co<profile> - Output profile (defaults to sRGB)\n", SW);   
601
 
        mexPrintf("\t%cl<profile> - Transform by device-link profile\n", SW);      
602
 
        mexPrintf("\t%cm<profiles> - Apply multiprofile chain\n", SW);      
603
 
 
604
 
        mexPrintf("\t%ct<n> - Rendering intent\n", SW);    
605
 
 
606
 
        mexPrintf("\t%cb - Black point compensation\n", SW);
607
 
        mexPrintf("\t%cc<0,1,2,3> - Optimize transform (0=Off, 1=Normal, 2=Hi-res, 3=Lo-Res) [defaults to 1]\n", SW);     
608
 
 
609
 
        mexPrintf("\t%cp<profile> - Soft proof profile\n", SW);
610
 
        mexPrintf("\t%cr<0,1,2,3> - Soft proof intent\n", SW);
611
 
 
612
 
        mexPrintf("\nYou can use following built-ins as profiles:\n\n");
613
 
 
614
 
        mexPrintf("\t*Lab2  -- D50-based v2 CIEL*a*b\n"
615
 
        "\t*Lab4  -- D50-based v4 CIEL*a*b\n"
616
 
        "\t*Lab   -- D50-based v4 CIEL*a*b\n"
617
 
        "\t*XYZ   -- CIE XYZ (PCS)\n"
618
 
        "\t*sRGB  -- IEC6 1996-2.1 sRGB color space\n" 
619
 
        "\t*Gray22 - Monochrome of Gamma 2.2\n"
620
 
        "\t*Gray30 - Monochrome of Gamma 3.0\n"
621
 
        "\t*null   - Monochrome black for all input\n"
622
 
        "\t*Lin2222- CMYK linearization of gamma 2.2 on each channel\n\n");
623
 
 
624
 
        mexPrintf("For suggestions, comments, bug reports etc. send mail to info@littlecms.com\n\n");
625
 
 
626
 
}
627
 
 
628
 
 
629
 
 
630
 
// Main entry point
631
 
 
632
 
void mexFunction(
633
 
                                 int nlhs,              // Number of left hand side (output) arguments
634
 
                                 mxArray *plhs[],       // Array of left hand side arguments
635
 
                                 int nrhs,              // Number of right hand side (input) arguments
636
 
                                 const mxArray *prhs[]  // Array of right hand side arguments
637
 
)
638
 
{
639
 
 
640
 
        char CommandLine[4096+1];
641
 
        char *pt, *argv[128];
642
 
        int argc = 1;
643
 
 
644
 
 
645
 
        if (nrhs != 2) {    
646
 
 
647
 
                PrintHelp();              
648
 
                return;
649
 
        }
650
 
 
651
 
 
652
 
        if(nlhs > 1) {        
653
 
                FatalError("Too many output arguments.");
654
 
        }
655
 
 
656
 
 
657
 
        // Setup error handler
658
 
 
659
 
        cmsSetLogErrorHandler(MatLabErrorHandler);
660
 
 
661
 
        // Defaults
662
 
 
663
 
        Verbose     = 0;
664
 
        cInProf     = NULL;
665
 
        cOutProf    = NULL;
666
 
        cProofing   = NULL;
667
 
 
668
 
        lMultiProfileChain = FALSE;
669
 
        nProfiles   = 0;
670
 
 
671
 
        Intent                  = INTENT_PERCEPTUAL;
672
 
        ProofingIntent          = INTENT_ABSOLUTE_COLORIMETRIC;
673
 
        PrecalcMode = 1;
674
 
        BlackPointCompensation  = FALSE;
675
 
        lIsDeviceLink           = FALSE;
676
 
 
677
 
        // Check types. Fist parameter is array of values, second parameter is command line
678
 
 
679
 
        if (!mxIsNumeric(prhs[0]))
680
 
                FatalError("Type mismatch on argument 1 -- Must be numeric");
681
 
 
682
 
        if (!mxIsChar(prhs[1]))
683
 
                FatalError("Type mismatch on argument 2 -- Must be string");
684
 
 
685
 
 
686
 
 
687
 
 
688
 
        // Unpack string to command line buffer
689
 
 
690
 
        if (mxGetString(prhs[1], CommandLine, 4096))
691
 
                FatalError("Cannot unpack command string");
692
 
 
693
 
        // Separate to argv[] convention
694
 
 
695
 
        argv[0] = NULL;
696
 
        for (pt = strtok(CommandLine, " ");
697
 
                pt;
698
 
                pt = strtok(NULL, " ")) {
699
 
 
700
 
                        argv[argc++] = pt;
701
 
        }
702
 
 
703
 
 
704
 
 
705
 
        // Parse arguments
706
 
        HandleSwitches(argc, argv);
707
 
 
708
 
 
709
 
        nBytesDepth = SizeOfArrayType(prhs[0]);
710
 
 
711
 
        OpenTransforms(argc, argv);
712
 
 
713
 
 
714
 
        plhs[0] = AllocateOutputArray(prhs[0], OutputChannels);
715
 
 
716
 
 
717
 
        ApplyTransforms(prhs[0], plhs[0]);
718
 
 
719
 
        CloseTransforms();
720
 
 
721
 
        // Done!
722
 
}
723
 
 
724