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