00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "magick/studio.h"
00043 #include "magick/cache.h"
00044 #include "magick/color.h"
00045 #include "magick/configure.h"
00046 #include "magick/exception.h"
00047 #include "magick/exception-private.h"
00048 #include "magick/hashmap.h"
00049 #include "magick/image.h"
00050 #include "magick/memory_.h"
00051 #include "magick/monitor.h"
00052 #include "magick/monitor-private.h"
00053 #include "magick/option.h"
00054 #include "magick/profile.h"
00055 #include "magick/property.h"
00056 #include "magick/quantum.h"
00057 #include "magick/quantum-private.h"
00058 #include "magick/splay-tree.h"
00059 #include "magick/string_.h"
00060 #include "magick/thread-private.h"
00061 #include "magick/token.h"
00062 #include "magick/utility.h"
00063 #if defined(MAGICKCORE_LCMS_DELEGATE)
00064 #if defined(MAGICKCORE_HAVE_LCMS_LCMS_H)
00065 #include <lcms/lcms.h>
00066 #else
00067 #include "lcms.h"
00068 #endif
00069 #endif
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 MagickExport MagickBooleanType CloneImageProfiles(Image *image,
00097 const Image *clone_image)
00098 {
00099 assert(image != (Image *) NULL);
00100 assert(image->signature == MagickSignature);
00101 if (image->debug != MagickFalse)
00102 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00103 assert(clone_image != (const Image *) NULL);
00104 assert(clone_image->signature == MagickSignature);
00105 image->color_profile.length=clone_image->color_profile.length;
00106 image->color_profile.info=clone_image->color_profile.info;
00107 image->iptc_profile.length=clone_image->iptc_profile.length;
00108 image->iptc_profile.info=clone_image->iptc_profile.info;
00109 if (clone_image->profiles != (void *) NULL)
00110 image->profiles=CloneSplayTree((SplayTreeInfo *) clone_image->profiles,
00111 (void *(*)(void *)) ConstantString,(void *(*)(void *)) CloneStringInfo);
00112 return(MagickTrue);
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 MagickExport MagickBooleanType DeleteImageProfile(Image *image,
00140 const char *name)
00141 {
00142 assert(image != (Image *) NULL);
00143 assert(image->signature == MagickSignature);
00144 if (image->debug != MagickFalse)
00145 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00146 if (image->profiles == (SplayTreeInfo *) NULL)
00147 return(MagickFalse);
00148 if (LocaleCompare(name,"icc") == 0)
00149 {
00150
00151
00152
00153 image->color_profile.length=0;
00154 image->color_profile.info=(unsigned char *) NULL;
00155 }
00156 if (LocaleCompare(name,"iptc") == 0)
00157 {
00158
00159
00160
00161 image->iptc_profile.length=0;
00162 image->iptc_profile.info=(unsigned char *) NULL;
00163 }
00164 return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->profiles,name));
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 MagickExport void DestroyImageProfiles(Image *image)
00190 {
00191 if (image->profiles != (SplayTreeInfo *) NULL)
00192 image->profiles=DestroySplayTree((SplayTreeInfo *) image->profiles);
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 MagickExport const StringInfo *GetImageProfile(const Image *image,
00220 const char *name)
00221 {
00222 char
00223 key[MaxTextExtent];
00224
00225 const StringInfo
00226 *profile;
00227
00228 assert(image != (Image *) NULL);
00229 assert(image->signature == MagickSignature);
00230 if (image->debug != MagickFalse)
00231 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00232 if (image->profiles == (SplayTreeInfo *) NULL)
00233 return((StringInfo *) NULL);
00234 (void) CopyMagickString(key,name,MaxTextExtent);
00235 profile=(const StringInfo *) GetValueFromSplayTree((SplayTreeInfo *)
00236 image->profiles,key);
00237 return(profile);
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 MagickExport char *GetNextImageProfile(const Image *image)
00263 {
00264 assert(image != (Image *) NULL);
00265 assert(image->signature == MagickSignature);
00266 if (image->debug != MagickFalse)
00267 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00268 if (image->profiles == (SplayTreeInfo *) NULL)
00269 return((char *) NULL);
00270 return((char *) GetNextKeyInSplayTree((SplayTreeInfo *) image->profiles));
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 #if defined(MAGICKCORE_LCMS_DELEGATE)
00315
00316 static unsigned short **DestroyPixelThreadSet(unsigned short **pixels)
00317 {
00318 register long
00319 i;
00320
00321 assert(pixels != (unsigned short **) NULL);
00322 for (i=0; i < (long) GetOpenMPMaximumThreads(); i++)
00323 if (pixels[i] != (unsigned short *) NULL)
00324 pixels[i]=(unsigned short *) RelinquishMagickMemory(pixels[i]);
00325 pixels=(unsigned short **) RelinquishAlignedMemory(pixels);
00326 return(pixels);
00327 }
00328
00329 static unsigned short **AcquirePixelThreadSet(const size_t columns,
00330 const size_t channels)
00331 {
00332 register long
00333 i;
00334
00335 unsigned short
00336 **pixels;
00337
00338 unsigned long
00339 number_threads;
00340
00341 number_threads=GetOpenMPMaximumThreads();
00342 pixels=(unsigned short **) AcquireAlignedMemory(number_threads,
00343 sizeof(*pixels));
00344 if (pixels == (unsigned short **) NULL)
00345 return((unsigned short **) NULL);
00346 (void) ResetMagickMemory(pixels,0,number_threads*sizeof(*pixels));
00347 for (i=0; i < (long) number_threads; i++)
00348 {
00349 pixels[i]=(unsigned short *) AcquireQuantumMemory(columns,channels*
00350 sizeof(**pixels));
00351 if (pixels[i] == (unsigned short *) NULL)
00352 return(DestroyPixelThreadSet(pixels));
00353 }
00354 return(pixels);
00355 }
00356
00357 static cmsHTRANSFORM *DestroyTransformThreadSet(cmsHTRANSFORM *transform)
00358 {
00359 register long
00360 i;
00361
00362 assert(transform != (cmsHTRANSFORM *) NULL);
00363 for (i=0; i < (long) GetOpenMPMaximumThreads(); i++)
00364 if (transform[i] != (cmsHTRANSFORM) NULL)
00365 cmsDeleteTransform(transform[i]);
00366 transform=(cmsHTRANSFORM *) RelinquishAlignedMemory(transform);
00367 return(transform);
00368 }
00369
00370 static cmsHTRANSFORM *AcquireTransformThreadSet(
00371 const cmsHPROFILE source_profile,const DWORD source_type,
00372 const cmsHPROFILE target_profile,const DWORD target_type,const int intent,
00373 const DWORD flags)
00374 {
00375 cmsHTRANSFORM
00376 *transform;
00377
00378 register long
00379 i;
00380
00381 unsigned long
00382 number_threads;
00383
00384 number_threads=GetOpenMPMaximumThreads();
00385 transform=(cmsHTRANSFORM *) AcquireAlignedMemory(number_threads,
00386 sizeof(*transform));
00387 if (transform == (cmsHTRANSFORM *) NULL)
00388 return((cmsHTRANSFORM *) NULL);
00389 (void) ResetMagickMemory(transform,0,number_threads*sizeof(*transform));
00390 for (i=0; i < (long) number_threads; i++)
00391 {
00392 transform[i]=cmsCreateTransform(source_profile,source_type,target_profile,
00393 target_type,intent,flags);
00394 if (transform[i] == (cmsHTRANSFORM) NULL)
00395 return(DestroyTransformThreadSet(transform));
00396 }
00397 return(transform);
00398 }
00399 #endif
00400
00401 static MagickBooleanType SetAdobeRGB1998ImageProfile(Image *image)
00402 {
00403 static unsigned char
00404 AdobeRGB1998Profile[] =
00405 {
00406 0x00, 0x00, 0x02, 0x30, 0x41, 0x44, 0x42, 0x45, 0x02, 0x10, 0x00,
00407 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
00408 0x5a, 0x20, 0x07, 0xd0, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x13, 0x00,
00409 0x33, 0x00, 0x3b, 0x61, 0x63, 0x73, 0x70, 0x41, 0x50, 0x50, 0x4c,
00410 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00,
00411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00412 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
00413 0x00, 0xd3, 0x2d, 0x41, 0x44, 0x42, 0x45, 0x00, 0x00, 0x00, 0x00,
00414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00417 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
00418 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
00419 0x32, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00,
00420 0x00, 0x6b, 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x9c, 0x00,
00421 0x00, 0x00, 0x14, 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x01, 0xb0,
00422 0x00, 0x00, 0x00, 0x14, 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01,
00423 0xc4, 0x00, 0x00, 0x00, 0x0e, 0x67, 0x54, 0x52, 0x43, 0x00, 0x00,
00424 0x01, 0xd4, 0x00, 0x00, 0x00, 0x0e, 0x62, 0x54, 0x52, 0x43, 0x00,
00425 0x00, 0x01, 0xe4, 0x00, 0x00, 0x00, 0x0e, 0x72, 0x58, 0x59, 0x5a,
00426 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x00, 0x14, 0x67, 0x58, 0x59,
00427 0x5a, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x14, 0x62, 0x58,
00428 0x59, 0x5a, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x14, 0x74,
00429 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79,
00430 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20,
00431 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65,
00432 0x6d, 0x73, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72,
00433 0x61, 0x74, 0x65, 0x64, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63,
00434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x41, 0x64, 0x6f,
00435 0x62, 0x65, 0x20, 0x52, 0x47, 0x42, 0x20, 0x28, 0x31, 0x39, 0x39,
00436 0x38, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00437 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00443 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00,
00444 0x00, 0x00, 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00,
00445 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
00446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00447 0x00, 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00448 0x00, 0x01, 0x02, 0x33, 0x00, 0x00, 0x63, 0x75, 0x72, 0x76, 0x00,
00449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x33, 0x00, 0x00,
00450 0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00451 0x01, 0x02, 0x33, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00,
00452 0x00, 0x00, 0x00, 0x00, 0x9c, 0x18, 0x00, 0x00, 0x4f, 0xa5, 0x00,
00453 0x00, 0x04, 0xfc, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
00454 0x00, 0x00, 0x34, 0x8d, 0x00, 0x00, 0xa0, 0x2c, 0x00, 0x00, 0x0f,
00455 0x95, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00456 0x26, 0x31, 0x00, 0x00, 0x10, 0x2f, 0x00, 0x00, 0xbe, 0x9c
00457 };
00458
00459 StringInfo
00460 *profile;
00461
00462 MagickBooleanType
00463 status;
00464
00465 assert(image != (Image *) NULL);
00466 assert(image->signature == MagickSignature);
00467 if (GetImageProfile(image,"icm") != (const StringInfo *) NULL)
00468 return(MagickFalse);
00469 profile=AcquireStringInfo(sizeof(AdobeRGB1998Profile));
00470 SetStringInfoDatum(profile,AdobeRGB1998Profile);
00471 status=SetImageProfile(image,"icm",profile);
00472 profile=DestroyStringInfo(profile);
00473 return(status);
00474 }
00475
00476 static MagickBooleanType SetsRGBImageProfile(Image *image)
00477 {
00478 static unsigned char
00479 sRGBProfile[] =
00480 {
00481 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, 0x02, 0x10, 0x00,
00482 0x00, 0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59,
00483 0x5a, 0x20, 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00,
00484 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54,
00485 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47,
00486 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00487 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00,
00488 0x00, 0xd3, 0x2d, 0x48, 0x50, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
00489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
00493 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00,
00494 0x33, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00,
00495 0x00, 0x6c, 0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0xf0, 0x00,
00496 0x00, 0x00, 0x14, 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x02, 0x04,
00497 0x00, 0x00, 0x00, 0x14, 0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02,
00498 0x18, 0x00, 0x00, 0x00, 0x14, 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00,
00499 0x02, 0x2c, 0x00, 0x00, 0x00, 0x14, 0x62, 0x58, 0x59, 0x5a, 0x00,
00500 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x14, 0x64, 0x6d, 0x6e, 0x64,
00501 0x00, 0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70, 0x64, 0x6d, 0x64,
00502 0x64, 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88, 0x76, 0x75,
00503 0x65, 0x64, 0x00, 0x00, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x86, 0x76,
00504 0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xd4, 0x00, 0x00, 0x00, 0x24,
00505 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00,
00506 0x14, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00,
00507 0x00, 0x24, 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x04, 0x30, 0x00,
00508 0x00, 0x00, 0x0c, 0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c,
00509 0x00, 0x00, 0x08, 0x0c, 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04,
00510 0x3c, 0x00, 0x00, 0x08, 0x0c, 0x62, 0x54, 0x52, 0x43, 0x00, 0x00,
00511 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, 0x74, 0x65, 0x78, 0x74, 0x00,
00512 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68,
00513 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x38, 0x20,
00514 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74, 0x74, 0x2d, 0x50, 0x61, 0x63,
00515 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x6e,
00516 0x79, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00,
00517 0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45,
00518 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00,
00519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
00520 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39,
00521 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
00522 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00523 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00524 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00526 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00527 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xcc, 0x58,
00528 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a,
00530 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa2, 0x00, 0x00,
00531 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20, 0x00,
00532 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99, 0x00, 0x00, 0xb7, 0x85,
00533 0x00, 0x00, 0x18, 0xda, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00,
00534 0x00, 0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00,
00535 0xb6, 0xcf, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00,
00536 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70,
00537 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
00538 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00539 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70,
00540 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x65, 0x63, 0x2e,
00541 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00545 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00,
00546 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31,
00547 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, 0x65, 0x66,
00548 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63, 0x6f,
00549 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20,
00550 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
00551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20,
00552 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44,
00553 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20,
00554 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63,
00555 0x65, 0x20, 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00,
00556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73,
00558 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65,
00559 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65,
00560 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
00561 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36,
00562 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00,
00563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, 0x65,
00564 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65,
00565 0x77, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
00566 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x36,
00567 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00,
00568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00570 0x00, 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
00571 0xa4, 0xfe, 0x00, 0x14, 0x5f, 0x2e, 0x00, 0x10, 0xcf, 0x14, 0x00,
00572 0x03, 0xed, 0xcc, 0x00, 0x04, 0x13, 0x0b, 0x00, 0x03, 0x5c, 0x9e,
00573 0x00, 0x00, 0x00, 0x01, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00,
00574 0x00, 0x00, 0x4c, 0x09, 0x56, 0x00, 0x50, 0x00, 0x00, 0x00, 0x57,
00575 0x1f, 0xe7, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
00576 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
00578 0x8f, 0x00, 0x00, 0x00, 0x02, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00,
00579 0x00, 0x00, 0x43, 0x52, 0x54, 0x20, 0x63, 0x75, 0x72, 0x76, 0x00,
00580 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05,
00581 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19, 0x00, 0x1e, 0x00,
00582 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37, 0x00, 0x3b,
00583 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54, 0x00,
00584 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
00585 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00,
00586 0x90, 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9,
00587 0x00, 0xae, 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00,
00588 0xc6, 0x00, 0xcb, 0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0,
00589 0x00, 0xe5, 0x00, 0xeb, 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01,
00590 0x01, 0x01, 0x07, 0x01, 0x0d, 0x01, 0x13, 0x01, 0x19, 0x01, 0x1f,
00591 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32, 0x01, 0x38, 0x01, 0x3e, 0x01,
00592 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59, 0x01, 0x60, 0x01, 0x67,
00593 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83, 0x01, 0x8b, 0x01,
00594 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1, 0x01, 0xb9,
00595 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1, 0x01,
00596 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
00597 0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02,
00598 0x4b, 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a,
00599 0x02, 0x84, 0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02,
00600 0xb6, 0x02, 0xc1, 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb,
00601 0x02, 0xf5, 0x03, 0x00, 0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03,
00602 0x2d, 0x03, 0x38, 0x03, 0x43, 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66,
00603 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a, 0x03, 0x96, 0x03, 0xa2, 0x03,
00604 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3, 0x03, 0xe0, 0x03, 0xec,
00605 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20, 0x04, 0x2d, 0x04,
00606 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71, 0x04, 0x7e,
00607 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4, 0x04,
00608 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
00609 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05,
00610 0x77, 0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5,
00611 0x05, 0xd5, 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06,
00612 0x27, 0x06, 0x37, 0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b,
00613 0x06, 0x8c, 0x06, 0x9d, 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06,
00614 0xe3, 0x06, 0xf5, 0x07, 0x07, 0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d,
00615 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74, 0x07, 0x86, 0x07, 0x99, 0x07,
00616 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5, 0x07, 0xf8, 0x08, 0x0b,
00617 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a, 0x08, 0x6e, 0x08,
00618 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2, 0x08, 0xe7,
00619 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f, 0x09,
00620 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
00621 0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a,
00622 0x54, 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5,
00623 0x0a, 0xdc, 0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b,
00624 0x51, 0x0b, 0x69, 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8,
00625 0x0b, 0xe1, 0x0b, 0xf9, 0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c,
00626 0x5c, 0x0c, 0x75, 0x0c, 0x8e, 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9,
00627 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26, 0x0d, 0x40, 0x0d, 0x5a, 0x0d,
00628 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3, 0x0d, 0xde, 0x0d, 0xf8,
00629 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64, 0x0e, 0x7f, 0x0e,
00630 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09, 0x0f, 0x25,
00631 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3, 0x0f,
00632 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
00633 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11,
00634 0x13, 0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa,
00635 0x11, 0xc9, 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12,
00636 0x64, 0x12, 0x84, 0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03,
00637 0x13, 0x23, 0x13, 0x43, 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13,
00638 0xc5, 0x13, 0xe5, 0x14, 0x06, 0x14, 0x27, 0x14, 0x49, 0x14, 0x6a,
00639 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce, 0x14, 0xf0, 0x15, 0x12, 0x15,
00640 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b, 0x15, 0xbd, 0x15, 0xe0,
00641 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c, 0x16, 0x8f, 0x16,
00642 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41, 0x17, 0x65,
00643 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b, 0x18,
00644 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
00645 0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19,
00646 0xdd, 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e,
00647 0x1a, 0xc5, 0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b,
00648 0x8a, 0x1b, 0xb2, 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52,
00649 0x1c, 0x7b, 0x1c, 0xa3, 0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d,
00650 0x47, 0x1d, 0x70, 0x1d, 0x99, 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16,
00651 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94, 0x1e, 0xbe, 0x1e, 0xe9, 0x1f,
00652 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94, 0x1f, 0xbf, 0x1f, 0xea,
00653 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98, 0x20, 0xc4, 0x20,
00654 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1, 0x21, 0xce,
00655 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf, 0x22,
00656 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
00657 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24,
00658 0xda, 0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7,
00659 0x25, 0xf7, 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26,
00660 0xe8, 0x27, 0x18, 0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc,
00661 0x28, 0x0d, 0x28, 0x3f, 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29,
00662 0x06, 0x29, 0x38, 0x29, 0x6b, 0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02,
00663 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b, 0x2a, 0xcf, 0x2b, 0x02, 0x2b,
00664 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1, 0x2c, 0x05, 0x2c, 0x39,
00665 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c, 0x2d, 0x41, 0x2d,
00666 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c, 0x2e, 0x82,
00667 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91, 0x2f,
00668 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
00669 0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32,
00670 0x2a, 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46,
00671 0x33, 0x7f, 0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34,
00672 0x9e, 0x34, 0xd8, 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2,
00673 0x35, 0xfd, 0x36, 0x37, 0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37,
00674 0x24, 0x37, 0x60, 0x37, 0x9c, 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50,
00675 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05, 0x39, 0x42, 0x39, 0x7f, 0x39,
00676 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74, 0x3a, 0xb2, 0x3a, 0xef,
00677 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8, 0x3c, 0x27, 0x3c,
00678 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61, 0x3d, 0xa1,
00679 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0, 0x3f,
00680 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
00681 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41,
00682 0xee, 0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a,
00683 0x43, 0x7d, 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44,
00684 0xce, 0x45, 0x12, 0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22,
00685 0x46, 0x67, 0x46, 0xab, 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47,
00686 0xc0, 0x48, 0x05, 0x48, 0x4b, 0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d,
00687 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0, 0x4a, 0x37, 0x4a, 0x7d, 0x4a,
00688 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a, 0x4b, 0xe2, 0x4c, 0x2a,
00689 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a, 0x4d, 0x93, 0x4d,
00690 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00, 0x4f, 0x49,
00691 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb, 0x51,
00692 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
00693 0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54,
00694 0x42, 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2,
00695 0x56, 0x0f, 0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57,
00696 0x92, 0x57, 0xe0, 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a,
00697 0x59, 0x69, 0x59, 0xb8, 0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a,
00698 0xf5, 0x5b, 0x45, 0x5b, 0x95, 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86,
00699 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78, 0x5d, 0xc9, 0x5e, 0x1a, 0x5e,
00700 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61, 0x5f, 0xb3, 0x60, 0x05,
00701 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f, 0x61, 0xa2, 0x61,
00702 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43, 0x63, 0x97,
00703 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d, 0x65,
00704 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
00705 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69,
00706 0x43, 0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7,
00707 0x6b, 0x4f, 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d,
00708 0x08, 0x6d, 0x60, 0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4,
00709 0x6f, 0x1e, 0x6f, 0x78, 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70,
00710 0xe0, 0x71, 0x3a, 0x71, 0x95, 0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6,
00711 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8, 0x74, 0x14, 0x74, 0x70, 0x74,
00712 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1, 0x76, 0x3e, 0x76, 0x9b,
00713 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11, 0x78, 0x6e, 0x78,
00714 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46, 0x7a, 0xa5,
00715 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81, 0x7c,
00716 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
00717 0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81,
00718 0x0a, 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4,
00719 0x83, 0x57, 0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85,
00720 0x47, 0x85, 0xab, 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b,
00721 0x87, 0x9f, 0x88, 0x04, 0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89,
00722 0x99, 0x89, 0xfe, 0x8a, 0x64, 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96,
00723 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca, 0x8d, 0x31, 0x8d, 0x98, 0x8d,
00724 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36, 0x8f, 0x9e, 0x90, 0x06,
00725 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8, 0x92, 0x11, 0x92,
00726 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20, 0x94, 0x8a,
00727 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f, 0x97,
00728 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
00729 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b,
00730 0xaf, 0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2,
00731 0x9e, 0x40, 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0,
00732 0x69, 0xa0, 0xd8, 0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96,
00733 0xa3, 0x06, 0xa3, 0x76, 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5,
00734 0x38, 0xa5, 0xa9, 0xa6, 0x1a, 0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e,
00735 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4, 0xa9, 0x37, 0xa9, 0xa9, 0xaa,
00736 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75, 0xab, 0xe9, 0xac, 0x5c,
00737 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d, 0xae, 0xa1, 0xaf,
00738 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea, 0xb1, 0x60,
00739 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae, 0xb4,
00740 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
00741 0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9,
00742 0x4a, 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7,
00743 0xbc, 0x21, 0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe,
00744 0x84, 0xbe, 0xff, 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec,
00745 0xc1, 0x67, 0xc1, 0xe3, 0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3,
00746 0xd4, 0xc4, 0x51, 0xc4, 0xce, 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46,
00747 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf, 0xc8, 0x3d, 0xc8, 0xbc, 0xc9,
00748 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7, 0xcb, 0x36, 0xcb, 0xb6,
00749 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5, 0xce, 0x36, 0xce,
00750 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba, 0xd1, 0x3c,
00751 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6, 0xd4,
00752 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
00753 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9,
00754 0xf1, 0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a,
00755 0xdd, 0x10, 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf,
00756 0xaf, 0xe0, 0x36, 0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53,
00757 0xe2, 0xdb, 0xe3, 0x63, 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5,
00758 0x84, 0xe6, 0x0d, 0xe6, 0x96, 0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32,
00759 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0, 0xea, 0x5b, 0xea, 0xe5, 0xeb,
00760 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11, 0xed, 0x9c, 0xee, 0x28,
00761 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58, 0xf0, 0xe5, 0xf1,
00762 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7, 0xf4, 0x34,
00763 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb, 0xf7,
00764 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
00765 0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd,
00766 0xba, 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff
00767 };
00768
00769 StringInfo
00770 *profile;
00771
00772 MagickBooleanType
00773 status;
00774
00775 assert(image != (Image *) NULL);
00776 assert(image->signature == MagickSignature);
00777 if (GetImageProfile(image,"icm") != (const StringInfo *) NULL)
00778 return(MagickFalse);
00779 profile=AcquireStringInfo(sizeof(sRGBProfile));
00780 SetStringInfoDatum(profile,sRGBProfile);
00781 status=SetImageProfile(image,"icm",profile);
00782 profile=DestroyStringInfo(profile);
00783 return(status);
00784 }
00785 #if defined(MAGICKCORE_LCMS_DELEGATE)
00786 #if defined(LCMS_VERSION) && (LCMS_VERSION > 1010)
00787 static int LCMSErrorHandler(int severity,const char *message)
00788 {
00789 (void) LogMagickEvent(TransformEvent,GetMagickModule(),"lcms: #%d, %s",
00790 severity,message != (char *) NULL ? message : "no message");
00791 return(1);
00792 }
00793 #endif
00794 #endif
00795
00796 MagickExport MagickBooleanType ProfileImage(Image *image,const char *name,
00797 const void *datum,const size_t length,
00798 const MagickBooleanType magick_unused(clone))
00799 {
00800 #define ProfileImageTag "Profile/Image"
00801 #define ThrowProfileException(severity,tag,context) \
00802 { \
00803 (void) cmsCloseProfile(source_profile); \
00804 (void) cmsCloseProfile(target_profile); \
00805 ThrowBinaryException(severity,tag,context); \
00806 }
00807
00808 MagickBooleanType
00809 status;
00810
00811 StringInfo
00812 *profile;
00813
00814 assert(image != (Image *) NULL);
00815 assert(image->signature == MagickSignature);
00816 if (image->debug != MagickFalse)
00817 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00818 assert(name != (const char *) NULL);
00819 if ((datum == (const void *) NULL) || (length == 0))
00820 {
00821 char
00822 **arguments,
00823 *names;
00824
00825 int
00826 number_arguments;
00827
00828 register long
00829 i;
00830
00831
00832
00833
00834 names=ConstantString(name);
00835 (void) SubstituteString(&names,","," ");
00836 arguments=StringToArgv(names,&number_arguments);
00837 names=DestroyString(names);
00838 if (arguments == (char **) NULL)
00839 return(MagickTrue);
00840 ResetImageProfileIterator(image);
00841 for (name=GetNextImageProfile(image); name != (const char *) NULL; )
00842 {
00843 for (i=1; i < number_arguments; i++)
00844 {
00845 if ((*arguments[i] == '!') &&
00846 (LocaleCompare(name,arguments[i]+1) == 0))
00847 break;
00848 if (GlobExpression(name,arguments[i],MagickTrue) != MagickFalse)
00849 {
00850 (void) DeleteImageProfile(image,name);
00851 ResetImageProfileIterator(image);
00852 break;
00853 }
00854 }
00855 name=GetNextImageProfile(image);
00856 }
00857 for (i=0; i < number_arguments; i++)
00858 arguments[i]=DestroyString(arguments[i]);
00859 arguments=(char **) RelinquishMagickMemory(arguments);
00860 return(MagickTrue);
00861 }
00862
00863
00864
00865 profile=AcquireStringInfo((size_t) length);
00866 SetStringInfoDatum(profile,(unsigned char *) datum);
00867 if ((LocaleCompare(name,"icc") == 0) || (LocaleCompare(name,"icm") == 0))
00868 {
00869 const StringInfo
00870 *icc_profile;
00871
00872 icc_profile=GetImageProfile(image,"icc");
00873 if ((icc_profile != (const StringInfo *) NULL) &&
00874 (CompareStringInfo(icc_profile,profile) == 0))
00875 {
00876 const char
00877 *value;
00878
00879 value=GetImageProperty(image,"exif:ColorSpace");
00880 if (LocaleCompare(value,"1") != 0)
00881 (void) SetsRGBImageProfile(image);
00882 value=GetImageProperty(image,"exif:InteroperabilityIndex");
00883 if (LocaleCompare(value,"R98.") != 0)
00884 (void) SetsRGBImageProfile(image);
00885 value=GetImageProperty(image,"exif:InteroperabilityIndex");
00886 if (LocaleCompare(value,"R03.") != 0)
00887 (void) SetAdobeRGB1998ImageProfile(image);
00888 icc_profile=GetImageProfile(image,"icc");
00889 }
00890 if ((icc_profile != (const StringInfo *) NULL) &&
00891 (CompareStringInfo(icc_profile,profile) == 0))
00892 {
00893 profile=DestroyStringInfo(profile);
00894 return(MagickTrue);
00895 }
00896 #if !defined(MAGICKCORE_LCMS_DELEGATE)
00897 (void) ThrowMagickException(&image->exception,GetMagickModule(),
00898 MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","`%s' (LCMS)",
00899 image->filename);
00900 #else
00901 if (icc_profile != (StringInfo *) NULL)
00902 {
00903 CacheView
00904 *image_view;
00905
00906 ColorspaceType
00907 source_colorspace,
00908 target_colorspace;
00909
00910 cmsHPROFILE
00911 source_profile,
00912 target_profile;
00913
00914 cmsHTRANSFORM
00915 *transform;
00916
00917 DWORD
00918 flags,
00919 source_type,
00920 target_type;
00921
00922 ExceptionInfo
00923 *exception;
00924
00925 int
00926 intent;
00927
00928 long
00929 progress,
00930 y;
00931
00932 MagickBooleanType
00933 status;
00934
00935 size_t
00936 length,
00937 source_channels,
00938 target_channels;
00939
00940 unsigned short
00941 **source_pixels,
00942 **target_pixels;
00943
00944
00945
00946
00947 #if defined(LCMS_VERSION) && (LCMS_VERSION > 1010)
00948 cmsSetErrorHandler(LCMSErrorHandler);
00949 #else
00950 (void) cmsErrorAction(LCMS_ERROR_SHOW);
00951 #endif
00952 source_profile=cmsOpenProfileFromMem(GetStringInfoDatum(icc_profile),
00953 (DWORD) GetStringInfoLength(icc_profile));
00954 target_profile=cmsOpenProfileFromMem(GetStringInfoDatum(profile),
00955 (DWORD) GetStringInfoLength(profile));
00956 if ((source_profile == (cmsHPROFILE) NULL) ||
00957 (target_profile == (cmsHPROFILE) NULL))
00958 ThrowBinaryException(ResourceLimitError,
00959 "ColorspaceColorProfileMismatch",name);
00960 switch (cmsGetColorSpace(source_profile))
00961 {
00962 case icSigCmykData:
00963 {
00964 source_colorspace=CMYKColorspace;
00965 source_type=(DWORD) TYPE_CMYK_16;
00966 source_channels=4;
00967 break;
00968 }
00969 case icSigGrayData:
00970 {
00971 source_colorspace=GRAYColorspace;
00972 source_type=(DWORD) TYPE_GRAY_16;
00973 source_channels=1;
00974 break;
00975 }
00976 case icSigLabData:
00977 {
00978 source_colorspace=LabColorspace;
00979 source_type=(DWORD) TYPE_Lab_16;
00980 source_channels=3;
00981 break;
00982 }
00983 case icSigLuvData:
00984 {
00985 source_colorspace=YUVColorspace;
00986 source_type=(DWORD) TYPE_YUV_16;
00987 source_channels=3;
00988 break;
00989 }
00990 case icSigRgbData:
00991 {
00992 source_colorspace=RGBColorspace;
00993 source_type=(DWORD) TYPE_RGB_16;
00994 source_channels=3;
00995 break;
00996 }
00997 case icSigXYZData:
00998 {
00999 source_colorspace=XYZColorspace;
01000 source_type=(DWORD) TYPE_XYZ_16;
01001 source_channels=3;
01002 break;
01003 }
01004 case icSigYCbCrData:
01005 {
01006 source_colorspace=YCbCrColorspace;
01007 source_type=(DWORD) TYPE_YCbCr_16;
01008 source_channels=3;
01009 break;
01010 }
01011 default:
01012 {
01013 source_colorspace=UndefinedColorspace;
01014 source_type=(DWORD) TYPE_RGB_16;
01015 source_channels=3;
01016 break;
01017 }
01018 }
01019 switch (cmsGetColorSpace(target_profile))
01020 {
01021 case icSigCmykData:
01022 {
01023 target_colorspace=CMYKColorspace;
01024 target_type=(DWORD) TYPE_CMYK_16;
01025 target_channels=4;
01026 break;
01027 }
01028 case icSigLabData:
01029 {
01030 target_colorspace=LabColorspace;
01031 target_type=(DWORD) TYPE_Lab_16;
01032 target_channels=3;
01033 break;
01034 }
01035 case icSigGrayData:
01036 {
01037 target_colorspace=GRAYColorspace;
01038 target_type=(DWORD) TYPE_GRAY_16;
01039 target_channels=1;
01040 break;
01041 }
01042 case icSigLuvData:
01043 {
01044 target_colorspace=YUVColorspace;
01045 target_type=(DWORD) TYPE_YUV_16;
01046 target_channels=3;
01047 break;
01048 }
01049 case icSigRgbData:
01050 {
01051 target_colorspace=RGBColorspace;
01052 target_type=(DWORD) TYPE_RGB_16;
01053 target_channels=3;
01054 break;
01055 }
01056 case icSigXYZData:
01057 {
01058 target_colorspace=XYZColorspace;
01059 target_type=(DWORD) TYPE_XYZ_16;
01060 target_channels=3;
01061 break;
01062 }
01063 case icSigYCbCrData:
01064 {
01065 target_colorspace=YCbCrColorspace;
01066 target_type=(DWORD) TYPE_YCbCr_16;
01067 target_channels=3;
01068 break;
01069 }
01070 default:
01071 {
01072 target_colorspace=UndefinedColorspace;
01073 target_type=(DWORD) TYPE_RGB_16;
01074 target_channels=3;
01075 break;
01076 }
01077 }
01078 exception=(&image->exception);
01079 if ((source_colorspace == UndefinedColorspace) ||
01080 (target_colorspace == UndefinedColorspace))
01081 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
01082 name);
01083 if ((source_colorspace == GRAYColorspace) &&
01084 (IsGrayImage(image,exception) == MagickFalse))
01085 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
01086 name);
01087 if ((source_colorspace == CMYKColorspace) &&
01088 (image->colorspace != CMYKColorspace))
01089 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
01090 name);
01091 if ((source_colorspace == XYZColorspace) &&
01092 (image->colorspace != XYZColorspace))
01093 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
01094 name);
01095 if ((source_colorspace == YCbCrColorspace) &&
01096 (image->colorspace != YCbCrColorspace))
01097 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
01098 name);
01099 if ((source_colorspace != CMYKColorspace) &&
01100 (source_colorspace != GRAYColorspace) &&
01101 (source_colorspace != LabColorspace) &&
01102 (source_colorspace != XYZColorspace) &&
01103 (source_colorspace != YCbCrColorspace) &&
01104 (image->colorspace != RGBColorspace))
01105 ThrowProfileException(ImageError,"ColorspaceColorProfileMismatch",
01106 name);
01107 switch (image->rendering_intent)
01108 {
01109 case AbsoluteIntent: intent=INTENT_ABSOLUTE_COLORIMETRIC; break;
01110 case PerceptualIntent: intent=INTENT_PERCEPTUAL; break;
01111 case RelativeIntent: intent=INTENT_RELATIVE_COLORIMETRIC; break;
01112 case SaturationIntent: intent=INTENT_SATURATION; break;
01113 default: intent=INTENT_PERCEPTUAL; break;
01114 }
01115 flags=cmsFLAGS_HIGHRESPRECALC;
01116 #if defined(cmsFLAGS_BLACKPOINTCOMPENSATION)
01117 if (image->black_point_compensation != MagickFalse)
01118 flags|=cmsFLAGS_BLACKPOINTCOMPENSATION;
01119 #endif
01120 transform=AcquireTransformThreadSet(source_profile,source_type,
01121 target_profile,target_type,intent,flags);
01122 (void) cmsCloseProfile(source_profile);
01123 if (transform == (cmsHTRANSFORM *) NULL)
01124 ThrowBinaryException(ImageError,"UnableToCreateColorTransform",
01125 name);
01126
01127
01128
01129 length=(size_t) image->columns;
01130 source_pixels=AcquirePixelThreadSet(image->columns,source_channels);
01131 target_pixels=AcquirePixelThreadSet(image->columns,target_channels);
01132 if ((source_pixels == (unsigned short **) NULL) ||
01133 (target_pixels == (unsigned short **) NULL))
01134 {
01135 transform=DestroyTransformThreadSet(transform);
01136 (void) cmsCloseProfile(target_profile);
01137 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
01138 image->filename);
01139 }
01140 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
01141 {
01142 target_pixels=DestroyPixelThreadSet(target_pixels);
01143 source_pixels=DestroyPixelThreadSet(source_pixels);
01144 transform=DestroyTransformThreadSet(transform);
01145 (void) cmsCloseProfile(target_profile);
01146 return(MagickFalse);
01147 }
01148 if (target_colorspace == CMYKColorspace)
01149 (void) SetImageColorspace(image,target_colorspace);
01150 status=MagickTrue;
01151 progress=0;
01152 image_view=AcquireCacheView(image);
01153 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01154 #pragma omp parallel for schedule(dynamic,4) shared(status)
01155 #endif
01156 for (y=0; y < (long) image->rows; y++)
01157 {
01158 MagickBooleanType
01159 sync;
01160
01161 register IndexPacket
01162 *__restrict indexes;
01163
01164 register long
01165 id,
01166 x;
01167
01168 register PixelPacket
01169 *__restrict q;
01170
01171 register unsigned short
01172 *p;
01173
01174 if (status == MagickFalse)
01175 continue;
01176 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
01177 exception);
01178 if (q == (PixelPacket *) NULL)
01179 {
01180 status=MagickFalse;
01181 continue;
01182 }
01183 indexes=GetCacheViewAuthenticIndexQueue(image_view);
01184 id=GetOpenMPThreadId();
01185 p=source_pixels[id];
01186 for (x=0; x < (long) image->columns; x++)
01187 {
01188 *p++=ScaleQuantumToShort(q->red);
01189 if (source_channels > 1)
01190 {
01191 *p++=ScaleQuantumToShort(q->green);
01192 *p++=ScaleQuantumToShort(q->blue);
01193 }
01194 if (source_channels > 3)
01195 *p++=ScaleQuantumToShort(indexes[x]);
01196 q++;
01197 }
01198 cmsDoTransform(transform[id],source_pixels[id],target_pixels[id],
01199 (unsigned int) image->columns);
01200 p=target_pixels[id];
01201 q-=image->columns;
01202 for (x=0; x < (long) image->columns; x++)
01203 {
01204 q->red=ScaleShortToQuantum(*p);
01205 q->green=q->red;
01206 q->blue=q->red;
01207 p++;
01208 if (target_channels > 1)
01209 {
01210 q->green=ScaleShortToQuantum(*p);
01211 p++;
01212 q->blue=ScaleShortToQuantum(*p);
01213 p++;
01214 }
01215 if (target_channels > 3)
01216 {
01217 indexes[x]=ScaleShortToQuantum(*p);
01218 p++;
01219 }
01220 q++;
01221 }
01222 sync=SyncCacheViewAuthenticPixels(image_view,exception);
01223 if (sync == MagickFalse)
01224 status=MagickFalse;
01225 if (image->progress_monitor != (MagickProgressMonitor) NULL)
01226 {
01227 MagickBooleanType
01228 proceed;
01229
01230 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01231 #pragma omp critical (MagickCore_ProfileImage)
01232 #endif
01233 proceed=SetImageProgress(image,ProfileImageTag,progress++,
01234 image->rows);
01235 if (proceed == MagickFalse)
01236 status=MagickFalse;
01237 }
01238 }
01239 image_view=DestroyCacheView(image_view);
01240 (void) SetImageColorspace(image,target_colorspace);
01241 switch (cmsGetColorSpace(target_profile))
01242 {
01243 case icSigRgbData:
01244 {
01245 image->type=image->matte == MagickFalse ? TrueColorType :
01246 TrueColorMatteType;
01247 break;
01248 }
01249 case icSigCmykData:
01250 {
01251 image->type=image->matte == MagickFalse ? ColorSeparationType :
01252 ColorSeparationMatteType;
01253 break;
01254 }
01255 case icSigGrayData:
01256 {
01257 image->type=image->matte == MagickFalse ? GrayscaleType :
01258 GrayscaleMatteType;
01259 break;
01260 }
01261 default:
01262 break;
01263 }
01264 target_pixels=DestroyPixelThreadSet(target_pixels);
01265 source_pixels=DestroyPixelThreadSet(source_pixels);
01266 transform=DestroyTransformThreadSet(transform);
01267 (void) cmsCloseProfile(target_profile);
01268 }
01269 #endif
01270 }
01271 status=SetImageProfile(image,name,profile);
01272 profile=DestroyStringInfo(profile);
01273 return(status);
01274 }
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301 MagickExport StringInfo *RemoveImageProfile(Image *image,const char *name)
01302 {
01303 StringInfo
01304 *profile;
01305
01306 assert(image != (Image *) NULL);
01307 assert(image->signature == MagickSignature);
01308 if (image->debug != MagickFalse)
01309 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01310 if (image->profiles == (SplayTreeInfo *) NULL)
01311 return((StringInfo *) NULL);
01312 if (LocaleCompare(name,"icc") == 0)
01313 {
01314
01315
01316
01317 image->color_profile.length=0;
01318 image->color_profile.info=(unsigned char *) NULL;
01319 }
01320 if (LocaleCompare(name,"iptc") == 0)
01321 {
01322
01323
01324
01325 image->iptc_profile.length=0;
01326 image->iptc_profile.info=(unsigned char *) NULL;
01327 }
01328 profile=(StringInfo *) RemoveNodeFromSplayTree((SplayTreeInfo *)
01329 image->profiles,name);
01330 return(profile);
01331 }
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357 MagickExport void ResetImageProfileIterator(const Image *image)
01358 {
01359 assert(image != (Image *) NULL);
01360 assert(image->signature == MagickSignature);
01361 if (image->debug != MagickFalse)
01362 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01363 if (image->profiles == (SplayTreeInfo *) NULL)
01364 return;
01365 ResetSplayTreeIterator((SplayTreeInfo *) image->profiles);
01366 }
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 static void *DestroyProfile(void *profile)
01400 {
01401 return((void *) DestroyStringInfo((StringInfo *) profile));
01402 }
01403
01404 static inline const unsigned char *ReadResourceByte(const unsigned char *p,
01405 unsigned char *quantum)
01406 {
01407 *quantum=(*p++);
01408 return(p);
01409 }
01410
01411 static inline const unsigned char *ReadResourceBytes(const unsigned char *p,
01412 const ssize_t count,unsigned char *quantum)
01413 {
01414 register ssize_t
01415 i;
01416
01417 for (i=0; i < count; i++)
01418 *quantum++=(*p++);
01419 return(p);
01420 }
01421
01422 static inline const unsigned char *ReadResourceLong(const unsigned char *p,
01423 unsigned long *quantum)
01424 {
01425 *quantum=(unsigned long) (*p++ << 24);
01426 *quantum|=(unsigned long) (*p++ << 16);
01427 *quantum|=(unsigned long) (*p++ << 8);
01428 *quantum|=(unsigned long) (*p++ << 0);
01429 return(p);
01430 }
01431
01432 static inline const unsigned char *ReadResourceShort(const unsigned char *p,
01433 unsigned short *quantum)
01434 {
01435 *quantum=(unsigned short) (*p++ << 8);
01436 *quantum|=(unsigned short) (*p++ << 0);
01437 return(p);
01438 }
01439
01440 static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
01441 const StringInfo *resource_block)
01442 {
01443 const unsigned char
01444 *datum;
01445
01446 register const unsigned char
01447 *p;
01448
01449 size_t
01450 length;
01451
01452 StringInfo
01453 *profile;
01454
01455 unsigned char
01456 length_byte;
01457
01458 unsigned long
01459 count;
01460
01461 unsigned short
01462 id;
01463
01464 datum=GetStringInfoDatum(resource_block);
01465 length=GetStringInfoLength(resource_block);
01466 for (p=datum; p < (datum+length-16); )
01467 {
01468 if (LocaleNCompare((char *) p,"8BIM",4) != 0)
01469 break;
01470 p+=4;
01471 p=ReadResourceShort(p,&id);
01472 p=ReadResourceByte(p,&length_byte);
01473 p+=length_byte;
01474 if (((length_byte+1) & 0x01) != 0)
01475 p++;
01476 if (p > (datum+length-4))
01477 break;
01478 p=ReadResourceLong(p,&count);
01479 if ((p > (datum+length-count)) || (count > length))
01480 break;
01481 switch (id)
01482 {
01483 case 0x03ed:
01484 {
01485 unsigned short
01486 resolution;
01487
01488
01489
01490
01491 p=ReadResourceShort(p,&resolution)+6;
01492 image->x_resolution=(double) resolution;
01493 p=ReadResourceShort(p,&resolution)+6;
01494 image->y_resolution=(double) resolution;
01495 break;
01496 }
01497 case 0x0404:
01498 {
01499
01500
01501
01502 profile=AcquireStringInfo(count);
01503 SetStringInfoDatum(profile,p);
01504 (void) SetImageProfile(image,"iptc",profile);
01505 profile=DestroyStringInfo(profile);
01506 p+=count;
01507 break;
01508 }
01509 case 0x040c:
01510 {
01511
01512
01513
01514 p+=count;
01515 break;
01516 }
01517 case 0x040f:
01518 {
01519
01520
01521
01522 profile=AcquireStringInfo(count);
01523 SetStringInfoDatum(profile,p);
01524 (void) SetImageProfile(image,"icc",profile);
01525 profile=DestroyStringInfo(profile);
01526 p+=count;
01527 break;
01528 }
01529 case 0x0422:
01530 {
01531
01532
01533
01534 profile=AcquireStringInfo(count);
01535 SetStringInfoDatum(profile,p);
01536 (void) SetImageProfile(image,"exif",profile);
01537 profile=DestroyStringInfo(profile);
01538 p+=count;
01539 break;
01540 }
01541 case 0x0424:
01542 {
01543
01544
01545
01546 profile=AcquireStringInfo(count);
01547 SetStringInfoDatum(profile,p);
01548 (void) SetImageProfile(image,"xmp",profile);
01549 profile=DestroyStringInfo(profile);
01550 p+=count;
01551 break;
01552 }
01553 default:
01554 {
01555 p+=count;
01556 break;
01557 }
01558 }
01559 if ((count & 0x01) != 0)
01560 p++;
01561 }
01562 return(MagickTrue);
01563 }
01564
01565 MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
01566 const StringInfo *profile)
01567 {
01568 char
01569 key[MaxTextExtent],
01570 property[MaxTextExtent];
01571
01572 MagickBooleanType
01573 status;
01574
01575 assert(image != (Image *) NULL);
01576 assert(image->signature == MagickSignature);
01577 if (image->debug != MagickFalse)
01578 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01579 if (image->profiles == (SplayTreeInfo *) NULL)
01580 image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
01581 DestroyProfile);
01582 (void) CopyMagickString(key,name,MaxTextExtent);
01583 status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,
01584 ConstantString(key),CloneStringInfo(profile));
01585 if ((status != MagickFalse) &&
01586 ((LocaleCompare(name,"icc") == 0) || (LocaleCompare(name,"icm") == 0)))
01587 {
01588 const StringInfo
01589 *icc_profile;
01590
01591
01592
01593
01594 icc_profile=GetImageProfile(image,name);
01595 if (icc_profile != (const StringInfo *) NULL)
01596 {
01597 image->color_profile.length=GetStringInfoLength(icc_profile);
01598 image->color_profile.info=GetStringInfoDatum(icc_profile);
01599 }
01600 }
01601 if ((status != MagickFalse) &&
01602 ((LocaleCompare(name,"iptc") == 0) || (LocaleCompare(name,"8bim") == 0)))
01603 {
01604 const StringInfo
01605 *iptc_profile;
01606
01607
01608
01609
01610 iptc_profile=GetImageProfile(image,name);
01611 if (iptc_profile != (const StringInfo *) NULL)
01612 {
01613 image->iptc_profile.length=GetStringInfoLength(iptc_profile);
01614 image->iptc_profile.info=GetStringInfoDatum(iptc_profile);
01615 }
01616 (void) GetProfilesFromResourceBlock(image,profile);
01617 }
01618
01619
01620
01621 (void) FormatMagickString(property,MaxTextExtent,"%s:sans",name);
01622 (void) GetImageProperty(image,property);
01623 return(status);
01624 }
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 static inline int ReadProfileByte(unsigned char **p,size_t *length)
01651 {
01652 int
01653 c;
01654
01655 if (*length < 1)
01656 return(EOF);
01657 c=(int) (*(*p)++);
01658 (*length)--;
01659 return(c);
01660 }
01661
01662 static inline unsigned short ReadProfileShort(const EndianType endian,
01663 unsigned char *buffer)
01664 {
01665 unsigned short
01666 value;
01667
01668 if (endian == MSBEndian)
01669 {
01670 value=(unsigned short) ((((unsigned char *) buffer)[0] << 8) |
01671 ((unsigned char *) buffer)[1]);
01672 return((unsigned short) (value & 0xffff));
01673 }
01674 value=(unsigned short) ((buffer[1] << 8) | buffer[0]);
01675 return((unsigned short) (value & 0xffff));
01676 }
01677
01678 static inline unsigned long ReadProfileLong(const EndianType endian,
01679 unsigned char *buffer)
01680 {
01681 unsigned long
01682 value;
01683
01684 if (endian == MSBEndian)
01685 {
01686 value=(unsigned long) ((buffer[0] << 24) | (buffer[1] << 16) |
01687 (buffer[2] << 8) | buffer[3]);
01688 return((unsigned long) (value & 0xffffffff));
01689 }
01690 value=(unsigned long) ((buffer[3] << 24) | (buffer[2] << 16) |
01691 (buffer[1] << 8 ) | (buffer[0]));
01692 return((unsigned long) (value & 0xffffffff));
01693 }
01694
01695 static inline void WriteProfileLong(const EndianType endian,
01696 const unsigned long value,unsigned char *p)
01697 {
01698 unsigned char
01699 buffer[4];
01700
01701 if (endian == MSBEndian)
01702 {
01703 buffer[0]=(unsigned char) (value >> 24);
01704 buffer[1]=(unsigned char) (value >> 16);
01705 buffer[2]=(unsigned char) (value >> 8);
01706 buffer[3]=(unsigned char) value;
01707 (void) CopyMagickMemory(p,buffer,4);
01708 return;
01709 }
01710 buffer[0]=(unsigned char) value;
01711 buffer[1]=(unsigned char) (value >> 8);
01712 buffer[2]=(unsigned char) (value >> 16);
01713 buffer[3]=(unsigned char) (value >> 24);
01714 (void) CopyMagickMemory(p,buffer,4);
01715 }
01716
01717 static void WriteProfileShort(const EndianType endian,
01718 const unsigned short value,unsigned char *p)
01719 {
01720 unsigned char
01721 buffer[2];
01722
01723 if (endian == MSBEndian)
01724 {
01725 buffer[0]=(unsigned char) (value >> 8);
01726 buffer[1]=(unsigned char) value;
01727 (void) CopyMagickMemory(p,buffer,2);
01728 return;
01729 }
01730 buffer[0]=(unsigned char) value;
01731 buffer[1]=(unsigned char) (value >> 8);
01732 (void) CopyMagickMemory(p,buffer,2);
01733 }
01734
01735 MagickExport MagickBooleanType SyncImageProfiles(Image *image)
01736 {
01737 #define MaxDirectoryStack 16
01738 #define EXIF_DELIMITER "\n"
01739 #define EXIF_NUM_FORMATS 12
01740 #define TAG_EXIF_OFFSET 0x8769
01741 #define TAG_INTEROP_OFFSET 0xa005
01742
01743 typedef struct _DirectoryInfo
01744 {
01745 unsigned char
01746 *directory;
01747
01748 unsigned long
01749 entry;
01750 } DirectoryInfo;
01751
01752 DirectoryInfo
01753 directory_stack[MaxDirectoryStack];
01754
01755 EndianType
01756 endian;
01757
01758 long
01759 id,
01760 level;
01761
01762 size_t
01763 length;
01764
01765 ssize_t
01766 offset;
01767
01768 static int
01769 format_bytes[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
01770
01771 StringInfo
01772 *profile;
01773
01774 unsigned char
01775 *directory,
01776 *exif;
01777
01778 unsigned long
01779 entry,
01780 number_entries;
01781
01782
01783
01784
01785 profile=(StringInfo *) GetImageProfile(image,"EXIF");
01786 if (profile == (StringInfo *) NULL)
01787 return(MagickTrue);
01788 length=GetStringInfoLength(profile);
01789 exif=GetStringInfoDatum(profile);
01790 while (length != 0)
01791 {
01792 if (ReadProfileByte(&exif,&length) != 0x45)
01793 continue;
01794 if (ReadProfileByte(&exif,&length) != 0x78)
01795 continue;
01796 if (ReadProfileByte(&exif,&length) != 0x69)
01797 continue;
01798 if (ReadProfileByte(&exif,&length) != 0x66)
01799 continue;
01800 if (ReadProfileByte(&exif,&length) != 0x00)
01801 continue;
01802 if (ReadProfileByte(&exif,&length) != 0x00)
01803 continue;
01804 break;
01805 }
01806 if (length < 16)
01807 return(MagickFalse);
01808 id=(int) ReadProfileShort(LSBEndian,exif);
01809 endian=LSBEndian;
01810 if (id == 0x4949)
01811 endian=LSBEndian;
01812 else
01813 if (id == 0x4D4D)
01814 endian=MSBEndian;
01815 else
01816 return(MagickFalse);
01817 if (ReadProfileShort(endian,exif+2) != 0x002a)
01818 return(MagickFalse);
01819
01820
01821
01822 offset=(ssize_t) ReadProfileLong(endian,exif+4);
01823 if ((size_t) offset >= length)
01824 return(MagickFalse);
01825 directory=exif+offset;
01826 level=0;
01827 entry=0;
01828 do
01829 {
01830 if (level > 0)
01831 {
01832 level--;
01833 directory=directory_stack[level].directory;
01834 entry=directory_stack[level].entry;
01835 }
01836
01837
01838
01839 number_entries=ReadProfileShort(endian,directory);
01840 for ( ; entry < number_entries; entry++)
01841 {
01842 long
01843 components,
01844 format,
01845 tag_value;
01846
01847 register unsigned char
01848 *p,
01849 *q;
01850
01851 size_t
01852 number_bytes;
01853
01854 q=(unsigned char *) (directory+2+(12*entry));
01855 tag_value=(long) ReadProfileShort(endian,q);
01856 format=(long) ReadProfileShort(endian,q+2);
01857 if ((format-1) >= EXIF_NUM_FORMATS)
01858 break;
01859 components=(long) ReadProfileLong(endian,q+4);
01860 number_bytes=(size_t) components*format_bytes[format];
01861 if (number_bytes <= 4)
01862 p=q+8;
01863 else
01864 {
01865 ssize_t
01866 offset;
01867
01868
01869
01870
01871 offset=(ssize_t) ReadProfileLong(endian,q+8);
01872 if ((size_t) (offset+number_bytes) > length)
01873 continue;
01874 p=(unsigned char *) (exif+offset);
01875 }
01876 switch (tag_value)
01877 {
01878 case 0x011a:
01879 {
01880 (void) WriteProfileLong(endian,(unsigned long)
01881 (image->x_resolution+0.5),p);
01882 (void) WriteProfileLong(endian,1UL,p+4);
01883 break;
01884 }
01885 case 0x011b:
01886 {
01887 (void) WriteProfileLong(endian,(unsigned long)
01888 (image->y_resolution+0.5),p);
01889 (void) WriteProfileLong(endian,1UL,p+4);
01890 break;
01891 }
01892 case 0x0112:
01893 {
01894 (void) WriteProfileShort(endian,(unsigned short)
01895 image->orientation,p);
01896 break;
01897 }
01898 case 0x0128:
01899 {
01900 (void) WriteProfileShort(endian,(unsigned short)
01901 (image->units+1),p);
01902 break;
01903 }
01904 default:
01905 break;
01906 }
01907 if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
01908 {
01909 size_t
01910 offset;
01911
01912 offset=(size_t) ReadProfileLong(endian,p);
01913 if ((offset < length) && (level < (MaxDirectoryStack-2)))
01914 {
01915 directory_stack[level].directory=directory;
01916 entry++;
01917 directory_stack[level].entry=entry;
01918 level++;
01919 directory_stack[level].directory=exif+offset;
01920 directory_stack[level].entry=0;
01921 level++;
01922 if ((directory+2+(12*number_entries)) > (exif+length))
01923 break;
01924 offset=(size_t) ReadProfileLong(endian,directory+2+(12*
01925 number_entries));
01926 if ((offset != 0) && (offset < length) &&
01927 (level < (MaxDirectoryStack-2)))
01928 {
01929 directory_stack[level].directory=exif+offset;
01930 directory_stack[level].entry=0;
01931 level++;
01932 }
01933 }
01934 break;
01935 }
01936 }
01937 } while (level > 0);
01938 return(MagickTrue);
01939 }