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
00043
#include "magick/studio.h"
00044
#include "magick/attribute.h"
00045
#include "magick/blob.h"
00046
#include "magick/blob_private.h"
00047
#include "magick/cache.h"
00048
#include "magick/color.h"
00049
#include "magick/color_private.h"
00050
#include "magick/constitute.h"
00051
#include "magick/error.h"
00052
#include "magick/error_private.h"
00053
#include "magick/geometry.h"
00054
#include "magick/hashmap.h"
00055
#include "magick/image.h"
00056
#include "magick/image_private.h"
00057
#include "magick/list.h"
00058
#include "magick/magick.h"
00059
#include "magick/memory_.h"
00060
#include "magick/monitor.h"
00061
#include "magick/option.h"
00062
#include "magick/profile.h"
00063
#include "magick/static.h"
00064
#include "magick/string_.h"
00065
#include "magick/utility.h"
00066
00067
00068
00069
00070 #define PopCharPixel(q,pixel) \
00071
{ \
00072
*(q)++=(unsigned char) (pixel); \
00073
}
00074 #define PopLongPixel(q,pixel) \
00075
{ \
00076
*(q)++=(unsigned char) ((pixel) >> 24); \
00077
*(q)++=(unsigned char) ((pixel) >> 16); \
00078
*(q)++=(unsigned char) ((pixel) >> 8); \
00079
*(q)++=(unsigned char) (pixel); \
00080
}
00081 #define PopShortPixel(q,pixel) \
00082
{ \
00083
*(q)++=(unsigned char) ((pixel) >> 8); \
00084
*(q)++=(unsigned char) (pixel); \
00085
}
00086 #define PushCharPixel(pixel,p) \
00087
{ \
00088
pixel=(unsigned long) (*(p)); \
00089
(p)++; \
00090
}
00091 #define PushLongPixel(pixel,p) \
00092
{ \
00093
pixel=(unsigned long) \
00094
((*(p) << 24) | (*((p)+1) << 16) | (*((p)+2) << 8) | *((p)+3)); \
00095
(p)+=4; \
00096
}
00097 #define PushShortPixel(pixel,p) \
00098
{ \
00099
pixel=(unsigned long) ((*(p) << 8) | *((p)+1)); \
00100
(p)+=2; \
00101
}
00102
00103
00104
00105
00106
static MagickBooleanType
00107
WriteMPCImage(
const ImageInfo *,
Image *);
00108
00109
00110
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 static MagickBooleanType IsMPC(
const unsigned char *magick,
const size_t length)
00137 {
00138
if (length < 14)
00139
return(
MagickFalse);
00140
if (
LocaleNCompare((
char *) magick,
"id=MagickCache",14) == 0)
00141
return(
MagickTrue);
00142
return(
MagickFalse);
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 static Image *
ReadMPCImage(
const ImageInfo *image_info,
ExceptionInfo *
exception)
00175 {
00176
char
00177 cache_filename[
MaxTextExtent],
00178
id[
MaxTextExtent],
00179 keyword[
MaxTextExtent],
00180 *options;
00181
00182
GeometryInfo
00183 geometry_info;
00184
00185
Image
00186 *image;
00187
00188
int
00189 c;
00190
00191
LinkedListInfo
00192 *profiles;
00193
00194
MagickBooleanType
00195 status;
00196
00197
MagickOffsetType
00198 offset;
00199
00200
MagickStatusType
00201 flags;
00202
00203
register long
00204 i;
00205
00206
register unsigned char
00207 *p;
00208
00209 size_t
00210 length;
00211
00212
StringInfo
00213 *profile;
00214
00215
unsigned long
00216 depth,
00217 quantum_depth;
00218
00219
00220
00221
00222
assert(image_info != (
const ImageInfo *) NULL);
00223
assert(image_info->
signature ==
MagickSignature);
00224
if (image_info->
debug !=
MagickFalse)
00225 (
void)
LogMagickEvent(
TraceEvent,
GetMagickModule(),image_info->
filename);
00226
assert(exception != (
ExceptionInfo *) NULL);
00227
assert(exception->
signature ==
MagickSignature);
00228 image=
AllocateImage(image_info);
00229 status=
OpenBlob(image_info,image,
ReadBinaryBlobMode,exception);
00230
if (status ==
MagickFalse)
00231 {
00232
DestroyImageList(image);
00233
return((
Image *) NULL);
00234 }
00235 (
void)
CopyMagickString(cache_filename,image->
filename,
MaxTextExtent);
00236
AppendImageFormat(
"cache",cache_filename);
00237 c=
ReadBlobByte(image);
00238
if (c == EOF)
00239 {
00240 image=
DestroyImage(image);
00241
return((
Image *) NULL);
00242 }
00243 *
id=
'\0';
00244 offset=0;
00245
do
00246 {
00247
00248
00249
00250 profiles=(
LinkedListInfo *) NULL;
00251 length=
MaxTextExtent;
00252 options=
AcquireString((
char *) NULL);
00253 quantum_depth=
QuantumDepth;
00254 image->
depth=8;
00255 image->
compression=
NoCompression;
00256
while ((isgraph(c) !=
MagickFalse) && (c != (
int)
':'))
00257 {
00258
register char
00259 *p;
00260
00261
if (c == (
int)
'{')
00262 {
00263
char
00264 *comment;
00265
00266
00267
00268
00269 length=
MaxTextExtent;
00270 comment=
AcquireString((
char *) NULL);
00271
for (p=comment; comment != (
char *) NULL; p++)
00272 {
00273 c=
ReadBlobByte(image);
00274
if ((c == EOF) || (c == (
int)
'}'))
00275
break;
00276
if ((size_t) (p-comment+1) >= length)
00277 {
00278 *p=
'\0';
00279 length<<=1;
00280 comment=(
char *)
ResizeMagickMemory(comment,
00281 (length+
MaxTextExtent)*
sizeof(*comment));
00282
if (comment == (
char *) NULL)
00283
break;
00284 p=comment+strlen(comment);
00285 }
00286 *p=(
char) c;
00287 }
00288
if (comment == (
char *) NULL)
00289
ThrowReaderException(
ResourceLimitError,
"MemoryAllocationFailed");
00290 *p=
'\0';
00291 (
void)
SetImageAttribute(image,
"Comment",comment);
00292 comment=(
char *)
RelinquishMagickMemory(comment);
00293 c=
ReadBlobByte(image);
00294 }
00295
else
00296
if (isalnum(c) !=
MagickFalse)
00297 {
00298
00299
00300
00301 p=keyword;
00302
do
00303 {
00304
if (isspace((
int) ((
unsigned char) c)) != 0)
00305
break;
00306
if (c == (
int)
'=')
00307
break;
00308
if ((size_t) (p-keyword) < (
MaxTextExtent-1))
00309 *p++=(
char) c;
00310 c=
ReadBlobByte(image);
00311 }
while (c != EOF);
00312 *p=
'\0';
00313 p=options;
00314
while (isspace((
int) ((
unsigned char) c)) != 0)
00315 c=
ReadBlobByte(image);
00316
if (c == (
int)
'=')
00317 {
00318
00319
00320
00321 c=
ReadBlobByte(image);
00322
while ((c != (
int)
'}') && (c != EOF))
00323 {
00324
if ((size_t) (p-options+1) >= length)
00325 {
00326 *p=
'\0';
00327 length<<=1;
00328 options=(
char *)
ResizeMagickMemory(options,
00329 (length+
MaxTextExtent)*
sizeof(*options));
00330
if (options == (
char *) NULL)
00331
break;
00332 p=options+strlen(options);
00333 }
00334
if (options == (
char *) NULL)
00335
ThrowReaderException(
ResourceLimitError,
00336
"MemoryAllocationFailed");
00337 *p++=(
char) c;
00338 c=
ReadBlobByte(image);
00339
if (*options !=
'{')
00340
if (isspace((
int) ((
unsigned char) c)) != 0)
00341
break;
00342 }
00343 }
00344 *p=
'\0';
00345
if (*options ==
'{')
00346 (
void)
CopyMagickString(options,options+1,
MaxTextExtent);
00347
00348
00349
00350
switch (*keyword)
00351 {
00352
case 'b':
00353
case 'B':
00354 {
00355
if (
LocaleCompare(keyword,
"background-color") == 0)
00356 {
00357 (
void)
QueryColorDatabase(options,&image->
background_color,
00358 exception);
00359
break;
00360 }
00361
if (
LocaleCompare(keyword,
"blue-primary") == 0)
00362 {
00363 flags=
ParseGeometry(options,&geometry_info);
00364 image->
chromaticity.
blue_primary.
x=geometry_info.
rho;
00365 image->
chromaticity.
blue_primary.
y=geometry_info.
sigma;
00366
if ((flags &
SigmaValue) == 0)
00367 image->
chromaticity.
blue_primary.
y=
00368 image->
chromaticity.
blue_primary.
x;
00369
break;
00370 }
00371
if (
LocaleCompare(keyword,
"border-color") == 0)
00372 {
00373 (
void)
QueryColorDatabase(options,&image->
border_color,
00374 exception);
00375
break;
00376 }
00377 (
void)
SetImageAttribute(image,keyword,options);
00378
break;
00379 }
00380
case 'c':
00381
case 'C':
00382 {
00383
if (
LocaleCompare(keyword,
"class") == 0)
00384 {
00385 image->
storage_class=(
ClassType)
00386
ParseMagickOption(
MagickClassOptions,
MagickFalse,options);
00387
break;
00388 }
00389
if (
LocaleCompare(keyword,
"colors") == 0)
00390 {
00391 image->
colors=(
unsigned long) atol(options);
00392
break;
00393 }
00394
if (
LocaleCompare(keyword,
"colorspace") == 0)
00395 {
00396 image->
colorspace=(
ColorspaceType)
ParseMagickOption(
00397
MagickColorspaceOptions,
MagickFalse,options);
00398
break;
00399 }
00400
if (
LocaleCompare(keyword,
"compression") == 0)
00401 {
00402 image->
compression=(
CompressionType)
ParseMagickOption(
00403
MagickCompressionOptions,
MagickFalse,options);
00404
break;
00405 }
00406
if (
LocaleCompare(keyword,
"columns") == 0)
00407 {
00408 image->
columns=(
unsigned long) atol(options);
00409
break;
00410 }
00411 (
void)
SetImageAttribute(image,keyword,options);
00412
break;
00413 }
00414
case 'd':
00415
case 'D':
00416 {
00417
if (
LocaleCompare(keyword,
"delay") == 0)
00418 {
00419 image->
delay=(
unsigned long) atol(options);
00420
break;
00421 }
00422
if (
LocaleCompare(keyword,
"depth") == 0)
00423 {
00424 image->
depth=(
unsigned long) atol(options);
00425
break;
00426 }
00427
if (
LocaleCompare(keyword,
"dispose") == 0)
00428 {
00429 image->
dispose=(
DisposeType)
ParseMagickOption(
00430
MagickDisposeOptions,
MagickFalse,options);
00431
break;
00432 }
00433 (
void)
SetImageAttribute(image,keyword,options);
00434
break;
00435 }
00436
case 'e':
00437
case 'E':
00438 {
00439
if (
LocaleCompare(keyword,
"error") == 0)
00440 {
00441 image->
error.
mean_error_per_pixel=atof(options);
00442
break;
00443 }
00444 (
void)
SetImageAttribute(image,keyword,options);
00445
break;
00446 }
00447
case 'g':
00448
case 'G':
00449 {
00450
if (
LocaleCompare(keyword,
"gamma") == 0)
00451 {
00452 image->
gamma=atof(options);
00453
break;
00454 }
00455
if (
LocaleCompare(keyword,
"green-primary") == 0)
00456 {
00457 flags=
ParseGeometry(options,&geometry_info);
00458 image->
chromaticity.
green_primary.
x=geometry_info.
rho;
00459 image->
chromaticity.
green_primary.
y=geometry_info.
sigma;
00460
if ((flags &
SigmaValue) == 0)
00461 image->
chromaticity.
green_primary.
y=
00462 image->
chromaticity.
green_primary.
x;
00463
break;
00464 }
00465 (
void)
SetImageAttribute(image,keyword,options);
00466
break;
00467 }
00468
case 'i':
00469
case 'I':
00470 {
00471
if (
LocaleCompare(keyword,
"id") == 0)
00472 {
00473 (
void)
CopyMagickString(
id,options,
MaxTextExtent);
00474
break;
00475 }
00476
if (
LocaleCompare(keyword,
"iterations") == 0)
00477 {
00478 image->
iterations=(
unsigned long) atol(options);
00479
break;
00480 }
00481 (
void)
SetImageAttribute(image,keyword,options);
00482
break;
00483 }
00484
case 'm':
00485
case 'M':
00486 {
00487
if (
LocaleCompare(keyword,
"matte") == 0)
00488 {
00489 image->
matte=(
MagickBooleanType)
ParseMagickOption(
00490
MagickBooleanOptions,
MagickFalse,options);
00491
break;
00492 }
00493
if (
LocaleCompare(keyword,
"matte-color") == 0)
00494 {
00495 (
void)
QueryColorDatabase(options,&image->
matte_color,
00496 exception);
00497
break;
00498 }
00499
if (
LocaleCompare(keyword,
"maximum-error") == 0)
00500 {
00501 image->
error.
normalized_maximum_error=atof(options);
00502
break;
00503 }
00504
if (
LocaleCompare(keyword,
"mean-error") == 0)
00505 {
00506 image->
error.
normalized_mean_error=atof(options);
00507
break;
00508 }
00509
if (
LocaleCompare(keyword,
"montage") == 0)
00510 {
00511 (
void)
CloneString(&image->
montage,options);
00512
break;
00513 }
00514 (
void)
SetImageAttribute(image,keyword,options);
00515
break;
00516 }
00517
case 'p':
00518
case 'P':
00519 {
00520
if (
LocaleCompare(keyword,
"page") == 0)
00521 {
00522
char
00523 *geometry;
00524
00525 geometry=
GetPageGeometry(options);
00526 (
void)
ParseAbsoluteGeometry(geometry,&image->
page);
00527 geometry=(
char *)
RelinquishMagickMemory(geometry);
00528
break;
00529 }
00530
if (
LocaleNCompare(keyword,
"profile-",8) == 0)
00531 {
00532
if (profiles == (
LinkedListInfo *) NULL)
00533 profiles=
NewLinkedList(0);
00534 (
void)
AppendElementToLinkedList(profiles,
00535
AcquireString(keyword+8));
00536 profile=
AcquireStringInfo((size_t) atol(options));
00537 (
void)
SetImageProfile(image,keyword+8,profile);
00538 profile=
DestroyStringInfo(profile);
00539
break;
00540 }
00541 (
void)
SetImageAttribute(image,keyword,options);
00542
break;
00543 }
00544
case 'o':
00545
case 'O':
00546 {
00547
if (
LocaleCompare(keyword,
"opaque") == 0)
00548 {
00549 image->
matte=(
MagickBooleanType)
ParseMagickOption(
00550
MagickBooleanOptions,
MagickFalse,options);
00551
break;
00552 }
00553 (
void)
SetImageAttribute(image,keyword,options);
00554
break;
00555 }
00556
case 'q':
00557
case 'Q':
00558 {
00559
if (
LocaleCompare(keyword,
"quantum-depth") == 0)
00560 {
00561 quantum_depth=(
unsigned long) atol(options);
00562
break;
00563 }
00564 (
void)
SetImageAttribute(image,keyword,options);
00565
break;
00566 }
00567
case 'r':
00568
case 'R':
00569 {
00570
if (
LocaleCompare(keyword,
"red-primary") == 0)
00571 {
00572 flags=
ParseGeometry(options,&geometry_info);
00573 image->
chromaticity.
red_primary.
x=geometry_info.
rho;
00574
if ((flags &
SigmaValue) != 0)
00575 image->
chromaticity.
red_primary.
y=geometry_info.
sigma;
00576
break;
00577 }
00578
if (
LocaleCompare(keyword,
"rendering-intent") == 0)
00579 {
00580 image->
rendering_intent=(
RenderingIntent)
ParseMagickOption(
00581
MagickIntentOptions,
MagickFalse,options);
00582
break;
00583 }
00584
if (
LocaleCompare(keyword,
"resolution") == 0)
00585 {
00586 flags=
ParseGeometry(options,&geometry_info);
00587 image->
x_resolution=geometry_info.
rho;
00588 image->
y_resolution=geometry_info.
sigma;
00589
if ((flags &
SigmaValue) == 0)
00590 image->
y_resolution=image->
x_resolution;
00591
break;
00592 }
00593
if (
LocaleCompare(keyword,
"rows") == 0)
00594 {
00595 image->
rows=(
unsigned long) atol(options);
00596
break;
00597 }
00598 (
void)
SetImageAttribute(image,keyword,options);
00599
break;
00600 }
00601
case 's':
00602
case 'S':
00603 {
00604
if (
LocaleCompare(keyword,
"scene") == 0)
00605 {
00606 image->
scene=(
unsigned long) atol(options);
00607
break;
00608 }
00609 (
void)
SetImageAttribute(image,keyword,options);
00610
break;
00611 }
00612
case 'u':
00613
case 'U':
00614 {
00615
if (
LocaleCompare(keyword,
"units") == 0)
00616 {
00617 image->
units=(
ResolutionType)
ParseMagickOption(
00618
MagickResolutionOptions,
MagickFalse,options);
00619
break;
00620 }
00621 (
void)
SetImageAttribute(image,keyword,options);
00622
break;
00623 }
00624
case 'w':
00625
case 'W':
00626 {
00627
if (
LocaleCompare(keyword,
"white-point") == 0)
00628 {
00629 flags=
ParseGeometry(options,&geometry_info);
00630 image->
chromaticity.
white_point.
x=geometry_info.
rho;
00631 image->
chromaticity.
white_point.
y=geometry_info.
sigma;
00632
if ((flags &
SigmaValue) == 0)
00633 image->
chromaticity.
white_point.
y=
00634 image->
chromaticity.
white_point.
x;
00635
break;
00636 }
00637 (
void)
SetImageAttribute(image,keyword,options);
00638
break;
00639 }
00640
default:
00641 {
00642 (
void)
SetImageAttribute(image,keyword,options);
00643
break;
00644 }
00645 }
00646 }
00647
else
00648 c=
ReadBlobByte(image);
00649
while (isspace((
int) ((
unsigned char) c)) != 0)
00650 c=
ReadBlobByte(image);
00651 }
00652 options=(
char *)
RelinquishMagickMemory(options);
00653 (
void)
ReadBlobByte(image);
00654
00655
00656
00657
if ((
LocaleCompare(
id,
"MagickCache") != 0) ||
00658 (image->
storage_class ==
UndefinedClass) ||
00659 (image->
compression ==
UndefinedCompression) || (image->
columns == 0) ||
00660 (image->
rows == 0))
00661
ThrowReaderException(
CorruptImageError,
"ImproperImageHeader");
00662
if (quantum_depth !=
QuantumDepth)
00663
ThrowReaderException(
CacheError,
"InconsistentPersistentCacheDepth");
00664
if (image->
montage != (
char *) NULL)
00665 {
00666
register char
00667 *p;
00668
00669
00670
00671
00672 length=
MaxTextExtent;
00673 image->
directory=
AcquireString((
char *) NULL);
00674 p=image->
directory;
00675
do
00676 {
00677 *p=
'\0';
00678
if ((strlen(image->
directory)+
MaxTextExtent) >= length)
00679 {
00680
00681
00682
00683 length<<=1;
00684 image->
directory=(
char *)
ResizeMagickMemory(image->
directory,
00685 (length+
MaxTextExtent)*
sizeof(*image->
directory));
00686
if (image->
directory == (
char *) NULL)
00687
ThrowReaderException(
CorruptImageError,
"UnableToReadImageData");
00688 p=image->
directory+strlen(image->
directory);
00689 }
00690 c=
ReadBlobByte(image);
00691 *p++=(
char) c;
00692 }
while (c != (
int)
'\0');
00693 }
00694
if (profiles != (
LinkedListInfo *) NULL)
00695 {
00696
const char
00697 *
name;
00698
00699
00700
00701
00702
ResetLinkedListIterator(profiles);
00703
name=(
const char *)
GetNextElementInLinkedList(profiles);
00704
while (
name != (
const char *) NULL)
00705 {
00706 profile=
GetImageProfile(image,
name);
00707
if (profile != (
StringInfo *) NULL)
00708 (
void)
ReadBlob(image,profile->
length,profile->
datum);
00709
name=(
const char *)
GetNextElementInLinkedList(profiles);
00710 }
00711 profiles=
DestroyLinkedList(profiles,
RelinquishMagickMemory);
00712 }
00713 depth=
GetImageQuantumDepth(image,
MagickFalse);
00714
if (image->
storage_class ==
PseudoClass)
00715 {
00716
00717
00718
00719
if (
AllocateImageColormap(image,image->
colors) ==
MagickFalse)
00720
ThrowReaderException(
ResourceLimitError,
"MemoryAllocationFailed");
00721
if (image->
colors != 0)
00722 {
00723 size_t
00724 packet_size;
00725
00726
unsigned char
00727 *colormap;
00728
00729
unsigned long
00730 pixel;
00731
00732
00733
00734
00735 packet_size=(size_t) (3*depth/8);
00736 colormap=(
unsigned char *)
00737
AcquireMagickMemory(packet_size*image->
colors);
00738
if (colormap == (
unsigned char *) NULL)
00739
ThrowReaderException(
ResourceLimitError,
"MemoryAllocationFailed");
00740 (
void)
ReadBlob(image,packet_size*image->
colors,colormap);
00741 p=colormap;
00742
switch (depth)
00743 {
00744
default:
00745
ThrowReaderException(
CorruptImageError,
00746
"ImageDepthNotSupported");
00747
case 8:
00748 {
00749
for (i=0; i < (
long) image->
colors; i++)
00750 {
00751
PushCharPixel(pixel,p);
00752 image->
colormap[i].
red=
ScaleCharToQuantum(pixel);
00753
PushCharPixel(pixel,p);
00754 image->
colormap[i].
green=
ScaleCharToQuantum(pixel);
00755
PushCharPixel(pixel,p);
00756 image->
colormap[i].
blue=
ScaleCharToQuantum(pixel);
00757 }
00758
break;
00759 }
00760
case 16:
00761 {
00762
for (i=0; i < (
long) image->
colors; i++)
00763 {
00764
PushShortPixel(pixel,p);
00765 image->
colormap[i].
red=
ScaleShortToQuantum(pixel);
00766
PushShortPixel(pixel,p);
00767 image->
colormap[i].
green=
ScaleShortToQuantum(pixel);
00768
PushShortPixel(pixel,p);
00769 image->
colormap[i].
blue=
ScaleShortToQuantum(pixel);
00770 }
00771
break;
00772 }
00773
case 32:
00774 {
00775
for (i=0; i < (
long) image->
colors; i++)
00776 {
00777
PushLongPixel(pixel,p);
00778 image->
colormap[i].
red=
ScaleLongToQuantum(pixel);
00779
PushLongPixel(pixel,p);
00780 image->
colormap[i].
green=
ScaleLongToQuantum(pixel);
00781
PushLongPixel(pixel,p);
00782 image->
colormap[i].
blue=
ScaleLongToQuantum(pixel);
00783 }
00784
break;
00785 }
00786 }
00787 colormap=(
unsigned char *)
RelinquishMagickMemory(colormap);
00788 }
00789 }
00790
if (
EOFBlob(image) !=
MagickFalse)
00791 {
00792
ThrowFileException(exception,
CorruptImageError,
"UnexpectedEndOfFile",
00793 image->
filename);
00794
break;
00795 }
00796
if ((image_info->
ping !=
MagickFalse) && (image_info->
number_scenes != 0))
00797
if (image->
scene >= (image_info->
scene+image_info->
number_scenes-1))
00798
break;
00799
00800
00801
00802 status=
PersistCache(image,cache_filename,
MagickTrue,&offset,exception);
00803
if (status ==
MagickFalse)
00804
ThrowReaderException(
CacheError,
"UnableToPersistPixelCache");
00805
00806
00807
00808
do
00809 {
00810 c=
ReadBlobByte(image);
00811 }
while ((isgraph(c) ==
MagickFalse) && (c != EOF));
00812
if (c != EOF)
00813 {
00814
00815
00816
00817
AllocateNextImage(image_info,image);
00818
if (image->
next == (
Image *) NULL)
00819 {
00820
DestroyImageList(image);
00821
return((
Image *) NULL);
00822 }
00823 image=
SyncNextImageInList(image);
00824
if (image->
progress_monitor != (
MagickProgressMonitor) NULL)
00825 {
00826 status=image->
progress_monitor(
LoadImagesTag,
TellBlob(image),
00827
GetBlobSize(image),image->
client_data);
00828
if (status ==
MagickFalse)
00829
break;
00830 }
00831 }
00832 }
while (c != EOF);
00833
CloseBlob(image);
00834
return(
GetFirstImageInList(image));
00835 }
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860 ModuleExport void RegisterMPCImage(
void)
00861 {
00862
MagickInfo
00863 *entry;
00864
00865 entry=
SetMagickInfo(
"CACHE");
00866 entry->
description=
AcquireString(
"Magick Persistent Cache image format");
00867 entry->
module=
AcquireString(
"CACHE");
00868 (
void)
RegisterMagickInfo(entry);
00869 entry=
SetMagickInfo(
"MPC");
00870 entry->
decoder=(
DecoderHandler *)
ReadMPCImage;
00871 entry->
encoder=(
EncoderHandler *)
WriteMPCImage;
00872 entry->
magick=(
MagickHandler *)
IsMPC;
00873 entry->
description=
AcquireString(
"Magick Persistent Cache image format");
00874 entry->
module=
AcquireString(
"MPC");
00875 (
void)
RegisterMagickInfo(entry);
00876 }
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 ModuleExport void UnregisterMPCImage(
void)
00898 {
00899 (
void)
UnregisterMagickInfo(
"CACHE");
00900 (
void)
UnregisterMagickInfo(
"MPC");
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928 static MagickBooleanType WriteMPCImage(
const ImageInfo *image_info,
Image *image)
00929 {
00930
char
00931 buffer[
MaxTextExtent],
00932 cache_filename[
MaxTextExtent];
00933
00934
const ImageAttribute
00935 *attribute;
00936
00937
MagickBooleanType
00938 status;
00939
00940
MagickOffsetType
00941 offset,
00942 scene;
00943
00944
register long
00945 i;
00946
00947
00948
00949
00950
assert(image_info != (
const ImageInfo *) NULL);
00951
assert(image_info->
signature ==
MagickSignature);
00952
assert(image != (
Image *) NULL);
00953
assert(image->
signature ==
MagickSignature);
00954
if (image->
debug !=
MagickFalse)
00955 (
void)
LogMagickEvent(
TraceEvent,
GetMagickModule(),image->
filename);
00956 status=
OpenBlob(image_info,image,
WriteBinaryBlobMode,&image->
exception);
00957
if (status ==
MagickFalse)
00958
return(status);
00959 (
void)
CopyMagickString(cache_filename,image->
filename,
MaxTextExtent);
00960
AppendImageFormat(
"cache",cache_filename);
00961 scene=0;
00962 offset=0;
00963
do
00964 {
00965
00966
00967
00968 (
void)
WriteBlobString(image,
"id=MagickCache\n");
00969 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"quantum-depth=%d\n",
00970
QuantumDepth);
00971 (
void)
WriteBlobString(image,buffer);
00972 (
void)
FormatMagickString(buffer,
MaxTextExtent,
00973
"class=%s colors=%lu matte=%s\n",
MagickOptionToMnemonic(
00974
MagickClassOptions,image->
storage_class),image->
colors,
00975
MagickOptionToMnemonic(
MagickBooleanOptions,(
long) image->
matte));
00976 (
void)
WriteBlobString(image,buffer);
00977 (
void)
FormatMagickString(buffer,
MaxTextExtent,
00978
"columns=%lu rows=%lu depth=%lu\n",image->
columns,image->
rows,
00979 image->
depth);
00980 (
void)
WriteBlobString(image,buffer);
00981
if (image->
colorspace !=
UndefinedColorspace)
00982 {
00983 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"colorspace=%s\n",
00984
MagickOptionToMnemonic(
MagickColorspaceOptions,image->
colorspace));
00985 (
void)
WriteBlobString(image,buffer);
00986 }
00987
if (image->
compression !=
UndefinedCompression)
00988 {
00989 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"compression=%s\n",
00990
MagickOptionToMnemonic(
MagickCompressionOptions,image->
compression));
00991 (
void)
WriteBlobString(image,buffer);
00992 }
00993
if (image->
units !=
UndefinedResolution)
00994 {
00995 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"units=%s\n",
00996
MagickOptionToMnemonic(
MagickResolutionOptions,image->
units));
00997 (
void)
WriteBlobString(image,buffer);
00998 }
00999
if ((image->
x_resolution != 0) || (image->
y_resolution != 0))
01000 {
01001 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"resolution=%gx%g\n",
01002 image->
x_resolution,image->
y_resolution);
01003 (
void)
WriteBlobString(image,buffer);
01004 }
01005
if ((image->
page.
width != 0) || (image->
page.
height != 0))
01006 {
01007 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"page=%lux%lu%+ld%+ld\n",
01008 image->
page.
width,image->
page.
height,image->
page.
x,image->
page.
y);
01009 (
void)
WriteBlobString(image,buffer);
01010 }
01011
else
01012
if ((image->
page.
x != 0) || (image->
page.
y != 0))
01013 {
01014 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"page=%+ld%+ld\n",
01015 image->
page.
x,image->
page.
y);
01016 (
void)
WriteBlobString(image,buffer);
01017 }
01018
if ((image->
next != (
Image *) NULL) || (image->
previous != (
Image *) NULL))
01019 {
01020
if (image->
scene == 0)
01021 (
void)
FormatMagickString(buffer,
MaxTextExtent,
01022
"iterations=%lu delay=%lu\n",image->
iterations,image->
delay);
01023
else
01024 (
void)
FormatMagickString(buffer,
MaxTextExtent,
01025
"scene=%lu iterations=%lu delay=%lu\n",image->
scene,
01026 image->
iterations,image->
delay);
01027 (
void)
WriteBlobString(image,buffer);
01028 }
01029
else
01030 {
01031
if (image->
scene != 0)
01032 {
01033 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"scene=%lu\n",
01034 image->
scene);
01035 (
void)
WriteBlobString(image,buffer);
01036 }
01037
if (image->
iterations != 0)
01038 {
01039 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"iterations=%lu\n",
01040 image->
iterations);
01041 (
void)
WriteBlobString(image,buffer);
01042 }
01043
if (image->
delay != 0)
01044 {
01045 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"delay=%lu\n",
01046 image->
delay);
01047 (
void)
WriteBlobString(image,buffer);
01048 }
01049 }
01050
if (image->
dispose !=
UndefinedDispose)
01051 {
01052 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"dispose=%s\n",
01053
MagickOptionToMnemonic(
MagickDisposeOptions,image->
dispose));
01054 (
void)
WriteBlobString(image,buffer);
01055 }
01056
if (image->
compose !=
UndefinedCompositeOp)
01057 {
01058 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"compose=%s\n",
01059
MagickOptionToMnemonic(
MagickCompositeOptions,image->
compose));
01060 (
void)
WriteBlobString(image,buffer);
01061 }
01062
if (image->
error.
mean_error_per_pixel != 0.0)
01063 {
01064 (
void)
FormatMagickString(buffer,
MaxTextExtent,
01065
"error=%g mean-error=%g maximum-error=%g\n",
01066 image->
error.
mean_error_per_pixel,image->
error.
normalized_mean_error,
01067 image->
error.
normalized_maximum_error);
01068 (
void)
WriteBlobString(image,buffer);
01069 }
01070
if (image->
rendering_intent !=
UndefinedIntent)
01071 {
01072 (
void)
FormatMagickString(buffer,
MaxTextExtent,
01073
"rendering-intent=%s\n",
01074
MagickOptionToMnemonic(
MagickIntentOptions,image->
rendering_intent));
01075 (
void)
WriteBlobString(image,buffer);
01076 }
01077
if (image->
gamma != 0.0)
01078 {
01079 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"gamma=%g\n",
01080 image->
gamma);
01081 (
void)
WriteBlobString(image,buffer);
01082 }
01083
if (image->
chromaticity.
white_point.
x != 0.0)
01084 {
01085
01086
01087
01088 (
void)
FormatMagickString(buffer,
MaxTextExtent,
01089
"red-primary=%g,%g green-primary=%g,%g blue-primary=%g,%g\n",
01090 image->
chromaticity.
red_primary.
x,image->
chromaticity.
red_primary.
y,
01091 image->
chromaticity.
green_primary.
x,
01092 image->
chromaticity.
green_primary.
y,
01093 image->
chromaticity.
blue_primary.
x,
01094 image->
chromaticity.
blue_primary.
y);
01095 (
void)
WriteBlobString(image,buffer);
01096 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"white-point=%g,%g\n",
01097 image->
chromaticity.
white_point.
x,image->
chromaticity.
white_point.
y);
01098 (
void)
WriteBlobString(image,buffer);
01099 }
01100
if (image->
profiles != (
HashmapInfo *) NULL)
01101 {
01102
const char
01103 *
name;
01104
01105
const StringInfo
01106 *profile;
01107
01108
01109
01110
01111
ResetImageProfileIterator(image);
01112
name=
GetNextImageProfile(image);
01113
while (
name != (
const char *) NULL)
01114 {
01115 profile=
GetImageProfile(image,
name);
01116 (
void)
FormatMagickString(buffer,
MaxTextExtent,
01117
"profile-%s=%lu\n",
name,(
unsigned long) profile->
length);
01118 (
void)
WriteBlobString(image,buffer);
01119
name=
GetNextImageProfile(image);
01120 }
01121 }
01122
if (image->
montage != (
char *) NULL)
01123 {
01124 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"montage=%s\n",
01125 image->
montage);
01126 (
void)
WriteBlobString(image,buffer);
01127 }
01128 attribute=
GetImageAttribute(image,(
char *) NULL);
01129
for ( ; attribute != (
const ImageAttribute *) NULL; attribute=attribute->
next)
01130 {
01131
if (attribute->
value != NULL)
01132 {
01133
long
01134 j;
01135
01136 (
void)
FormatMagickString(buffer,
MaxTextExtent,
"%s=",
01137 attribute->
key);
01138 (
void)
WriteBlobString(image,buffer);
01139
for (j=0; j < (
long) strlen(attribute->
value); j++)
01140
if (isspace((
int) ((
unsigned char) attribute->
value[j])) != 0)
01141
break;
01142
if (j < (
long) strlen(attribute->
value))
01143 (
void)
WriteBlobByte(image,
'{');
01144 (
void)
WriteBlobString(image,attribute->
value);
01145
if (j < (
long) strlen(attribute->
value))
01146 (
void)
WriteBlobByte(image,
'}');
01147 (
void)
WriteBlobByte(image,
'\n');
01148 }
01149 }
01150 (
void)
WriteBlobString(image,
"\f\n:\032");
01151
if (image->
montage != (
char *) NULL)
01152 {
01153
01154
01155
01156
if (image->
directory != (
char *) NULL)
01157 (
void)
WriteBlobString(image,image->
directory);
01158 (
void)
WriteBlobByte(image,
'\0');
01159 }
01160
if (image->
profiles != 0)
01161 {
01162
const char
01163 *
name;
01164
01165
const StringInfo
01166 *profile;
01167
01168
01169
01170
01171
ResetImageProfileIterator(image);
01172
name=
GetNextImageProfile(image);
01173
while (
name != (
const char *) NULL)
01174 {
01175 profile=
GetImageProfile(image,
name);
01176 (
void)
WriteBlob(image,profile->
length,profile->
datum);
01177
name=
GetNextImageProfile(image);
01178 }
01179 }
01180
if (image->
storage_class ==
PseudoClass)
01181 {
01182
register unsigned char
01183 *q;
01184
01185 size_t
01186 packet_size;
01187
01188
unsigned char
01189 *colormap;
01190
01191
unsigned long
01192 depth,
01193 pixel;
01194
01195
01196
01197
01198 depth=
GetImageQuantumDepth(image,
MagickTrue);
01199 packet_size=(size_t) (depth > 8 ? 6 : 3);
01200 colormap=(
unsigned char *)
01201
AcquireMagickMemory(packet_size*image->
colors);
01202
if (colormap == (
unsigned char *) NULL)
01203
return(
MagickFalse);
01204
01205
01206
01207 q=colormap;
01208
for (i=0; i < (
long) image->
colors; i++)
01209 {
01210
switch (depth)
01211 {
01212
default:
01213
ThrowWriterException(
CorruptImageError,
"ImageDepthNotSupported");
01214
case 32:
01215 {
01216 pixel=
ScaleQuantumToLong(image->
colormap[i].
red);
01217
PopLongPixel(q,pixel);
01218 pixel=
ScaleQuantumToLong(image->
colormap[i].
green);
01219
PopLongPixel(q,pixel);
01220 pixel=
ScaleQuantumToLong(image->
colormap[i].
blue);
01221
PopLongPixel(q,pixel);
01222 }
01223
case 16:
01224 {
01225 pixel=
ScaleQuantumToShort(image->
colormap[i].
red);
01226
PopShortPixel(q,pixel);
01227 pixel=
ScaleQuantumToShort(image->
colormap[i].
green);
01228
PopShortPixel(q,pixel);
01229 pixel=
ScaleQuantumToShort(image->
colormap[i].
blue);
01230
PopShortPixel(q,pixel);
01231
break;
01232 }
01233
case 8:
01234 {
01235 pixel=(
unsigned long)
ScaleQuantumToChar(image->
colormap[i].
red);
01236
PopCharPixel(q,pixel);
01237 pixel=(
unsigned long)
01238
ScaleQuantumToChar(image->
colormap[i].
green);
01239
PopCharPixel(q,pixel);
01240 pixel=(
unsigned long)
ScaleQuantumToChar(image->
colormap[i].
blue);
01241
PopCharPixel(q,pixel);
01242
break;
01243 }
01244 }
01245 }
01246 (
void)
WriteBlob(image,packet_size*image->
colors