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