/src/imagemagick/coders/mpc.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
3 | | % % |
4 | | % % |
5 | | % % |
6 | | % M M PPPP CCCC % |
7 | | % MM MM P P C % |
8 | | % M M M PPPP C % |
9 | | % M M P C % |
10 | | % M M P CCCC % |
11 | | % % |
12 | | % % |
13 | | % Read/Write Magick Pixel Cache Image Format % |
14 | | % % |
15 | | % Software Design % |
16 | | % Cristy % |
17 | | % March 2000 % |
18 | | % % |
19 | | % % |
20 | | % Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization % |
21 | | % dedicated to making software imaging solutions freely available. % |
22 | | % % |
23 | | % You may not use this file except in compliance with the License. You may % |
24 | | % obtain a copy of the License at % |
25 | | % % |
26 | | % https://imagemagick.org/script/license.php % |
27 | | % % |
28 | | % Unless required by applicable law or agreed to in writing, software % |
29 | | % distributed under the License is distributed on an "AS IS" BASIS, % |
30 | | % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % |
31 | | % See the License for the specific language governing permissions and % |
32 | | % limitations under the License. % |
33 | | % % |
34 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
35 | | % |
36 | | % |
37 | | % |
38 | | */ |
39 | | |
40 | | /* |
41 | | Include declarations. |
42 | | */ |
43 | | #include "MagickCore/studio.h" |
44 | | #include "MagickCore/artifact.h" |
45 | | #include "MagickCore/attribute.h" |
46 | | #include "MagickCore/blob.h" |
47 | | #include "MagickCore/blob-private.h" |
48 | | #include "MagickCore/cache.h" |
49 | | #include "MagickCore/color.h" |
50 | | #include "MagickCore/color-private.h" |
51 | | #include "MagickCore/colormap.h" |
52 | | #include "MagickCore/constitute.h" |
53 | | #include "MagickCore/exception.h" |
54 | | #include "MagickCore/exception-private.h" |
55 | | #include "MagickCore/geometry.h" |
56 | | #include "MagickCore/image.h" |
57 | | #include "MagickCore/image-private.h" |
58 | | #include "MagickCore/linked-list.h" |
59 | | #include "MagickCore/list.h" |
60 | | #include "MagickCore/magick.h" |
61 | | #include "MagickCore/memory_.h" |
62 | | #include "MagickCore/module.h" |
63 | | #include "MagickCore/monitor.h" |
64 | | #include "MagickCore/monitor-private.h" |
65 | | #include "MagickCore/option.h" |
66 | | #include "MagickCore/pixel-private.h" |
67 | | #include "MagickCore/profile-private.h" |
68 | | #include "MagickCore/property.h" |
69 | | #include "MagickCore/quantum-private.h" |
70 | | #include "MagickCore/resource_.h" |
71 | | #include "MagickCore/static.h" |
72 | | #include "MagickCore/statistic.h" |
73 | | #include "MagickCore/string_.h" |
74 | | #include "MagickCore/string-private.h" |
75 | | #include "MagickCore/utility.h" |
76 | | #include "MagickCore/version-private.h" |
77 | | |
78 | | /* |
79 | | Define declarations. |
80 | | */ |
81 | 9.00k | #define MagickPixelCacheNonce "MagickPixelCache" |
82 | | |
83 | | /* |
84 | | Forward declarations. |
85 | | */ |
86 | | static MagickBooleanType |
87 | | WriteMPCImage(const ImageInfo *,Image *,ExceptionInfo *); |
88 | | |
89 | | /* |
90 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
91 | | % % |
92 | | % % |
93 | | % % |
94 | | % I s M P C % |
95 | | % % |
96 | | % % |
97 | | % % |
98 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
99 | | % |
100 | | % IsMPC() returns MagickTrue if the image format type, identified by the |
101 | | % magick string, is an Magick Pixel Cache image. |
102 | | % |
103 | | % The format of the IsMPC method is: |
104 | | % |
105 | | % MagickBooleanType IsMPC(const unsigned char *magick,const size_t length) |
106 | | % |
107 | | % A description of each parameter follows: |
108 | | % |
109 | | % o magick: compare image format pattern against these bytes. |
110 | | % |
111 | | % o length: Specifies the length of the magick string. |
112 | | % |
113 | | */ |
114 | | static MagickBooleanType IsMPC(const unsigned char *magick,const size_t length) |
115 | 0 | { |
116 | 0 | if (length < 19) |
117 | 0 | return(MagickFalse); |
118 | 0 | if (LocaleNCompare((const char *) magick,"id=MagickPixelCache",19) == 0) |
119 | 0 | return(MagickTrue); |
120 | 0 | return(MagickFalse); |
121 | 0 | } |
122 | | |
123 | | /* |
124 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
125 | | % % |
126 | | % % |
127 | | % % |
128 | | % R e a d C A C H E I m a g e % |
129 | | % % |
130 | | % % |
131 | | % % |
132 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
133 | | % |
134 | | % ReadMPCImage() reads an Magick Pixel Cache image file and returns |
135 | | % it. It allocates the memory necessary for the new Image structure and |
136 | | % returns a pointer to the new image. |
137 | | % |
138 | | % The format of the ReadMPCImage method is: |
139 | | % |
140 | | % Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception) |
141 | | % |
142 | | % Decompression code contributed by Kyle Shorter. |
143 | | % |
144 | | % A description of each parameter follows: |
145 | | % |
146 | | % o image_info: the image info. |
147 | | % |
148 | | % o exception: return any errors or warnings in this structure. |
149 | | % |
150 | | */ |
151 | | static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception) |
152 | 7.73k | { |
153 | 7.73k | char |
154 | 7.73k | cache_filename[MagickPathExtent], |
155 | 7.73k | id[MagickPathExtent], |
156 | 7.73k | keyword[MagickPathExtent], |
157 | 7.73k | *options; |
158 | | |
159 | 7.73k | GeometryInfo |
160 | 7.73k | geometry_info; |
161 | | |
162 | 7.73k | Image |
163 | 7.73k | *image; |
164 | | |
165 | 7.73k | int |
166 | 7.73k | c; |
167 | | |
168 | 7.73k | LinkedListInfo |
169 | 7.73k | *profiles; |
170 | | |
171 | 7.73k | MagickBooleanType |
172 | 7.73k | status; |
173 | | |
174 | 7.73k | MagickOffsetType |
175 | 7.73k | offset; |
176 | | |
177 | 7.73k | MagickStatusType |
178 | 7.73k | flags; |
179 | | |
180 | 7.73k | size_t |
181 | 7.73k | depth, |
182 | 7.73k | extent, |
183 | 7.73k | length; |
184 | | |
185 | 7.73k | ssize_t |
186 | 7.73k | count, |
187 | 7.73k | i; |
188 | | |
189 | 7.73k | StringInfo |
190 | 7.73k | *nonce; |
191 | | |
192 | 7.73k | unsigned int |
193 | 7.73k | signature; |
194 | | |
195 | | /* |
196 | | Open image file. |
197 | | */ |
198 | 7.73k | assert(image_info != (const ImageInfo *) NULL); |
199 | 7.73k | assert(image_info->signature == MagickCoreSignature); |
200 | 7.73k | assert(exception != (ExceptionInfo *) NULL); |
201 | 7.73k | assert(exception->signature == MagickCoreSignature); |
202 | 7.73k | if (IsEventLogging() != MagickFalse) |
203 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", |
204 | 0 | image_info->filename); |
205 | 7.73k | image=AcquireImage(image_info,exception); |
206 | 7.73k | status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); |
207 | 7.73k | if (status == MagickFalse) |
208 | 0 | { |
209 | 0 | image=DestroyImageList(image); |
210 | 0 | return((Image *) NULL); |
211 | 0 | } |
212 | 7.73k | (void) CopyMagickString(cache_filename,image->filename,MagickPathExtent-6); |
213 | 7.73k | AppendImageFormat("cache",cache_filename); |
214 | 7.73k | c=ReadBlobByte(image); |
215 | 7.73k | if (c == EOF) |
216 | 0 | { |
217 | 0 | image=DestroyImage(image); |
218 | 0 | return((Image *) NULL); |
219 | 0 | } |
220 | 7.73k | *id='\0'; |
221 | 7.73k | (void) memset(keyword,0,sizeof(keyword)); |
222 | 7.73k | offset=0; |
223 | 7.73k | do |
224 | 7.73k | { |
225 | | /* |
226 | | Decode image header; header terminates one character beyond a ':'. |
227 | | */ |
228 | 7.73k | SetGeometryInfo(&geometry_info); |
229 | 7.73k | profiles=(LinkedListInfo *) NULL; |
230 | 7.73k | length=MagickPathExtent; |
231 | 7.73k | options=AcquireString((char *) NULL); |
232 | 7.73k | nonce=StringToStringInfo(MagickPixelCacheNonce); |
233 | 7.73k | signature=GetMagickSignature(nonce); |
234 | 7.73k | nonce=DestroyStringInfo(nonce); |
235 | 7.73k | image->depth=8; |
236 | 7.73k | image->compression=NoCompression; |
237 | 225k | while ((isgraph((int) ((unsigned char) c)) != 0) && (c != (int) ':')) |
238 | 217k | { |
239 | 217k | char |
240 | 217k | *p; |
241 | | |
242 | 217k | if (c == (int) '{') |
243 | 7.33k | { |
244 | 7.33k | char |
245 | 7.33k | *comment; |
246 | | |
247 | | /* |
248 | | Read comment-- any text between { }. |
249 | | */ |
250 | 7.33k | length=MagickPathExtent; |
251 | 7.33k | comment=AcquireString((char *) NULL); |
252 | 57.6k | for (p=comment; comment != (char *) NULL; p++) |
253 | 57.6k | { |
254 | 57.6k | c=ReadBlobByte(image); |
255 | 57.6k | if (c == (int) '\\') |
256 | 935 | c=ReadBlobByte(image); |
257 | 56.7k | else |
258 | 56.7k | if ((c == EOF) || (c == (int) '}')) |
259 | 7.33k | break; |
260 | 50.3k | if ((size_t) (p-comment+1) >= length) |
261 | 4 | { |
262 | 4 | *p='\0'; |
263 | 4 | length<<=1; |
264 | 4 | comment=(char *) ResizeQuantumMemory(comment,length+ |
265 | 4 | MagickPathExtent,sizeof(*comment)); |
266 | 4 | if (comment == (char *) NULL) |
267 | 0 | break; |
268 | 4 | p=comment+strlen(comment); |
269 | 4 | } |
270 | 50.3k | *p=(char) c; |
271 | 50.3k | } |
272 | 7.33k | if (comment == (char *) NULL) |
273 | 0 | { |
274 | 0 | options=DestroyString(options); |
275 | 0 | ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); |
276 | 0 | } |
277 | 7.33k | *p='\0'; |
278 | 7.33k | (void) SetImageProperty(image,"comment",comment,exception); |
279 | 7.33k | comment=DestroyString(comment); |
280 | 7.33k | c=ReadBlobByte(image); |
281 | 7.33k | } |
282 | 210k | else |
283 | 210k | if (isalnum((int) ((unsigned char) c)) != MagickFalse) |
284 | 126k | { |
285 | | /* |
286 | | Get the keyword. |
287 | | */ |
288 | 126k | length=MagickPathExtent-1; |
289 | 126k | p=keyword; |
290 | 126k | do |
291 | 1.24M | { |
292 | 1.24M | if (c == (int) '=') |
293 | 123k | break; |
294 | 1.12M | if ((size_t) (p-keyword) < (MagickPathExtent-1)) |
295 | 1.12M | *p++=(char) c; |
296 | 1.12M | c=ReadBlobByte(image); |
297 | 1.12M | } while (c != EOF); |
298 | 0 | *p='\0'; |
299 | 126k | p=options; |
300 | 126k | while (isspace((int) ((unsigned char) c)) != 0) |
301 | 0 | c=ReadBlobByte(image); |
302 | 126k | if (c == (int) '=') |
303 | 123k | { |
304 | | /* |
305 | | Get the keyword value. |
306 | | */ |
307 | 123k | c=ReadBlobByte(image); |
308 | 1.00M | while ((c != (int) '{') && (c != (int) '}') && (c != EOF)) |
309 | 917k | { |
310 | 917k | if ((size_t) (p-options+1) >= length) |
311 | 16 | { |
312 | 16 | *p='\0'; |
313 | 16 | length<<=1; |
314 | 16 | options=(char *) ResizeQuantumMemory(options,length+ |
315 | 16 | MagickPathExtent,sizeof(*options)); |
316 | 16 | if (options == (char *) NULL) |
317 | 0 | break; |
318 | 16 | p=options+strlen(options); |
319 | 16 | } |
320 | 917k | *p++=(char) c; |
321 | 917k | c=ReadBlobByte(image); |
322 | 917k | if (c == '\\') |
323 | 4.71k | { |
324 | 4.71k | c=ReadBlobByte(image); |
325 | 4.71k | if ((c == (int) '{') || (c == (int) '}')) |
326 | 801 | { |
327 | 801 | *p++=(char) c; |
328 | 801 | c=ReadBlobByte(image); |
329 | 801 | } |
330 | 4.71k | } |
331 | 917k | if (*options != '{') |
332 | 917k | if (isspace((int) ((unsigned char) c)) != 0) |
333 | 40.6k | break; |
334 | 917k | } |
335 | 123k | if (options == (char *) NULL) |
336 | 0 | ThrowReaderException(ResourceLimitError, |
337 | 123k | "MemoryAllocationFailed"); |
338 | 123k | } |
339 | 126k | *p='\0'; |
340 | 126k | if (*options == '{') |
341 | 0 | (void) CopyMagickString(options,options+1,strlen(options)); |
342 | | /* |
343 | | Assign a value to the specified keyword. |
344 | | */ |
345 | 126k | switch (*keyword) |
346 | 126k | { |
347 | 1.93k | case 'a': |
348 | 5.62k | case 'A': |
349 | 5.62k | { |
350 | 5.62k | if (LocaleCompare(keyword,"alpha-trait") == 0) |
351 | 396 | { |
352 | 396 | ssize_t |
353 | 396 | alpha_trait; |
354 | | |
355 | 396 | alpha_trait=ParseCommandOption(MagickPixelTraitOptions, |
356 | 396 | MagickFalse,options); |
357 | 396 | if (alpha_trait < 0) |
358 | 194 | break; |
359 | 202 | image->alpha_trait=(PixelTrait) alpha_trait; |
360 | 202 | break; |
361 | 396 | } |
362 | 5.23k | (void) SetImageProperty(image,keyword,options,exception); |
363 | 5.23k | break; |
364 | 5.62k | } |
365 | 4.69k | case 'b': |
366 | 6.75k | case 'B': |
367 | 6.75k | { |
368 | 6.75k | if (LocaleCompare(keyword,"background-color") == 0) |
369 | 194 | { |
370 | 194 | (void) QueryColorCompliance(options,AllCompliance, |
371 | 194 | &image->background_color,exception); |
372 | 194 | break; |
373 | 194 | } |
374 | 6.56k | if (LocaleCompare(keyword,"blue-primary") == 0) |
375 | 389 | { |
376 | 389 | flags=ParseGeometry(options,&geometry_info); |
377 | 389 | image->chromaticity.blue_primary.x=geometry_info.rho; |
378 | 389 | image->chromaticity.blue_primary.y=geometry_info.sigma; |
379 | 389 | if ((flags & SigmaValue) == 0) |
380 | 194 | image->chromaticity.blue_primary.y= |
381 | 194 | image->chromaticity.blue_primary.x; |
382 | 389 | break; |
383 | 389 | } |
384 | 6.17k | if (LocaleCompare(keyword,"border-color") == 0) |
385 | 554 | { |
386 | 554 | (void) QueryColorCompliance(options,AllCompliance, |
387 | 554 | &image->border_color,exception); |
388 | 554 | break; |
389 | 554 | } |
390 | 5.62k | (void) SetImageProperty(image,keyword,options,exception); |
391 | 5.62k | break; |
392 | 6.17k | } |
393 | 6.17k | case 'c': |
394 | 7.49k | case 'C': |
395 | 7.49k | { |
396 | 7.49k | if (LocaleCompare(keyword,"channel-mask") == 0) |
397 | 0 | { |
398 | 0 | image->channel_mask=(ChannelType) |
399 | 0 | strtol(options,(char **) NULL,16); |
400 | 0 | break; |
401 | 0 | } |
402 | 7.49k | if (LocaleCompare(keyword,"class") == 0) |
403 | 557 | { |
404 | 557 | ssize_t |
405 | 557 | storage_class; |
406 | | |
407 | 557 | storage_class=ParseCommandOption(MagickClassOptions, |
408 | 557 | MagickFalse,options); |
409 | 557 | if (storage_class < 0) |
410 | 201 | break; |
411 | 356 | image->storage_class=(ClassType) storage_class; |
412 | 356 | break; |
413 | 557 | } |
414 | 6.94k | if (LocaleCompare(keyword,"colors") == 0) |
415 | 350 | { |
416 | 350 | image->colors=StringToUnsignedLong(options); |
417 | 350 | break; |
418 | 350 | } |
419 | 6.59k | if (LocaleCompare(keyword,"colorspace") == 0) |
420 | 395 | { |
421 | 395 | ssize_t |
422 | 395 | colorspace; |
423 | | |
424 | 395 | colorspace=ParseCommandOption(MagickColorspaceOptions, |
425 | 395 | MagickFalse,options); |
426 | 395 | if (colorspace < 0) |
427 | 194 | break; |
428 | 201 | image->colorspace=(ColorspaceType) colorspace; |
429 | 201 | break; |
430 | 395 | } |
431 | 6.19k | if (LocaleCompare(keyword,"compression") == 0) |
432 | 525 | { |
433 | 525 | ssize_t |
434 | 525 | compression; |
435 | | |
436 | 525 | compression=ParseCommandOption(MagickCompressOptions, |
437 | 525 | MagickFalse,options); |
438 | 525 | if (compression < 0) |
439 | 295 | break; |
440 | 230 | image->compression=(CompressionType) compression; |
441 | 230 | break; |
442 | 525 | } |
443 | 5.67k | if (LocaleCompare(keyword,"columns") == 0) |
444 | 2.13k | { |
445 | 2.13k | image->columns=StringToUnsignedLong(options); |
446 | 2.13k | break; |
447 | 2.13k | } |
448 | 3.53k | (void) SetImageProperty(image,keyword,options,exception); |
449 | 3.53k | break; |
450 | 5.67k | } |
451 | 2.16k | case 'd': |
452 | 13.3k | case 'D': |
453 | 13.3k | { |
454 | 13.3k | if (LocaleCompare(keyword,"delay") == 0) |
455 | 194 | { |
456 | 194 | image->delay=StringToUnsignedLong(options); |
457 | 194 | break; |
458 | 194 | } |
459 | 13.1k | if (LocaleCompare(keyword,"depth") == 0) |
460 | 330 | { |
461 | 330 | image->depth=StringToUnsignedLong(options); |
462 | 330 | break; |
463 | 330 | } |
464 | 12.8k | if (LocaleCompare(keyword,"dispose") == 0) |
465 | 490 | { |
466 | 490 | ssize_t |
467 | 490 | dispose; |
468 | | |
469 | 490 | dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse, |
470 | 490 | options); |
471 | 490 | if (dispose < 0) |
472 | 295 | break; |
473 | 195 | image->dispose=(DisposeType) dispose; |
474 | 195 | break; |
475 | 490 | } |
476 | 12.3k | (void) SetImageProperty(image,keyword,options,exception); |
477 | 12.3k | break; |
478 | 12.8k | } |
479 | 1.99k | case 'e': |
480 | 2.77k | case 'E': |
481 | 2.77k | { |
482 | 2.77k | if (LocaleCompare(keyword,"endian") == 0) |
483 | 424 | { |
484 | 424 | ssize_t |
485 | 424 | endian; |
486 | | |
487 | 424 | endian=ParseCommandOption(MagickEndianOptions,MagickFalse, |
488 | 424 | options); |
489 | 424 | if (endian < 0) |
490 | 229 | break; |
491 | 195 | image->endian=(EndianType) endian; |
492 | 195 | break; |
493 | 424 | } |
494 | 2.35k | if (LocaleCompare(keyword,"error") == 0) |
495 | 195 | { |
496 | 195 | image->error.mean_error_per_pixel=StringToDouble(options, |
497 | 195 | (char **) NULL); |
498 | 195 | break; |
499 | 195 | } |
500 | 2.15k | (void) SetImageProperty(image,keyword,options,exception); |
501 | 2.15k | break; |
502 | 2.35k | } |
503 | 4.24k | case 'g': |
504 | 5.19k | case 'G': |
505 | 5.19k | { |
506 | 5.19k | if (LocaleCompare(keyword,"gamma") == 0) |
507 | 194 | { |
508 | 194 | image->gamma=StringToDouble(options,(char **) NULL); |
509 | 194 | break; |
510 | 194 | } |
511 | 4.99k | if (LocaleCompare(keyword,"green-primary") == 0) |
512 | 1.84k | { |
513 | 1.84k | flags=ParseGeometry(options,&geometry_info); |
514 | 1.84k | image->chromaticity.green_primary.x=geometry_info.rho; |
515 | 1.84k | image->chromaticity.green_primary.y=geometry_info.sigma; |
516 | 1.84k | if ((flags & SigmaValue) == 0) |
517 | 1.34k | image->chromaticity.green_primary.y= |
518 | 1.34k | image->chromaticity.green_primary.x; |
519 | 1.84k | break; |
520 | 1.84k | } |
521 | 3.15k | (void) SetImageProperty(image,keyword,options,exception); |
522 | 3.15k | break; |
523 | 4.99k | } |
524 | 5.37k | case 'i': |
525 | 7.77k | case 'I': |
526 | 7.77k | { |
527 | 7.77k | if (LocaleCompare(keyword,"id") == 0) |
528 | 3.05k | { |
529 | 3.05k | (void) CopyMagickString(id,options,MagickPathExtent); |
530 | 3.05k | break; |
531 | 3.05k | } |
532 | 4.72k | if (LocaleCompare(keyword,"iterations") == 0) |
533 | 194 | { |
534 | 194 | image->iterations=StringToUnsignedLong(options); |
535 | 194 | break; |
536 | 194 | } |
537 | 4.52k | (void) SetImageProperty(image,keyword,options,exception); |
538 | 4.52k | break; |
539 | 4.72k | } |
540 | 25.1k | case 'm': |
541 | 27.6k | case 'M': |
542 | 27.6k | { |
543 | 27.6k | if (LocaleCompare(keyword,"magick-signature") == 0) |
544 | 232 | { |
545 | 232 | signature=(unsigned int) StringToUnsignedLong(options); |
546 | 232 | break; |
547 | 232 | } |
548 | 27.4k | if (LocaleCompare(keyword,"mattecolor") == 0) |
549 | 20.6k | { |
550 | 20.6k | (void) QueryColorCompliance(options,AllCompliance, |
551 | 20.6k | &image->matte_color,exception); |
552 | 20.6k | break; |
553 | 20.6k | } |
554 | 6.81k | if (LocaleCompare(keyword,"maximum-error") == 0) |
555 | 198 | { |
556 | 198 | image->error.normalized_maximum_error=StringToDouble( |
557 | 198 | options,(char **) NULL); |
558 | 198 | break; |
559 | 198 | } |
560 | 6.61k | if (LocaleCompare(keyword,"mean-error") == 0) |
561 | 194 | { |
562 | 194 | image->error.normalized_mean_error=StringToDouble(options, |
563 | 194 | (char **) NULL); |
564 | 194 | break; |
565 | 194 | } |
566 | 6.42k | if (LocaleCompare(keyword,"montage") == 0) |
567 | 1.24k | { |
568 | 1.24k | (void) CloneString(&image->montage,options); |
569 | 1.24k | break; |
570 | 1.24k | } |
571 | 5.17k | (void) SetImageProperty(image,keyword,options,exception); |
572 | 5.17k | break; |
573 | 6.42k | } |
574 | 1.16k | case 'n': |
575 | 1.62k | case 'N': |
576 | 1.62k | { |
577 | 1.62k | if (LocaleCompare(keyword,"number-channels") == 0) |
578 | 288 | { |
579 | 288 | image->number_channels=StringToUnsignedLong(options); |
580 | 288 | break; |
581 | 288 | } |
582 | 1.33k | if (LocaleCompare(keyword,"number-meta-channels") == 0) |
583 | 445 | { |
584 | 445 | image->number_meta_channels=StringToUnsignedLong(options); |
585 | 445 | break; |
586 | 445 | } |
587 | 894 | break; |
588 | 1.33k | } |
589 | 1.71k | case 'o': |
590 | 2.81k | case 'O': |
591 | 2.81k | { |
592 | 2.81k | if (LocaleCompare(keyword,"orientation") == 0) |
593 | 388 | { |
594 | 388 | ssize_t |
595 | 388 | orientation; |
596 | | |
597 | 388 | orientation=ParseCommandOption(MagickOrientationOptions, |
598 | 388 | MagickFalse,options); |
599 | 388 | if (orientation < 0) |
600 | 194 | break; |
601 | 194 | image->orientation=(OrientationType) orientation; |
602 | 194 | break; |
603 | 388 | } |
604 | 2.42k | (void) SetImageProperty(image,keyword,options,exception); |
605 | 2.42k | break; |
606 | 2.81k | } |
607 | 11.3k | case 'p': |
608 | 14.2k | case 'P': |
609 | 14.2k | { |
610 | 14.2k | if (LocaleCompare(keyword,"page") == 0) |
611 | 2.80k | { |
612 | 2.80k | char |
613 | 2.80k | *geometry; |
614 | | |
615 | 2.80k | geometry=GetPageGeometry(options); |
616 | 2.80k | (void) ParseAbsoluteGeometry(geometry,&image->page); |
617 | 2.80k | geometry=DestroyString(geometry); |
618 | 2.80k | break; |
619 | 2.80k | } |
620 | 11.4k | if (LocaleCompare(keyword,"pixel-intensity") == 0) |
621 | 388 | { |
622 | 388 | ssize_t |
623 | 388 | intensity; |
624 | | |
625 | 388 | intensity=ParseCommandOption(MagickPixelIntensityOptions, |
626 | 388 | MagickFalse,options); |
627 | 388 | if (intensity < 0) |
628 | 194 | break; |
629 | 194 | image->intensity=(PixelIntensityMethod) intensity; |
630 | 194 | break; |
631 | 388 | } |
632 | 11.0k | if (LocaleCompare(keyword,"profile") == 0) |
633 | 7.40k | { |
634 | 7.40k | if (profiles == (LinkedListInfo *) NULL) |
635 | 665 | profiles=NewLinkedList(0); |
636 | 7.40k | (void) AppendValueToLinkedList(profiles, |
637 | 7.40k | AcquireString(options)); |
638 | 7.40k | break; |
639 | 7.40k | } |
640 | 3.60k | (void) SetImageProperty(image,keyword,options,exception); |
641 | 3.60k | break; |
642 | 11.0k | } |
643 | 670 | case 'q': |
644 | 3.64k | case 'Q': |
645 | 3.64k | { |
646 | 3.64k | if (LocaleCompare(keyword,"quality") == 0) |
647 | 194 | { |
648 | 194 | image->quality=StringToUnsignedLong(options); |
649 | 194 | break; |
650 | 194 | } |
651 | 3.44k | (void) SetImageProperty(image,keyword,options,exception); |
652 | 3.44k | break; |
653 | 3.64k | } |
654 | 4.25k | case 'r': |
655 | 5.30k | case 'R': |
656 | 5.30k | { |
657 | 5.30k | if (LocaleCompare(keyword,"red-primary") == 0) |
658 | 447 | { |
659 | 447 | flags=ParseGeometry(options,&geometry_info); |
660 | 447 | image->chromaticity.red_primary.x=geometry_info.rho; |
661 | 447 | if ((flags & SigmaValue) != 0) |
662 | 205 | image->chromaticity.red_primary.y=geometry_info.sigma; |
663 | 447 | break; |
664 | 447 | } |
665 | 4.85k | if (LocaleCompare(keyword,"rendering-intent") == 0) |
666 | 397 | { |
667 | 397 | ssize_t |
668 | 397 | rendering_intent; |
669 | | |
670 | 397 | rendering_intent=ParseCommandOption(MagickIntentOptions, |
671 | 397 | MagickFalse,options); |
672 | 397 | if (rendering_intent < 0) |
673 | 197 | break; |
674 | 200 | image->rendering_intent=(RenderingIntent) rendering_intent; |
675 | 200 | break; |
676 | 397 | } |
677 | 4.46k | if (LocaleCompare(keyword,"resolution") == 0) |
678 | 388 | { |
679 | 388 | flags=ParseGeometry(options,&geometry_info); |
680 | 388 | image->resolution.x=geometry_info.rho; |
681 | 388 | image->resolution.y=geometry_info.sigma; |
682 | 388 | if ((flags & SigmaValue) == 0) |
683 | 194 | image->resolution.y=image->resolution.x; |
684 | 388 | break; |
685 | 388 | } |
686 | 4.07k | if (LocaleCompare(keyword,"rows") == 0) |
687 | 1.99k | { |
688 | 1.99k | image->rows=StringToUnsignedLong(options); |
689 | 1.99k | break; |
690 | 1.99k | } |
691 | 2.07k | (void) SetImageProperty(image,keyword,options,exception); |
692 | 2.07k | break; |
693 | 4.07k | } |
694 | 2.02k | case 's': |
695 | 2.73k | case 'S': |
696 | 2.73k | { |
697 | 2.73k | if (LocaleCompare(keyword,"scene") == 0) |
698 | 194 | { |
699 | 194 | image->scene=StringToUnsignedLong(options); |
700 | 194 | break; |
701 | 194 | } |
702 | 2.53k | (void) SetImageProperty(image,keyword,options,exception); |
703 | 2.53k | break; |
704 | 2.73k | } |
705 | 7.04k | case 't': |
706 | 7.66k | case 'T': |
707 | 7.66k | { |
708 | 7.66k | if (LocaleCompare(keyword,"ticks-per-second") == 0) |
709 | 194 | { |
710 | 194 | image->ticks_per_second=(ssize_t) StringToLong(options); |
711 | 194 | break; |
712 | 194 | } |
713 | 7.46k | if (LocaleCompare(keyword,"tile-offset") == 0) |
714 | 1.78k | { |
715 | 1.78k | char |
716 | 1.78k | *geometry; |
717 | | |
718 | 1.78k | geometry=GetPageGeometry(options); |
719 | 1.78k | (void) ParseAbsoluteGeometry(geometry,&image->tile_offset); |
720 | 1.78k | geometry=DestroyString(geometry); |
721 | 1.78k | } |
722 | 7.46k | if (LocaleCompare(keyword,"type") == 0) |
723 | 4.11k | { |
724 | 4.11k | ssize_t |
725 | 4.11k | type; |
726 | | |
727 | 4.11k | type=ParseCommandOption(MagickTypeOptions,MagickFalse, |
728 | 4.11k | options); |
729 | 4.11k | if (type < 0) |
730 | 3.71k | break; |
731 | 398 | image->type=(ImageType) type; |
732 | 398 | break; |
733 | 4.11k | } |
734 | 3.35k | (void) SetImageProperty(image,keyword,options,exception); |
735 | 3.35k | break; |
736 | 7.46k | } |
737 | 2.54k | case 'u': |
738 | 3.10k | case 'U': |
739 | 3.10k | { |
740 | 3.10k | if (LocaleCompare(keyword,"units") == 0) |
741 | 1.71k | { |
742 | 1.71k | ssize_t |
743 | 1.71k | units; |
744 | | |
745 | 1.71k | units=ParseCommandOption(MagickResolutionOptions, |
746 | 1.71k | MagickFalse,options); |
747 | 1.71k | if (units < 0) |
748 | 200 | break; |
749 | 1.51k | image->units=(ResolutionType) units; |
750 | 1.51k | break; |
751 | 1.71k | } |
752 | 1.39k | (void) SetImageProperty(image,keyword,options,exception); |
753 | 1.39k | break; |
754 | 3.10k | } |
755 | 1.23k | case 'w': |
756 | 2.03k | case 'W': |
757 | 2.03k | { |
758 | 2.03k | if (LocaleCompare(keyword,"white-point") == 0) |
759 | 388 | { |
760 | 388 | flags=ParseGeometry(options,&geometry_info); |
761 | 388 | image->chromaticity.white_point.x=geometry_info.rho; |
762 | 388 | image->chromaticity.white_point.y=geometry_info.sigma; |
763 | 388 | if ((flags & SigmaValue) == 0) |
764 | 194 | image->chromaticity.white_point.y= |
765 | 194 | image->chromaticity.white_point.x; |
766 | 388 | break; |
767 | 388 | } |
768 | 1.65k | (void) SetImageProperty(image,keyword,options,exception); |
769 | 1.65k | break; |
770 | 2.03k | } |
771 | 6.47k | default: |
772 | 6.47k | { |
773 | 6.47k | (void) SetImageProperty(image,keyword,options,exception); |
774 | 6.47k | break; |
775 | 2.03k | } |
776 | 126k | } |
777 | 126k | } |
778 | 84.1k | else |
779 | 84.1k | c=ReadBlobByte(image); |
780 | 265k | while (isspace((int) ((unsigned char) c)) != 0) |
781 | 47.8k | c=ReadBlobByte(image); |
782 | 217k | } |
783 | 7.73k | options=DestroyString(options); |
784 | 7.73k | (void) ReadBlobByte(image); |
785 | | /* |
786 | | Verify that required image information is defined. |
787 | | */ |
788 | 7.73k | if ((LocaleCompare(id,"MagickPixelCache") != 0) || |
789 | 7.73k | (image->storage_class == UndefinedClass) || |
790 | 7.73k | (image->compression == UndefinedCompression) || |
791 | 7.73k | (image->columns == 0) || (image->rows == 0) || |
792 | 7.73k | (image->number_channels > MaxPixelChannels) || |
793 | 7.73k | (image->number_meta_channels > (size_t) (MaxPixelChannels-MetaPixelChannels)) || |
794 | 7.73k | ((image->number_channels+image->number_meta_channels) >= MaxPixelChannels) || |
795 | 7.73k | (image->depth == 0) || (image->depth > 64)) |
796 | 6.47k | { |
797 | 6.47k | if (profiles != (LinkedListInfo *) NULL) |
798 | 33 | profiles=DestroyLinkedList(profiles,RelinquishMagickMemory); |
799 | 6.47k | ThrowReaderException(CorruptImageError,"ImproperImageHeader"); |
800 | 0 | } |
801 | 1.26k | nonce=StringToStringInfo(MagickPixelCacheNonce); |
802 | 1.26k | if (signature != GetMagickSignature(nonce)) |
803 | 38 | { |
804 | 38 | nonce=DestroyStringInfo(nonce); |
805 | 38 | if (profiles != (LinkedListInfo *) NULL) |
806 | 1 | profiles=DestroyLinkedList(profiles,RelinquishMagickMemory); |
807 | 38 | ThrowReaderException(CacheError,"IncompatibleAPI"); |
808 | 0 | } |
809 | 1.22k | nonce=DestroyStringInfo(nonce); |
810 | 1.22k | if (image->montage != (char *) NULL) |
811 | 22 | { |
812 | 22 | char |
813 | 22 | *p; |
814 | | |
815 | | /* |
816 | | Image directory. |
817 | | */ |
818 | 22 | extent=MagickPathExtent; |
819 | 22 | image->directory=AcquireString((char *) NULL); |
820 | 22 | p=image->directory; |
821 | 22 | length=0; |
822 | 22 | do |
823 | 12.9k | { |
824 | 12.9k | *p='\0'; |
825 | 12.9k | if ((length+MagickPathExtent) >= extent) |
826 | 23 | { |
827 | | /* |
828 | | Allocate more memory for the image directory. |
829 | | */ |
830 | 23 | extent<<=1; |
831 | 23 | image->directory=(char *) ResizeQuantumMemory(image->directory, |
832 | 23 | extent+MagickPathExtent,sizeof(*image->directory)); |
833 | 23 | if (image->directory == (char *) NULL) |
834 | 0 | { |
835 | 0 | if (profiles != (LinkedListInfo *) NULL) |
836 | 0 | profiles=DestroyLinkedList(profiles,RelinquishMagickMemory); |
837 | 0 | ThrowReaderException(CorruptImageError, |
838 | 0 | "UnableToReadImageData"); |
839 | 0 | } |
840 | 23 | p=image->directory+length; |
841 | 23 | } |
842 | 12.9k | c=ReadBlobByte(image); |
843 | 12.9k | if (c == EOF) |
844 | 16 | break; |
845 | 12.9k | *p++=(char) c; |
846 | 12.9k | length++; |
847 | 12.9k | } while (c != (int) '\0'); |
848 | 22 | } |
849 | 1.22k | if (profiles != (LinkedListInfo *) NULL) |
850 | 631 | { |
851 | 631 | const char |
852 | 631 | *name; |
853 | | |
854 | 631 | StringInfo |
855 | 631 | *profile; |
856 | | |
857 | | /* |
858 | | Read image profile blobs. |
859 | | */ |
860 | 631 | ResetLinkedListIterator(profiles); |
861 | 631 | name=(const char *) GetNextValueInLinkedList(profiles); |
862 | 7.43k | while (name != (const char *) NULL) |
863 | 6.87k | { |
864 | 6.87k | length=ReadBlobMSBLong(image); |
865 | 6.87k | if ((MagickSizeType) length > GetBlobSize(image)) |
866 | 32 | break; |
867 | 6.84k | profile=AcquireProfileStringInfo(name,length,exception); |
868 | 6.84k | if (profile == (StringInfo *) NULL) |
869 | 0 | { |
870 | 0 | count=(ssize_t) SeekBlob(image,(MagickOffsetType) length,SEEK_CUR); |
871 | 0 | if (count != (ssize_t) length) |
872 | 0 | break; |
873 | 0 | } |
874 | 6.84k | else |
875 | 6.84k | { |
876 | 6.84k | count=ReadBlob(image,length,GetStringInfoDatum(profile)); |
877 | 6.84k | if (count != (ssize_t) length) |
878 | 40 | { |
879 | 40 | profile=DestroyStringInfo(profile); |
880 | 40 | break; |
881 | 40 | } |
882 | 6.80k | status=SetImageProfilePrivate(image,profile,exception); |
883 | 6.80k | } |
884 | 6.80k | if (status == MagickFalse) |
885 | 0 | break; |
886 | 6.80k | name=(const char *) GetNextValueInLinkedList(profiles); |
887 | 6.80k | } |
888 | 631 | profiles=DestroyLinkedList(profiles,RelinquishMagickMemory); |
889 | 631 | } |
890 | 1.22k | depth=GetImageQuantumDepth(image,MagickFalse); |
891 | 1.22k | if (image->storage_class == PseudoClass) |
892 | 160 | { |
893 | 160 | const unsigned char |
894 | 160 | *p; |
895 | | |
896 | 160 | size_t |
897 | 160 | packet_size; |
898 | | |
899 | 160 | unsigned char |
900 | 160 | *colormap; |
901 | | |
902 | | /* |
903 | | Create image colormap. |
904 | | */ |
905 | 160 | packet_size=(size_t) (3UL*depth/8UL); |
906 | 160 | if ((MagickSizeType) (packet_size*image->colors) > GetBlobSize(image)) |
907 | 102 | ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile"); |
908 | 58 | image->colormap=(PixelInfo *) AcquireQuantumMemory(image->colors+1, |
909 | 58 | sizeof(*image->colormap)); |
910 | 58 | if (image->colormap == (PixelInfo *) NULL) |
911 | 54 | ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); |
912 | 54 | if (image->colors != 0) |
913 | 49 | { |
914 | | /* |
915 | | Read image colormap from file. |
916 | | */ |
917 | 49 | colormap=(unsigned char *) AcquireQuantumMemory(image->colors, |
918 | 49 | packet_size*sizeof(*colormap)); |
919 | 49 | if (colormap == (unsigned char *) NULL) |
920 | 49 | ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); |
921 | 49 | count=ReadBlob(image,packet_size*image->colors,colormap); |
922 | 49 | if (count != (ssize_t) (packet_size*image->colors)) |
923 | 14 | { |
924 | 14 | colormap=(unsigned char *) RelinquishMagickMemory(colormap); |
925 | 14 | ThrowReaderException(CorruptImageError, |
926 | 14 | "InsufficientImageDataInFile"); |
927 | 0 | } |
928 | 35 | p=colormap; |
929 | 35 | switch (depth) |
930 | 35 | { |
931 | 1 | default: |
932 | 1 | colormap=(unsigned char *) RelinquishMagickMemory(colormap); |
933 | 1 | ThrowReaderException(CorruptImageError, |
934 | 0 | "ImageDepthNotSupported"); |
935 | 13 | case 8: |
936 | 13 | { |
937 | 13 | unsigned char |
938 | 13 | pixel; |
939 | | |
940 | 4.05k | for (i=0; i < (ssize_t) image->colors; i++) |
941 | 4.03k | { |
942 | 4.03k | p=PushCharPixel(p,&pixel); |
943 | 4.03k | image->colormap[i].red=(MagickRealType) |
944 | 4.03k | ScaleCharToQuantum(pixel); |
945 | 4.03k | p=PushCharPixel(p,&pixel); |
946 | 4.03k | image->colormap[i].green=(MagickRealType) |
947 | 4.03k | ScaleCharToQuantum(pixel); |
948 | 4.03k | p=PushCharPixel(p,&pixel); |
949 | 4.03k | image->colormap[i].blue=(MagickRealType) |
950 | 4.03k | ScaleCharToQuantum(pixel); |
951 | 4.03k | } |
952 | 13 | break; |
953 | 0 | } |
954 | 12 | case 16: |
955 | 12 | { |
956 | 12 | unsigned short |
957 | 12 | pixel; |
958 | | |
959 | 2.38k | for (i=0; i < (ssize_t) image->colors; i++) |
960 | 2.37k | { |
961 | 2.37k | p=PushShortPixel(MSBEndian,p,&pixel); |
962 | 2.37k | image->colormap[i].red=(MagickRealType) |
963 | 2.37k | ScaleShortToQuantum(pixel); |
964 | 2.37k | p=PushShortPixel(MSBEndian,p,&pixel); |
965 | 2.37k | image->colormap[i].green=(MagickRealType) |
966 | 2.37k | ScaleShortToQuantum(pixel); |
967 | 2.37k | p=PushShortPixel(MSBEndian,p,&pixel); |
968 | 2.37k | image->colormap[i].blue=(MagickRealType) |
969 | 2.37k | ScaleShortToQuantum(pixel); |
970 | 2.37k | } |
971 | 12 | break; |
972 | 0 | } |
973 | 9 | case 32: |
974 | 9 | { |
975 | 9 | unsigned int |
976 | 9 | pixel; |
977 | | |
978 | 212 | for (i=0; i < (ssize_t) image->colors; i++) |
979 | 203 | { |
980 | 203 | p=PushLongPixel(MSBEndian,p,&pixel); |
981 | 203 | image->colormap[i].red=(MagickRealType) |
982 | 203 | ScaleLongToQuantum(pixel); |
983 | 203 | p=PushLongPixel(MSBEndian,p,&pixel); |
984 | 203 | image->colormap[i].green=(MagickRealType) |
985 | 203 | ScaleLongToQuantum(pixel); |
986 | 203 | p=PushLongPixel(MSBEndian,p,&pixel); |
987 | 203 | image->colormap[i].blue=(MagickRealType) |
988 | 203 | ScaleLongToQuantum(pixel); |
989 | 203 | } |
990 | 9 | break; |
991 | 0 | } |
992 | 35 | } |
993 | 34 | colormap=(unsigned char *) RelinquishMagickMemory(colormap); |
994 | 34 | } |
995 | 54 | } |
996 | 1.10k | if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) |
997 | 0 | if (image->scene >= (image_info->scene+image_info->number_scenes-1)) |
998 | 0 | break; |
999 | 1.10k | if ((AcquireMagickResource(WidthResource,image->columns) == MagickFalse) || |
1000 | 1.10k | (AcquireMagickResource(HeightResource,image->rows) == MagickFalse)) |
1001 | 900 | ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit"); |
1002 | | /* |
1003 | | Attach persistent pixel cache. |
1004 | | */ |
1005 | 900 | status=PersistPixelCache(image,cache_filename,MagickTrue,&offset,exception); |
1006 | 900 | if (status == MagickFalse) |
1007 | 900 | { |
1008 | 900 | status=SetImageExtent(image,image->columns,image->rows,exception); |
1009 | 900 | ThrowReaderException(CacheError,"UnableToPersistPixelCache"); |
1010 | 0 | } |
1011 | 0 | if (EOFBlob(image) != MagickFalse) |
1012 | 0 | { |
1013 | 0 | ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", |
1014 | 0 | image->filename); |
1015 | 0 | break; |
1016 | 0 | } |
1017 | | /* |
1018 | | Proceed to next image. |
1019 | | */ |
1020 | 0 | do |
1021 | 0 | { |
1022 | 0 | c=ReadBlobByte(image); |
1023 | 0 | } while ((isgraph((int) ((unsigned char) c)) == 0) && (c != EOF)); |
1024 | 0 | if ((c != EOF) && ((c == 'i') || (c == 'I'))) |
1025 | 0 | { |
1026 | | /* |
1027 | | Allocate next image structure. |
1028 | | */ |
1029 | 0 | AcquireNextImage(image_info,image,exception); |
1030 | 0 | if (GetNextImageInList(image) == (Image *) NULL) |
1031 | 0 | { |
1032 | 0 | status=MagickFalse; |
1033 | 0 | break; |
1034 | 0 | } |
1035 | 0 | image=SyncNextImageInList(image); |
1036 | 0 | status=SetImageProgress(image,LoadImagesTag,TellBlob(image), |
1037 | 0 | GetBlobSize(image)); |
1038 | 0 | if (status == MagickFalse) |
1039 | 0 | break; |
1040 | 0 | } |
1041 | 0 | } while ((c != EOF) && ((c == 'i') || (c == 'I'))); |
1042 | 0 | if (CloseBlob(image) == MagickFalse) |
1043 | 0 | status=MagickFalse; |
1044 | 0 | if (status == MagickFalse) |
1045 | 0 | return(DestroyImageList(image)); |
1046 | 0 | return(GetFirstImageInList(image)); |
1047 | 0 | } |
1048 | | |
1049 | | /* |
1050 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
1051 | | % % |
1052 | | % % |
1053 | | % % |
1054 | | % R e g i s t e r M P C I m a g e % |
1055 | | % % |
1056 | | % % |
1057 | | % % |
1058 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
1059 | | % |
1060 | | % RegisterMPCImage() adds properties for the Cache image format to |
1061 | | % the list of supported formats. The properties include the image format |
1062 | | % tag, a method to read and/or write the format, whether the format |
1063 | | % supports the saving of more than one frame to the same file or blob, |
1064 | | % whether the format supports native in-memory I/O, and a brief |
1065 | | % description of the format. |
1066 | | % |
1067 | | % The format of the RegisterMPCImage method is: |
1068 | | % |
1069 | | % size_t RegisterMPCImage(void) |
1070 | | % |
1071 | | */ |
1072 | | ModuleExport size_t RegisterMPCImage(void) |
1073 | 10 | { |
1074 | 10 | MagickInfo |
1075 | 10 | *entry; |
1076 | | |
1077 | 10 | entry=AcquireMagickInfo("MPC","CACHE","Magick Pixel Cache image format"); |
1078 | 10 | entry->flags|=CoderStealthFlag; |
1079 | 10 | (void) RegisterMagickInfo(entry); |
1080 | 10 | entry=AcquireMagickInfo("MPC","MPC","Magick Pixel Cache image format"); |
1081 | 10 | entry->decoder=(DecodeImageHandler *) ReadMPCImage; |
1082 | 10 | entry->encoder=(EncodeImageHandler *) WriteMPCImage; |
1083 | 10 | entry->magick=(IsImageFormatHandler *) IsMPC; |
1084 | 10 | entry->flags|=CoderDecoderSeekableStreamFlag; |
1085 | 10 | (void) RegisterMagickInfo(entry); |
1086 | 10 | return(MagickImageCoderSignature); |
1087 | 10 | } |
1088 | | |
1089 | | /* |
1090 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
1091 | | % % |
1092 | | % % |
1093 | | % % |
1094 | | % U n r e g i s t e r M P C I m a g e % |
1095 | | % % |
1096 | | % % |
1097 | | % % |
1098 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
1099 | | % |
1100 | | % UnregisterMPCImage() removes format registrations made by the |
1101 | | % MPC module from the list of supported formats. |
1102 | | % |
1103 | | % The format of the UnregisterMPCImage method is: |
1104 | | % |
1105 | | % UnregisterMPCImage(void) |
1106 | | % |
1107 | | */ |
1108 | | ModuleExport void UnregisterMPCImage(void) |
1109 | 0 | { |
1110 | 0 | (void) UnregisterMagickInfo("CACHE"); |
1111 | 0 | (void) UnregisterMagickInfo("MPC"); |
1112 | 0 | } |
1113 | | |
1114 | | /* |
1115 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
1116 | | % % |
1117 | | % % |
1118 | | % % |
1119 | | % W r i t e M P C I m a g e % |
1120 | | % % |
1121 | | % % |
1122 | | % % |
1123 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
1124 | | % |
1125 | | % WriteMPCImage() writes an Magick Pixel Cache image to a file. |
1126 | | % |
1127 | | % The format of the WriteMPCImage method is: |
1128 | | % |
1129 | | % MagickBooleanType WriteMPCImage(const ImageInfo *image_info, |
1130 | | % Image *image,ExceptionInfo *exception) |
1131 | | % |
1132 | | % A description of each parameter follows: |
1133 | | % |
1134 | | % o image_info: the image info. |
1135 | | % |
1136 | | % o image: the image. |
1137 | | % |
1138 | | % o exception: return any errors or warnings in this structure. |
1139 | | % |
1140 | | */ |
1141 | | static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image, |
1142 | | ExceptionInfo *exception) |
1143 | 0 | { |
1144 | 0 | char |
1145 | 0 | buffer[MagickPathExtent], |
1146 | 0 | cache_filename[MagickPathExtent]; |
1147 | |
|
1148 | 0 | const char |
1149 | 0 | *property, |
1150 | 0 | *value; |
1151 | |
|
1152 | 0 | MagickBooleanType |
1153 | 0 | status; |
1154 | |
|
1155 | 0 | MagickOffsetType |
1156 | 0 | offset, |
1157 | 0 | scene; |
1158 | |
|
1159 | 0 | size_t |
1160 | 0 | depth, |
1161 | 0 | number_scenes; |
1162 | |
|
1163 | 0 | ssize_t |
1164 | 0 | i; |
1165 | | |
1166 | | /* |
1167 | | Open persistent cache. |
1168 | | */ |
1169 | 0 | assert(image_info != (const ImageInfo *) NULL); |
1170 | 0 | assert(image_info->signature == MagickCoreSignature); |
1171 | 0 | assert(image != (Image *) NULL); |
1172 | 0 | assert(image->signature == MagickCoreSignature); |
1173 | 0 | assert(exception != (ExceptionInfo *) NULL); |
1174 | 0 | assert(exception->signature == MagickCoreSignature); |
1175 | 0 | if (IsEventLogging() != MagickFalse) |
1176 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); |
1177 | 0 | status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); |
1178 | 0 | if (status == MagickFalse) |
1179 | 0 | return(status); |
1180 | 0 | (void) CopyMagickString(cache_filename,image->filename,MagickPathExtent-6); |
1181 | 0 | AppendImageFormat("cache",cache_filename); |
1182 | 0 | scene=0; |
1183 | 0 | offset=0; |
1184 | 0 | number_scenes=GetImageListLength(image); |
1185 | 0 | do |
1186 | 0 | { |
1187 | 0 | StringInfo |
1188 | 0 | *nonce; |
1189 | | |
1190 | | /* |
1191 | | Write cache meta-information. |
1192 | | |
1193 | | SetImageStorageClass() required to sync pixel cache. |
1194 | | */ |
1195 | 0 | (void) SetImageStorageClass(image,image->storage_class,exception); |
1196 | 0 | depth=GetImageQuantumDepth(image,MagickTrue); |
1197 | 0 | if ((image->storage_class == PseudoClass) && |
1198 | 0 | (image->colors > (size_t) (GetQuantumRange(image->depth)+1))) |
1199 | 0 | (void) SetImageStorageClass(image,DirectClass,exception); |
1200 | 0 | (void) WriteBlobString(image,"id=MagickPixelCache\n"); |
1201 | 0 | nonce=StringToStringInfo(MagickPixelCacheNonce); |
1202 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"magick-signature=%u\n", |
1203 | 0 | GetMagickSignature(nonce)); |
1204 | 0 | nonce=DestroyStringInfo(nonce); |
1205 | 0 | (void) WriteBlobString(image,buffer); |
1206 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1207 | 0 | "class=%s colors=%.20g alpha-trait=%s\n",CommandOptionToMnemonic( |
1208 | 0 | MagickClassOptions,image->storage_class),(double) image->colors, |
1209 | 0 | CommandOptionToMnemonic(MagickPixelTraitOptions,(ssize_t) |
1210 | 0 | image->alpha_trait)); |
1211 | 0 | (void) WriteBlobString(image,buffer); |
1212 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"number-channels=%.20g " |
1213 | 0 | "number-meta-channels=%.20g channel-mask=0x%016llx\n", |
1214 | 0 | (double) image->number_channels,(double) image->number_meta_channels, |
1215 | 0 | (MagickOffsetType) image->channel_mask); |
1216 | 0 | (void) WriteBlobString(image,buffer); |
1217 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1218 | 0 | "columns=%.20g rows=%.20g depth=%.20g\n",(double) image->columns, |
1219 | 0 | (double) image->rows,(double) image->depth); |
1220 | 0 | (void) WriteBlobString(image,buffer); |
1221 | 0 | if (image->type != UndefinedType) |
1222 | 0 | { |
1223 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"type=%s\n", |
1224 | 0 | CommandOptionToMnemonic(MagickTypeOptions,image->type)); |
1225 | 0 | (void) WriteBlobString(image,buffer); |
1226 | 0 | } |
1227 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"colorspace=%s\n", |
1228 | 0 | CommandOptionToMnemonic(MagickColorspaceOptions,image->colorspace)); |
1229 | 0 | (void) WriteBlobString(image,buffer); |
1230 | 0 | if (image->intensity != UndefinedPixelIntensityMethod) |
1231 | 0 | { |
1232 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1233 | 0 | "pixel-intensity=%s\n",CommandOptionToMnemonic( |
1234 | 0 | MagickPixelIntensityOptions,image->intensity)); |
1235 | 0 | (void) WriteBlobString(image,buffer); |
1236 | 0 | } |
1237 | 0 | if (image->endian != UndefinedEndian) |
1238 | 0 | { |
1239 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"endian=%s\n", |
1240 | 0 | CommandOptionToMnemonic(MagickEndianOptions,image->endian)); |
1241 | 0 | (void) WriteBlobString(image,buffer); |
1242 | 0 | } |
1243 | 0 | if (image->compression != UndefinedCompression) |
1244 | 0 | { |
1245 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1246 | 0 | "compression=%s quality=%.20g\n",CommandOptionToMnemonic( |
1247 | 0 | MagickCompressOptions,image->compression),(double) image->quality); |
1248 | 0 | (void) WriteBlobString(image,buffer); |
1249 | 0 | } |
1250 | 0 | if (image->units != UndefinedResolution) |
1251 | 0 | { |
1252 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"units=%s\n", |
1253 | 0 | CommandOptionToMnemonic(MagickResolutionOptions,image->units)); |
1254 | 0 | (void) WriteBlobString(image,buffer); |
1255 | 0 | } |
1256 | 0 | if ((image->resolution.x != 0) || (image->resolution.y != 0)) |
1257 | 0 | { |
1258 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1259 | 0 | "resolution=%gx%g\n",image->resolution.x,image->resolution.y); |
1260 | 0 | (void) WriteBlobString(image,buffer); |
1261 | 0 | } |
1262 | 0 | if ((image->page.width != 0) || (image->page.height != 0)) |
1263 | 0 | { |
1264 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1265 | 0 | "page=%.20gx%.20g%+.20g%+.20g\n",(double) image->page.width,(double) |
1266 | 0 | image->page.height,(double) image->page.x,(double) image->page.y); |
1267 | 0 | (void) WriteBlobString(image,buffer); |
1268 | 0 | } |
1269 | 0 | else |
1270 | 0 | if ((image->page.x != 0) || (image->page.y != 0)) |
1271 | 0 | { |
1272 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"page=%+ld%+ld\n", |
1273 | 0 | (long) image->page.x,(long) image->page.y); |
1274 | 0 | (void) WriteBlobString(image,buffer); |
1275 | 0 | } |
1276 | 0 | if ((image->tile_offset.x != 0) || (image->tile_offset.y != 0)) |
1277 | 0 | { |
1278 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1279 | 0 | "tile-offset=%+ld%+ld\n",(long) image->tile_offset.x,(long) |
1280 | 0 | image->tile_offset.y); |
1281 | 0 | (void) WriteBlobString(image,buffer); |
1282 | 0 | } |
1283 | 0 | if ((GetNextImageInList(image) != (Image *) NULL) || |
1284 | 0 | (GetPreviousImageInList(image) != (Image *) NULL)) |
1285 | 0 | { |
1286 | 0 | if (image->scene == 0) |
1287 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1288 | 0 | "iterations=%.20g delay=%.20g ticks-per-second=%.20g\n",(double) |
1289 | 0 | image->iterations,(double) image->delay,(double) |
1290 | 0 | image->ticks_per_second); |
1291 | 0 | else |
1292 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"scene=%.20g " |
1293 | 0 | "iterations=%.20g delay=%.20g ticks-per-second=%.20g\n", |
1294 | 0 | (double) image->scene,(double) image->iterations,(double) |
1295 | 0 | image->delay,(double) image->ticks_per_second); |
1296 | 0 | (void) WriteBlobString(image,buffer); |
1297 | 0 | } |
1298 | 0 | else |
1299 | 0 | { |
1300 | 0 | if (image->scene != 0) |
1301 | 0 | { |
1302 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"scene=%.20g\n", |
1303 | 0 | (double) image->scene); |
1304 | 0 | (void) WriteBlobString(image,buffer); |
1305 | 0 | } |
1306 | 0 | if (image->iterations != 0) |
1307 | 0 | { |
1308 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1309 | 0 | "iterations=%.20g\n",(double) image->iterations); |
1310 | 0 | (void) WriteBlobString(image,buffer); |
1311 | 0 | } |
1312 | 0 | if (image->delay != 0) |
1313 | 0 | { |
1314 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"delay=%.20g\n", |
1315 | 0 | (double) image->delay); |
1316 | 0 | (void) WriteBlobString(image,buffer); |
1317 | 0 | } |
1318 | 0 | if (image->ticks_per_second != UndefinedTicksPerSecond) |
1319 | 0 | { |
1320 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1321 | 0 | "ticks-per-second=%.20g\n",(double) image->ticks_per_second); |
1322 | 0 | (void) WriteBlobString(image,buffer); |
1323 | 0 | } |
1324 | 0 | } |
1325 | 0 | if (image->gravity != UndefinedGravity) |
1326 | 0 | { |
1327 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"gravity=%s\n", |
1328 | 0 | CommandOptionToMnemonic(MagickGravityOptions,image->gravity)); |
1329 | 0 | (void) WriteBlobString(image,buffer); |
1330 | 0 | } |
1331 | 0 | if (image->dispose != UndefinedDispose) |
1332 | 0 | { |
1333 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"dispose=%s\n", |
1334 | 0 | CommandOptionToMnemonic(MagickDisposeOptions,image->dispose)); |
1335 | 0 | (void) WriteBlobString(image,buffer); |
1336 | 0 | } |
1337 | 0 | if (image->rendering_intent != UndefinedIntent) |
1338 | 0 | { |
1339 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1340 | 0 | "rendering-intent=%s\n",CommandOptionToMnemonic(MagickIntentOptions, |
1341 | 0 | image->rendering_intent)); |
1342 | 0 | (void) WriteBlobString(image,buffer); |
1343 | 0 | } |
1344 | 0 | if (image->gamma != 0.0) |
1345 | 0 | { |
1346 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"gamma=%g\n", |
1347 | 0 | image->gamma); |
1348 | 0 | (void) WriteBlobString(image,buffer); |
1349 | 0 | } |
1350 | 0 | if (image->chromaticity.white_point.x != 0.0) |
1351 | 0 | { |
1352 | | /* |
1353 | | Note chromaticity points. |
1354 | | */ |
1355 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"red-primary=%g,%g " |
1356 | 0 | "green-primary=%g,%g blue-primary=%g,%g\n", |
1357 | 0 | image->chromaticity.red_primary.x,image->chromaticity.red_primary.y, |
1358 | 0 | image->chromaticity.green_primary.x, |
1359 | 0 | image->chromaticity.green_primary.y, |
1360 | 0 | image->chromaticity.blue_primary.x, |
1361 | 0 | image->chromaticity.blue_primary.y); |
1362 | 0 | (void) WriteBlobString(image,buffer); |
1363 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1364 | 0 | "white-point=%g,%g\n",image->chromaticity.white_point.x, |
1365 | 0 | image->chromaticity.white_point.y); |
1366 | 0 | (void) WriteBlobString(image,buffer); |
1367 | 0 | } |
1368 | 0 | if (image->orientation != UndefinedOrientation) |
1369 | 0 | { |
1370 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
1371 | 0 | "orientation=%s\n",CommandOptionToMnemonic(MagickOrientationOptions, |
1372 | 0 | image->orientation)); |
1373 | 0 | (void) WriteBlobString(image,buffer); |
1374 | 0 | } |
1375 | 0 | if (image->profiles != (void *) NULL) |
1376 | 0 | { |
1377 | 0 | const char |
1378 | 0 | *name; |
1379 | |
|
1380 | 0 | const StringInfo |
1381 | 0 | *profile; |
1382 | | |
1383 | | /* |
1384 | | Write image profile names. |
1385 | | */ |
1386 | 0 | ResetImageProfileIterator(image); |
1387 | 0 | for (name=GetNextImageProfile(image); name != (const char *) NULL; ) |
1388 | 0 | { |
1389 | 0 | profile=GetImageProfile(image,name); |
1390 | 0 | if (profile != (StringInfo *) NULL) |
1391 | 0 | { |
1392 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"profile=%s\n", |
1393 | 0 | name); |
1394 | 0 | (void) WriteBlobString(image,buffer); |
1395 | 0 | } |
1396 | 0 | name=GetNextImageProfile(image); |
1397 | 0 | } |
1398 | 0 | } |
1399 | 0 | if (image->montage != (char *) NULL) |
1400 | 0 | { |
1401 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"montage=%s\n", |
1402 | 0 | image->montage); |
1403 | 0 | (void) WriteBlobString(image,buffer); |
1404 | 0 | } |
1405 | 0 | ResetImagePropertyIterator(image); |
1406 | 0 | property=GetNextImageProperty(image); |
1407 | 0 | while (property != (const char *) NULL) |
1408 | 0 | { |
1409 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"%s=",property); |
1410 | 0 | (void) WriteBlobString(image,buffer); |
1411 | 0 | value=GetImageProperty(image,property,exception); |
1412 | 0 | if (value != (const char *) NULL) |
1413 | 0 | { |
1414 | 0 | size_t |
1415 | 0 | length; |
1416 | |
|
1417 | 0 | length=strlen(value); |
1418 | 0 | for (i=0; i < (ssize_t) length; i++) |
1419 | 0 | if (isspace((int) ((unsigned char) value[i])) != 0) |
1420 | 0 | break; |
1421 | 0 | if ((i == (ssize_t) length) && (i != 0)) |
1422 | 0 | (void) WriteBlob(image,length,(const unsigned char *) value); |
1423 | 0 | else |
1424 | 0 | { |
1425 | 0 | (void) WriteBlobByte(image,'{'); |
1426 | 0 | if ((strchr(value,'{') == (char *) NULL) && |
1427 | 0 | (strchr(value,'}') == (char *) NULL)) |
1428 | 0 | (void) WriteBlob(image,length,(const unsigned char *) value); |
1429 | 0 | else |
1430 | 0 | for (i=0; i < (ssize_t) length; i++) |
1431 | 0 | { |
1432 | 0 | if ((value[i] == (int) '{') || (value[i] == (int) '}')) |
1433 | 0 | (void) WriteBlobByte(image,'\\'); |
1434 | 0 | (void) WriteBlobByte(image,(unsigned char) value[i]); |
1435 | 0 | } |
1436 | 0 | (void) WriteBlobByte(image,'}'); |
1437 | 0 | } |
1438 | 0 | } |
1439 | 0 | (void) WriteBlobByte(image,'\n'); |
1440 | 0 | property=GetNextImageProperty(image); |
1441 | 0 | } |
1442 | 0 | (void) WriteBlobString(image,"\f\n:\032"); |
1443 | 0 | if (image->montage != (char *) NULL) |
1444 | 0 | { |
1445 | | /* |
1446 | | Write montage tile directory. |
1447 | | */ |
1448 | 0 | if (image->directory != (char *) NULL) |
1449 | 0 | (void) WriteBlobString(image,image->directory); |
1450 | 0 | (void) WriteBlobByte(image,'\0'); |
1451 | 0 | } |
1452 | 0 | if (image->profiles != 0) |
1453 | 0 | { |
1454 | 0 | const char |
1455 | 0 | *name; |
1456 | |
|
1457 | 0 | const StringInfo |
1458 | 0 | *profile; |
1459 | | |
1460 | | /* |
1461 | | Write image profile blobs. |
1462 | | */ |
1463 | 0 | ResetImageProfileIterator(image); |
1464 | 0 | name=GetNextImageProfile(image); |
1465 | 0 | while (name != (const char *) NULL) |
1466 | 0 | { |
1467 | 0 | profile=GetImageProfile(image,name); |
1468 | 0 | (void) WriteBlobMSBLong(image,(unsigned int) |
1469 | 0 | GetStringInfoLength(profile)); |
1470 | 0 | (void) WriteBlob(image,GetStringInfoLength(profile), |
1471 | 0 | GetStringInfoDatum(profile)); |
1472 | 0 | name=GetNextImageProfile(image); |
1473 | 0 | } |
1474 | 0 | } |
1475 | 0 | if (image->storage_class == PseudoClass) |
1476 | 0 | { |
1477 | 0 | size_t |
1478 | 0 | packet_size; |
1479 | |
|
1480 | 0 | unsigned char |
1481 | 0 | *colormap, |
1482 | 0 | *q; |
1483 | | |
1484 | | /* |
1485 | | Allocate colormap. |
1486 | | */ |
1487 | 0 | packet_size=(size_t) (3UL*depth/8UL); |
1488 | 0 | colormap=(unsigned char *) AcquireQuantumMemory(image->colors, |
1489 | 0 | packet_size*sizeof(*colormap)); |
1490 | 0 | if (colormap == (unsigned char *) NULL) |
1491 | 0 | return(MagickFalse); |
1492 | | /* |
1493 | | Write colormap to file. |
1494 | | */ |
1495 | 0 | q=colormap; |
1496 | 0 | for (i=0; i < (ssize_t) image->colors; i++) |
1497 | 0 | { |
1498 | 0 | switch (depth) |
1499 | 0 | { |
1500 | 0 | default: |
1501 | 0 | { |
1502 | 0 | colormap=(unsigned char *) RelinquishMagickMemory(colormap); |
1503 | 0 | ThrowWriterException(CorruptImageError,"ImageDepthNotSupported"); |
1504 | 0 | break; |
1505 | 0 | } |
1506 | 0 | case 32: |
1507 | 0 | { |
1508 | 0 | unsigned int |
1509 | 0 | pixel; |
1510 | |
|
1511 | 0 | pixel=ScaleQuantumToLong(ClampToQuantum(image->colormap[i].red)); |
1512 | 0 | q=PopLongPixel(MSBEndian,pixel,q); |
1513 | 0 | pixel=ScaleQuantumToLong(ClampToQuantum( |
1514 | 0 | image->colormap[i].green)); |
1515 | 0 | q=PopLongPixel(MSBEndian,pixel,q); |
1516 | 0 | pixel=ScaleQuantumToLong(ClampToQuantum(image->colormap[i].blue)); |
1517 | 0 | q=PopLongPixel(MSBEndian,pixel,q); |
1518 | 0 | break; |
1519 | 0 | } |
1520 | 0 | case 16: |
1521 | 0 | { |
1522 | 0 | unsigned short |
1523 | 0 | pixel; |
1524 | |
|
1525 | 0 | pixel=ScaleQuantumToShort(ClampToQuantum(image->colormap[i].red)); |
1526 | 0 | q=PopShortPixel(MSBEndian,pixel,q); |
1527 | 0 | pixel=ScaleQuantumToShort(ClampToQuantum( |
1528 | 0 | image->colormap[i].green)); |
1529 | 0 | q=PopShortPixel(MSBEndian,pixel,q); |
1530 | 0 | pixel=ScaleQuantumToShort(ClampToQuantum( |
1531 | 0 | image->colormap[i].blue)); |
1532 | 0 | q=PopShortPixel(MSBEndian,pixel,q); |
1533 | 0 | break; |
1534 | 0 | } |
1535 | 0 | case 8: |
1536 | 0 | { |
1537 | 0 | unsigned char |
1538 | 0 | pixel; |
1539 | |
|
1540 | 0 | pixel=(unsigned char) ScaleQuantumToChar(ClampToQuantum( |
1541 | 0 | image->colormap[i].red)); |
1542 | 0 | q=PopCharPixel(pixel,q); |
1543 | 0 | pixel=(unsigned char) ScaleQuantumToChar(ClampToQuantum( |
1544 | 0 | image->colormap[i].green)); |
1545 | 0 | q=PopCharPixel(pixel,q); |
1546 | 0 | pixel=(unsigned char) ScaleQuantumToChar(ClampToQuantum( |
1547 | 0 | image->colormap[i].blue)); |
1548 | 0 | q=PopCharPixel(pixel,q); |
1549 | 0 | break; |
1550 | 0 | } |
1551 | 0 | } |
1552 | 0 | } |
1553 | 0 | (void) WriteBlob(image,packet_size*image->colors,colormap); |
1554 | 0 | colormap=(unsigned char *) RelinquishMagickMemory(colormap); |
1555 | 0 | } |
1556 | | /* |
1557 | | Initialize persistent pixel cache. |
1558 | | */ |
1559 | 0 | status=PersistPixelCache(image,cache_filename,MagickFalse,&offset, |
1560 | 0 | exception); |
1561 | 0 | if (status == MagickFalse) |
1562 | 0 | ThrowWriterException(CacheError,"UnableToPersistPixelCache"); |
1563 | 0 | if (GetNextImageInList(image) == (Image *) NULL) |
1564 | 0 | break; |
1565 | 0 | image=SyncNextImageInList(image); |
1566 | 0 | if (image->progress_monitor != (MagickProgressMonitor) NULL) |
1567 | 0 | { |
1568 | 0 | status=image->progress_monitor(SaveImagesTag,scene, |
1569 | 0 | number_scenes,image->client_data); |
1570 | 0 | if (status == MagickFalse) |
1571 | 0 | break; |
1572 | 0 | } |
1573 | 0 | scene++; |
1574 | 0 | } while (image_info->adjoin != MagickFalse); |
1575 | 0 | if (CloseBlob(image) == MagickFalse) |
1576 | 0 | status=MagickFalse; |
1577 | 0 | return(status); |
1578 | 0 | } |