blob: 0ec26f2b1283bd4bc34bfeea74b4432f89551fa8 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% RRRR GGGG BBBB %
7% R R G B B %
8% RRRR G GG BBBB %
9% R R G G B B %
10% R R GGG BBBB %
11% %
12% %
13% Read/Write Raw RGB Image Format %
14% %
15% Software Design %
16% John Cristy %
17% July 1992 %
18% %
19% %
20% Copyright 1999-2008 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% http://www.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 Include declarations.
41*/
42#include "magick/studio.h"
43#include "magick/blob.h"
44#include "magick/blob-private.h"
45#include "magick/cache.h"
46#include "magick/colorspace.h"
47#include "magick/constitute.h"
48#include "magick/exception.h"
49#include "magick/exception-private.h"
50#include "magick/image.h"
51#include "magick/image-private.h"
52#include "magick/list.h"
53#include "magick/magick.h"
54#include "magick/memory_.h"
55#include "magick/monitor.h"
56#include "magick/monitor-private.h"
57#include "magick/pixel-private.h"
58#include "magick/quantum-private.h"
59#include "magick/static.h"
60#include "magick/statistic.h"
61#include "magick/string_.h"
62#include "magick/module.h"
63#include "magick/utility.h"
64
65/*
66 Forward declarations.
67*/
68static MagickBooleanType
69 WriteRGBImage(const ImageInfo *,Image *);
70
71/*
72%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73% %
74% %
75% %
76% R e a d R G B I m a g e %
77% %
78% %
79% %
80%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81%
cristy90dbac72010-08-22 15:08:40 +000082% ReadRGBImage() reads an image of raw RGB, RGBA, or RGBO samples and returns
83% it. It allocates the memory necessary for the new Image structure and
84% returns a pointer to the new image.
cristy3ed852e2009-09-05 21:47:34 +000085%
86% The format of the ReadRGBImage method is:
87%
cristy90dbac72010-08-22 15:08:40 +000088% Image *ReadRGBImage(const ImageInfo *image_info,
89% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +000090%
91% A description of each parameter follows:
92%
93% o image_info: the image info.
94%
95% o exception: return any errors or warnings in this structure.
96%
97*/
cristy90dbac72010-08-22 15:08:40 +000098static Image *ReadRGBImage(const ImageInfo *image_info,
99 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000100{
101 Image
102 *canvas_image,
103 *image;
104
cristy3ed852e2009-09-05 21:47:34 +0000105 MagickBooleanType
106 status;
107
108 MagickOffsetType
109 scene;
110
111 QuantumInfo
112 *quantum_info;
113
114 QuantumType
115 quantum_type;
116
cristybb503372010-05-27 20:51:26 +0000117 register ssize_t
cristy90dbac72010-08-22 15:08:40 +0000118 i;
cristy3ed852e2009-09-05 21:47:34 +0000119
cristy3ed852e2009-09-05 21:47:34 +0000120 ssize_t
cristya38675f2010-08-21 18:35:13 +0000121 count,
122 y;
cristy3ed852e2009-09-05 21:47:34 +0000123
124 size_t
125 length;
126
127 unsigned char
128 *pixels;
129
cristy3ed852e2009-09-05 21:47:34 +0000130 /*
131 Open image file.
132 */
133 assert(image_info != (const ImageInfo *) NULL);
134 assert(image_info->signature == MagickSignature);
135 if (image_info->debug != MagickFalse)
136 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
137 image_info->filename);
138 assert(exception != (ExceptionInfo *) NULL);
139 assert(exception->signature == MagickSignature);
140 image=AcquireImage(image_info);
141 if ((image->columns == 0) || (image->rows == 0))
142 ThrowReaderException(OptionError,"MustSpecifyImageSize");
cristy90dbac72010-08-22 15:08:40 +0000143 image->colorspace=RGBColorspace;
cristy3ed852e2009-09-05 21:47:34 +0000144 if (image_info->interlace != PartitionInterlace)
145 {
146 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
147 if (status == MagickFalse)
148 {
149 image=DestroyImageList(image);
150 return((Image *) NULL);
151 }
cristyd4297022010-09-16 22:59:09 +0000152 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
153 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
154 image->filename);
cristy3ed852e2009-09-05 21:47:34 +0000155 }
156 /*
157 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
158 */
159 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
160 exception);
161 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod);
162 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
163 if (quantum_info == (QuantumInfo *) NULL)
164 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
165 pixels=GetQuantumPixels(quantum_info);
166 quantum_type=RGBQuantum;
cristy90dbac72010-08-22 15:08:40 +0000167 if (LocaleCompare(image_info->magick,"RGBA") == 0)
cristya38675f2010-08-21 18:35:13 +0000168 {
cristy90dbac72010-08-22 15:08:40 +0000169 quantum_type=RGBAQuantum;
170 image->matte=MagickTrue;
cristya38675f2010-08-21 18:35:13 +0000171 }
cristy90dbac72010-08-22 15:08:40 +0000172 if (LocaleCompare(image_info->magick,"RGBO") == 0)
173 {
174 quantum_type=RGBOQuantum;
175 image->matte=MagickTrue;
176 }
cristy3ed852e2009-09-05 21:47:34 +0000177 if (image_info->number_scenes != 0)
178 while (image->scene < image_info->scene)
179 {
180 /*
181 Skip to next image.
182 */
183 image->scene++;
184 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +0000185 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000186 {
187 count=ReadBlob(image,length,pixels);
188 if (count != (ssize_t) length)
189 break;
190 }
191 }
cristy3ed852e2009-09-05 21:47:34 +0000192 count=0;
193 length=0;
194 scene=0;
195 do
196 {
197 /*
198 Read pixels to virtual canvas image then push to image.
199 */
200 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
201 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
202 break;
cristy90dbac72010-08-22 15:08:40 +0000203 image->colorspace=RGBColorspace;
cristy3ed852e2009-09-05 21:47:34 +0000204 switch (image_info->interlace)
205 {
206 case NoInterlace:
207 default:
208 {
209 /*
210 No interlacing: RGBRGBRGBRGBRGBRGB...
211 */
212 if (scene == 0)
213 {
214 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
215 count=ReadBlob(image,length,pixels);
cristy3ed852e2009-09-05 21:47:34 +0000216 }
cristybb503372010-05-27 20:51:26 +0000217 for (y=0; y < (ssize_t) image->extract_info.height; y++)
cristy3ed852e2009-09-05 21:47:34 +0000218 {
219 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000220 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000221
cristy3ed852e2009-09-05 21:47:34 +0000222 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000223 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000224
cristy90dbac72010-08-22 15:08:40 +0000225 register ssize_t
226 x;
227
cristy21da32d2009-09-12 14:56:09 +0000228 if (count != (ssize_t) length)
229 {
230 ThrowFileException(exception,CorruptImageError,
231 "UnexpectedEndOfFile",image->filename);
232 break;
233 }
cristy3ed852e2009-09-05 21:47:34 +0000234 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
235 exception);
236 if (q == (PixelPacket *) NULL)
237 break;
238 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
239 quantum_info,quantum_type,pixels,exception);
240 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
241 break;
cristy90dbac72010-08-22 15:08:40 +0000242 if (((y-image->extract_info.y) >= 0) &&
cristybb503372010-05-27 20:51:26 +0000243 ((y-image->extract_info.y) < (ssize_t) image->rows))
cristy3ed852e2009-09-05 21:47:34 +0000244 {
245 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
246 canvas_image->columns,1,exception);
247 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
248 image->columns,1,exception);
249 if ((p == (const PixelPacket *) NULL) ||
250 (q == (PixelPacket *) NULL))
251 break;
cristybb503372010-05-27 20:51:26 +0000252 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000253 {
cristy90dbac72010-08-22 15:08:40 +0000254 SetRedPixelComponent(q,GetRedPixelComponent(p));
255 SetGreenPixelComponent(q,GetGreenPixelComponent(p));
256 SetBluePixelComponent(q,GetBluePixelComponent(p));
257 SetOpacityPixelComponent(q,OpaqueOpacity);
258 if (image->matte != MagickFalse)
259 SetOpacityPixelComponent(q,GetOpacityPixelComponent(p));
cristy3ed852e2009-09-05 21:47:34 +0000260 p++;
261 q++;
262 }
263 if (SyncAuthenticPixels(image,exception) == MagickFalse)
264 break;
265 }
266 if (image->previous == (Image *) NULL)
267 {
cristycee97112010-05-28 00:44:52 +0000268 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
269 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000270 if (status == MagickFalse)
271 break;
272 }
273 count=ReadBlob(image,length,pixels);
cristy3ed852e2009-09-05 21:47:34 +0000274 }
275 break;
276 }
277 case LineInterlace:
278 {
cristy90dbac72010-08-22 15:08:40 +0000279 static QuantumType
280 quantum_types[4] =
281 {
282 RedQuantum,
283 GreenQuantum,
284 BlueQuantum,
285 AlphaQuantum
286 };
287
cristy3ed852e2009-09-05 21:47:34 +0000288 /*
289 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
290 */
cristy90dbac72010-08-22 15:08:40 +0000291 if (LocaleCompare(image_info->magick,"RGBO") == 0)
292 quantum_types[3]=OpacityQuantum;
cristy3ed852e2009-09-05 21:47:34 +0000293 if (scene == 0)
294 {
cristy90dbac72010-08-22 15:08:40 +0000295 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
cristy3ed852e2009-09-05 21:47:34 +0000296 count=ReadBlob(image,length,pixels);
cristy3ed852e2009-09-05 21:47:34 +0000297 }
cristybb503372010-05-27 20:51:26 +0000298 for (y=0; y < (ssize_t) image->extract_info.height; y++)
cristy3ed852e2009-09-05 21:47:34 +0000299 {
300 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000301 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000302
cristy3ed852e2009-09-05 21:47:34 +0000303 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000304 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000305
cristy90dbac72010-08-22 15:08:40 +0000306 register ssize_t
307 x;
308
cristy21da32d2009-09-12 14:56:09 +0000309 if (count != (ssize_t) length)
310 {
311 ThrowFileException(exception,CorruptImageError,
312 "UnexpectedEndOfFile",image->filename);
313 break;
314 }
cristy90dbac72010-08-22 15:08:40 +0000315 for (i=0; i < (ssize_t) (image->matte != MagickFalse ? 4 : 3); i++)
cristy3ed852e2009-09-05 21:47:34 +0000316 {
cristy90dbac72010-08-22 15:08:40 +0000317 quantum_type=quantum_types[i];
cristy3ed852e2009-09-05 21:47:34 +0000318 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
319 exception);
320 if (q == (PixelPacket *) NULL)
321 break;
322 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
cristy90dbac72010-08-22 15:08:40 +0000323 quantum_info,quantum_type,pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +0000324 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
325 break;
cristy90dbac72010-08-22 15:08:40 +0000326 if (((y-image->extract_info.y) >= 0) &&
cristybb503372010-05-27 20:51:26 +0000327 ((y-image->extract_info.y) < (ssize_t) image->rows))
cristy3ed852e2009-09-05 21:47:34 +0000328 {
329 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
330 0,canvas_image->columns,1,exception);
331 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
332 image->columns,1,exception);
333 if ((p == (const PixelPacket *) NULL) ||
334 (q == (PixelPacket *) NULL))
335 break;
cristy90dbac72010-08-22 15:08:40 +0000336 for (x=0; x < (ssize_t) image->columns; x++)
337 {
338 switch (quantum_type)
cristy3ed852e2009-09-05 21:47:34 +0000339 {
cristy90dbac72010-08-22 15:08:40 +0000340 case RedQuantum:
341 {
342 SetRedPixelComponent(q,GetRedPixelComponent(p));
343 break;
344 }
345 case GreenQuantum:
346 {
347 SetGreenPixelComponent(q,GetGreenPixelComponent(p));
348 break;
349 }
350 case BlueQuantum:
351 {
352 SetBluePixelComponent(q,GetBluePixelComponent(p));
353 break;
354 }
355 case OpacityQuantum:
356 {
357 SetOpacityPixelComponent(q,GetOpacityPixelComponent(p));
358 break;
359 }
360 case AlphaQuantum:
361 {
362 SetAlphaPixelComponent(q,GetAlphaPixelComponent(p));
363 break;
364 }
365 default:
366 break;
cristy3ed852e2009-09-05 21:47:34 +0000367 }
cristy90dbac72010-08-22 15:08:40 +0000368 p++;
369 q++;
370 }
cristy3ed852e2009-09-05 21:47:34 +0000371 if (SyncAuthenticPixels(image,exception) == MagickFalse)
372 break;
373 }
374 count=ReadBlob(image,length,pixels);
cristy3ed852e2009-09-05 21:47:34 +0000375 }
376 if (image->previous == (Image *) NULL)
377 {
cristycee97112010-05-28 00:44:52 +0000378 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
379 image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000380 if (status == MagickFalse)
381 break;
382 }
383 }
384 break;
385 }
386 case PlaneInterlace:
387 {
388 /*
389 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
390 */
391 if (scene == 0)
392 {
cristy90dbac72010-08-22 15:08:40 +0000393 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
cristy3ed852e2009-09-05 21:47:34 +0000394 count=ReadBlob(image,length,pixels);
cristy3ed852e2009-09-05 21:47:34 +0000395 }
cristy90dbac72010-08-22 15:08:40 +0000396 for (y=0; y < (ssize_t) image->extract_info.height; y++)
cristy3ed852e2009-09-05 21:47:34 +0000397 {
cristy90dbac72010-08-22 15:08:40 +0000398 register const PixelPacket
399 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +0000400
cristy90dbac72010-08-22 15:08:40 +0000401 register PixelPacket
402 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000403
cristy90dbac72010-08-22 15:08:40 +0000404 register ssize_t
405 x;
cristy3ed852e2009-09-05 21:47:34 +0000406
cristy90dbac72010-08-22 15:08:40 +0000407 if (count != (ssize_t) length)
cristy3ed852e2009-09-05 21:47:34 +0000408 {
cristy90dbac72010-08-22 15:08:40 +0000409 ThrowFileException(exception,CorruptImageError,
410 "UnexpectedEndOfFile",image->filename);
411 break;
412 }
413 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
414 exception);
415 if (q == (PixelPacket *) NULL)
416 break;
417 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
418 quantum_info,RedQuantum,pixels,exception);
419 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
420 break;
421 if (((y-image->extract_info.y) >= 0) &&
422 ((y-image->extract_info.y) < (ssize_t) image->rows))
423 {
424 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
425 canvas_image->columns,1,exception);
426 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
427 image->columns,1,exception);
428 if ((p == (const PixelPacket *) NULL) ||
429 (q == (PixelPacket *) NULL))
430 break;
431 for (x=0; x < (ssize_t) image->columns; x++)
432 {
433 SetRedPixelComponent(q,GetRedPixelComponent(p));
434 p++;
435 q++;
436 }
437 if (SyncAuthenticPixels(image,exception) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000438 break;
439 }
cristy90dbac72010-08-22 15:08:40 +0000440 count=ReadBlob(image,length,pixels);
cristy3ed852e2009-09-05 21:47:34 +0000441 }
442 if (image->previous == (Image *) NULL)
443 {
cristy90dbac72010-08-22 15:08:40 +0000444 status=SetImageProgress(image,LoadImageTag,1,6);
445 if (status == MagickFalse)
446 break;
447 }
448 for (y=0; y < (ssize_t) image->extract_info.height; y++)
449 {
450 register const PixelPacket
451 *restrict p;
452
453 register PixelPacket
454 *restrict q;
455
456 register ssize_t
457 x;
458
459 if (count != (ssize_t) length)
460 {
461 ThrowFileException(exception,CorruptImageError,
462 "UnexpectedEndOfFile",image->filename);
463 break;
464 }
465 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
466 exception);
467 if (q == (PixelPacket *) NULL)
468 break;
469 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
470 quantum_info,GreenQuantum,pixels,exception);
471 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
472 break;
473 if (((y-image->extract_info.y) >= 0) &&
474 ((y-image->extract_info.y) < (ssize_t) image->rows))
475 {
476 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
477 canvas_image->columns,1,exception);
478 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
479 image->columns,1,exception);
480 if ((p == (const PixelPacket *) NULL) ||
481 (q == (PixelPacket *) NULL))
482 break;
483 for (x=0; x < (ssize_t) image->columns; x++)
484 {
485 SetGreenPixelComponent(q,GetGreenPixelComponent(p));
486 p++;
487 q++;
488 }
489 if (SyncAuthenticPixels(image,exception) == MagickFalse)
490 break;
491 }
492 count=ReadBlob(image,length,pixels);
493 }
494 if (image->previous == (Image *) NULL)
495 {
496 status=SetImageProgress(image,LoadImageTag,2,6);
497 if (status == MagickFalse)
498 break;
499 }
500 for (y=0; y < (ssize_t) image->extract_info.height; y++)
501 {
502 register const PixelPacket
503 *restrict p;
504
505 register PixelPacket
506 *restrict q;
507
508 register ssize_t
509 x;
510
511 if (count != (ssize_t) length)
512 {
513 ThrowFileException(exception,CorruptImageError,
514 "UnexpectedEndOfFile",image->filename);
515 break;
516 }
517 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
518 exception);
519 if (q == (PixelPacket *) NULL)
520 break;
521 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
522 quantum_info,BlueQuantum,pixels,exception);
523 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
524 break;
525 if (((y-image->extract_info.y) >= 0) &&
526 ((y-image->extract_info.y) < (ssize_t) image->rows))
527 {
528 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
529 canvas_image->columns,1,exception);
530 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
531 image->columns,1,exception);
532 if ((p == (const PixelPacket *) NULL) ||
533 (q == (PixelPacket *) NULL))
534 break;
535 for (x=0; x < (ssize_t) image->columns; x++)
536 {
537 SetBluePixelComponent(q,GetBluePixelComponent(p));
538 p++;
539 q++;
540 }
541 if (SyncAuthenticPixels(image,exception) == MagickFalse)
542 break;
543 }
544 count=ReadBlob(image,length,pixels);
545 }
546 if (image->previous == (Image *) NULL)
547 {
548 status=SetImageProgress(image,LoadImageTag,3,6);
549 if (status == MagickFalse)
550 break;
551 }
552 if (image->previous == (Image *) NULL)
553 {
554 status=SetImageProgress(image,LoadImageTag,4,6);
555 if (status == MagickFalse)
556 break;
557 }
558 if (image->matte != MagickFalse)
559 {
560 for (y=0; y < (ssize_t) image->extract_info.height; y++)
561 {
562 register const PixelPacket
563 *restrict p;
564
565 register PixelPacket
566 *restrict q;
567
568 register ssize_t
569 x;
570
571 if (count != (ssize_t) length)
572 {
573 ThrowFileException(exception,CorruptImageError,
574 "UnexpectedEndOfFile",image->filename);
575 break;
576 }
577 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
578 exception);
579 if (q == (PixelPacket *) NULL)
580 break;
581 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
582 quantum_info,AlphaQuantum,pixels,exception);
583 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
584 break;
585 if (((y-image->extract_info.y) >= 0) &&
586 ((y-image->extract_info.y) < (ssize_t) image->rows))
587 {
588 p=GetVirtualPixels(canvas_image,
589 canvas_image->extract_info.x,0,canvas_image->columns,1,
590 exception);
591 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
592 image->columns,1,exception);
593 if ((p == (const PixelPacket *) NULL) ||
594 (q == (PixelPacket *) NULL))
595 break;
596 for (x=0; x < (ssize_t) image->columns; x++)
597 {
598 SetOpacityPixelComponent(q,GetOpacityPixelComponent(p));
599 p++;
600 q++;
601 }
602 if (SyncAuthenticPixels(image,exception) == MagickFalse)
603 break;
604 }
605 count=ReadBlob(image,length,pixels);
606 }
607 if (image->previous == (Image *) NULL)
608 {
609 status=SetImageProgress(image,LoadImageTag,5,6);
610 if (status == MagickFalse)
611 break;
612 }
613 }
614 if (image->previous == (Image *) NULL)
615 {
616 status=SetImageProgress(image,LoadImageTag,6,6);
cristy3ed852e2009-09-05 21:47:34 +0000617 if (status == MagickFalse)
618 break;
619 }
620 break;
621 }
622 case PartitionInterlace:
623 {
624 /*
625 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
626 */
cristy90dbac72010-08-22 15:08:40 +0000627 AppendImageFormat("R",image->filename);
628 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
629 if (status == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000630 {
cristy90dbac72010-08-22 15:08:40 +0000631 canvas_image=DestroyImageList(canvas_image);
632 image=DestroyImageList(image);
633 return((Image *) NULL);
634 }
cristyd4297022010-09-16 22:59:09 +0000635 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
636 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
637 image->filename);
cristy90dbac72010-08-22 15:08:40 +0000638 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
639 for (i=0; i < (ssize_t) scene; i++)
640 for (y=0; y < (ssize_t) image->extract_info.height; y++)
641 if (ReadBlob(image,length,pixels) != (ssize_t) length)
cristy21da32d2009-09-12 14:56:09 +0000642 {
643 ThrowFileException(exception,CorruptImageError,
644 "UnexpectedEndOfFile",image->filename);
645 break;
646 }
cristy90dbac72010-08-22 15:08:40 +0000647 count=ReadBlob(image,length,pixels);
648 for (y=0; y < (ssize_t) image->extract_info.height; y++)
649 {
650 register const PixelPacket
651 *restrict p;
652
653 register PixelPacket
654 *restrict q;
655
656 register ssize_t
657 x;
658
659 if (count != (ssize_t) length)
cristy3ed852e2009-09-05 21:47:34 +0000660 {
cristy90dbac72010-08-22 15:08:40 +0000661 ThrowFileException(exception,CorruptImageError,
662 "UnexpectedEndOfFile",image->filename);
663 break;
664 }
665 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
666 exception);
667 if (q == (PixelPacket *) NULL)
668 break;
669 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
670 quantum_info,RedQuantum,pixels,exception);
671 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
672 break;
673 if (((y-image->extract_info.y) >= 0) &&
674 ((y-image->extract_info.y) < (ssize_t) image->rows))
675 {
676 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
677 canvas_image->columns,1,exception);
678 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
679 image->columns,1,exception);
680 if ((p == (const PixelPacket *) NULL) ||
681 (q == (PixelPacket *) NULL))
682 break;
683 for (x=0; x < (ssize_t) image->columns; x++)
684 {
685 SetRedPixelComponent(q,GetRedPixelComponent(p));
686 p++;
687 q++;
688 }
689 if (SyncAuthenticPixels(image,exception) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000690 break;
691 }
cristy90dbac72010-08-22 15:08:40 +0000692 count=ReadBlob(image,length,pixels);
cristy3ed852e2009-09-05 21:47:34 +0000693 }
694 if (image->previous == (Image *) NULL)
695 {
cristy90dbac72010-08-22 15:08:40 +0000696 status=SetImageProgress(image,LoadImageTag,1,5);
697 if (status == MagickFalse)
698 break;
699 }
700 (void) CloseBlob(image);
701 AppendImageFormat("G",image->filename);
702 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
703 if (status == MagickFalse)
704 {
705 canvas_image=DestroyImageList(canvas_image);
706 image=DestroyImageList(image);
707 return((Image *) NULL);
708 }
709 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
710 for (i=0; i < (ssize_t) scene; i++)
711 for (y=0; y < (ssize_t) image->extract_info.height; y++)
712 if (ReadBlob(image,length,pixels) != (ssize_t) length)
713 {
714 ThrowFileException(exception,CorruptImageError,
715 "UnexpectedEndOfFile",image->filename);
716 break;
717 }
718 count=ReadBlob(image,length,pixels);
719 for (y=0; y < (ssize_t) image->extract_info.height; y++)
720 {
721 register const PixelPacket
722 *restrict p;
723
724 register PixelPacket
725 *restrict q;
726
727 register ssize_t
728 x;
729
730 if (count != (ssize_t) length)
731 {
732 ThrowFileException(exception,CorruptImageError,
733 "UnexpectedEndOfFile",image->filename);
734 break;
735 }
736 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
737 exception);
738 if (q == (PixelPacket *) NULL)
739 break;
740 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
741 quantum_info,GreenQuantum,pixels,exception);
742 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
743 break;
744 if (((y-image->extract_info.y) >= 0) &&
745 ((y-image->extract_info.y) < (ssize_t) image->rows))
746 {
747 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
748 canvas_image->columns,1,exception);
749 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
750 image->columns,1,exception);
751 if ((p == (const PixelPacket *) NULL) ||
752 (q == (PixelPacket *) NULL))
753 break;
754 for (x=0; x < (ssize_t) image->columns; x++)
755 {
756 SetGreenPixelComponent(q,GetGreenPixelComponent(p));
757 p++;
758 q++;
759 }
760 if (SyncAuthenticPixels(image,exception) == MagickFalse)
761 break;
762 }
763 count=ReadBlob(image,length,pixels);
764 }
765 if (image->previous == (Image *) NULL)
766 {
767 status=SetImageProgress(image,LoadImageTag,2,5);
768 if (status == MagickFalse)
769 break;
770 }
771 (void) CloseBlob(image);
772 AppendImageFormat("B",image->filename);
773 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
774 if (status == MagickFalse)
775 {
776 canvas_image=DestroyImageList(canvas_image);
777 image=DestroyImageList(image);
778 return((Image *) NULL);
779 }
780 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
781 for (i=0; i < (ssize_t) scene; i++)
782 for (y=0; y < (ssize_t) image->extract_info.height; y++)
783 if (ReadBlob(image,length,pixels) != (ssize_t) length)
784 {
785 ThrowFileException(exception,CorruptImageError,
786 "UnexpectedEndOfFile",image->filename);
787 break;
788 }
789 count=ReadBlob(image,length,pixels);
790 for (y=0; y < (ssize_t) image->extract_info.height; y++)
791 {
792 register const PixelPacket
793 *restrict p;
794
795 register PixelPacket
796 *restrict q;
797
798 register ssize_t
799 x;
800
801 if (count != (ssize_t) length)
802 {
803 ThrowFileException(exception,CorruptImageError,
804 "UnexpectedEndOfFile",image->filename);
805 break;
806 }
807 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
808 exception);
809 if (q == (PixelPacket *) NULL)
810 break;
811 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
812 quantum_info,BlueQuantum,pixels,exception);
813 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
814 break;
815 if (((y-image->extract_info.y) >= 0) &&
816 ((y-image->extract_info.y) < (ssize_t) image->rows))
817 {
818 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
819 canvas_image->columns,1,exception);
820 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
821 image->columns,1,exception);
822 if ((p == (const PixelPacket *) NULL) ||
823 (q == (PixelPacket *) NULL))
824 break;
825 for (x=0; x < (ssize_t) image->columns; x++)
826 {
827 SetBluePixelComponent(q,GetBluePixelComponent(p));
828 p++;
829 q++;
830 }
831 if (SyncAuthenticPixels(image,exception) == MagickFalse)
832 break;
833 }
834 count=ReadBlob(image,length,pixels);
835 }
836 if (image->previous == (Image *) NULL)
837 {
838 status=SetImageProgress(image,LoadImageTag,3,5);
839 if (status == MagickFalse)
840 break;
841 }
842 if (image->matte != MagickFalse)
843 {
844 (void) CloseBlob(image);
845 AppendImageFormat("A",image->filename);
846 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
847 if (status == MagickFalse)
848 {
849 canvas_image=DestroyImageList(canvas_image);
850 image=DestroyImageList(image);
851 return((Image *) NULL);
852 }
853 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
854 for (i=0; i < (ssize_t) scene; i++)
855 for (y=0; y < (ssize_t) image->extract_info.height; y++)
856 if (ReadBlob(image,length,pixels) != (ssize_t) length)
857 {
858 ThrowFileException(exception,CorruptImageError,
859 "UnexpectedEndOfFile",image->filename);
860 break;
861 }
862 count=ReadBlob(image,length,pixels);
863 for (y=0; y < (ssize_t) image->extract_info.height; y++)
864 {
865 register const PixelPacket
866 *restrict p;
867
868 register PixelPacket
869 *restrict q;
870
871 register ssize_t
872 x;
873
874 if (count != (ssize_t) length)
875 {
876 ThrowFileException(exception,CorruptImageError,
877 "UnexpectedEndOfFile",image->filename);
878 break;
879 }
880 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
881 exception);
882 if (q == (PixelPacket *) NULL)
883 break;
884 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
885 quantum_info,BlueQuantum,pixels,exception);
886 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
887 break;
888 if (((y-image->extract_info.y) >= 0) &&
889 ((y-image->extract_info.y) < (ssize_t) image->rows))
890 {
891 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
892 0,canvas_image->columns,1,exception);
893 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
894 image->columns,1,exception);
895 if ((p == (const PixelPacket *) NULL) ||
896 (q == (PixelPacket *) NULL))
897 break;
898 for (x=0; x < (ssize_t) image->columns; x++)
899 {
900 SetOpacityPixelComponent(q,GetOpacityPixelComponent(p));
901 p++;
902 q++;
903 }
904 if (SyncAuthenticPixels(image,exception) == MagickFalse)
905 break;
906 }
907 count=ReadBlob(image,length,pixels);
908 }
909 if (image->previous == (Image *) NULL)
910 {
911 status=SetImageProgress(image,LoadImageTag,4,5);
912 if (status == MagickFalse)
913 break;
914 }
915 }
916 (void) CloseBlob(image);
917 if (image->previous == (Image *) NULL)
918 {
cristy3ed852e2009-09-05 21:47:34 +0000919 status=SetImageProgress(image,LoadImageTag,5,5);
920 if (status == MagickFalse)
921 break;
922 }
923 break;
924 }
925 }
926 SetQuantumImageType(image,quantum_type);
cristy3ed852e2009-09-05 21:47:34 +0000927 /*
928 Proceed to next image.
929 */
930 if (image_info->number_scenes != 0)
931 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
932 break;
933 if (count == (ssize_t) length)
934 {
935 /*
936 Allocate next image structure.
937 */
938 AcquireNextImage(image_info,image);
939 if (GetNextImageInList(image) == (Image *) NULL)
940 {
941 image=DestroyImageList(image);
942 return((Image *) NULL);
943 }
944 image=SyncNextImageInList(image);
945 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
946 GetBlobSize(image));
947 if (status == MagickFalse)
948 break;
949 }
950 scene++;
951 } while (count == (ssize_t) length);
cristy3ed852e2009-09-05 21:47:34 +0000952 quantum_info=DestroyQuantumInfo(quantum_info);
cristy01a3f332009-10-27 14:17:37 +0000953 InheritException(&image->exception,&canvas_image->exception);
cristy3ed852e2009-09-05 21:47:34 +0000954 canvas_image=DestroyImage(canvas_image);
955 (void) CloseBlob(image);
956 return(GetFirstImageInList(image));
957}
958
959/*
960%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
961% %
962% %
963% %
964% R e g i s t e r R G B I m a g e %
965% %
966% %
967% %
968%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
969%
cristy90dbac72010-08-22 15:08:40 +0000970% RegisterRGBImage() adds attributes for the RGB image format to
cristy3ed852e2009-09-05 21:47:34 +0000971% the list of supported formats. The attributes include the image format
972% tag, a method to read and/or write the format, whether the format
973% supports the saving of more than one frame to the same file or blob,
974% whether the format supports native in-memory I/O, and a brief
975% description of the format.
976%
977% The format of the RegisterRGBImage method is:
978%
cristybb503372010-05-27 20:51:26 +0000979% size_t RegisterRGBImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000980%
981*/
cristybb503372010-05-27 20:51:26 +0000982ModuleExport size_t RegisterRGBImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000983{
984 MagickInfo
985 *entry;
986
987 entry=SetMagickInfo("RGB");
988 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
989 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
990 entry->raw=MagickTrue;
991 entry->endian_support=MagickTrue;
cristy3ed852e2009-09-05 21:47:34 +0000992 entry->description=ConstantString("Raw red, green, and blue samples");
993 entry->module=ConstantString("RGB");
994 (void) RegisterMagickInfo(entry);
cristy3ed852e2009-09-05 21:47:34 +0000995 entry=SetMagickInfo("RGBA");
996 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
997 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
998 entry->raw=MagickTrue;
999 entry->endian_support=MagickTrue;
cristy3ed852e2009-09-05 21:47:34 +00001000 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
1001 entry->module=ConstantString("RGB");
1002 (void) RegisterMagickInfo(entry);
1003 entry=SetMagickInfo("RGBO");
1004 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1005 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1006 entry->raw=MagickTrue;
1007 entry->endian_support=MagickTrue;
cristy90dbac72010-08-22 15:08:40 +00001008 entry->description=ConstantString("Raw red, green, blue, and opacity samples");
cristy3ed852e2009-09-05 21:47:34 +00001009 entry->module=ConstantString("RGB");
1010 (void) RegisterMagickInfo(entry);
1011 return(MagickImageCoderSignature);
1012}
1013
1014/*
1015%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1016% %
1017% %
1018% %
1019% U n r e g i s t e r R G B I m a g e %
1020% %
1021% %
1022% %
1023%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1024%
cristy90dbac72010-08-22 15:08:40 +00001025% UnregisterRGBImage() removes format registrations made by the RGB module
1026% from the list of supported formats.
cristy3ed852e2009-09-05 21:47:34 +00001027%
1028% The format of the UnregisterRGBImage method is:
1029%
1030% UnregisterRGBImage(void)
1031%
1032*/
1033ModuleExport void UnregisterRGBImage(void)
1034{
1035 (void) UnregisterMagickInfo("RGBO");
1036 (void) UnregisterMagickInfo("RGBA");
cristy3ed852e2009-09-05 21:47:34 +00001037 (void) UnregisterMagickInfo("RGB");
1038}
1039
1040/*
1041%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1042% %
1043% %
1044% %
1045% W r i t e R G B I m a g e %
1046% %
1047% %
1048% %
1049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1050%
cristy90dbac72010-08-22 15:08:40 +00001051% WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1052% rasterfile format.
cristy3ed852e2009-09-05 21:47:34 +00001053%
1054% The format of the WriteRGBImage method is:
1055%
cristy90dbac72010-08-22 15:08:40 +00001056% MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1057% Image *image)
cristy3ed852e2009-09-05 21:47:34 +00001058%
1059% A description of each parameter follows.
1060%
1061% o image_info: the image info.
1062%
1063% o image: The image.
1064%
1065*/
cristy90dbac72010-08-22 15:08:40 +00001066static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1067 Image *image)
cristy3ed852e2009-09-05 21:47:34 +00001068{
cristy3ed852e2009-09-05 21:47:34 +00001069 MagickBooleanType
1070 status;
1071
1072 MagickOffsetType
1073 scene;
1074
1075 QuantumInfo
1076 *quantum_info;
1077
1078 QuantumType
cristy90dbac72010-08-22 15:08:40 +00001079 quantum_type;
cristy3ed852e2009-09-05 21:47:34 +00001080
1081 ssize_t
cristy90dbac72010-08-22 15:08:40 +00001082 count,
1083 y;
cristy3ed852e2009-09-05 21:47:34 +00001084
1085 size_t
1086 length;
1087
1088 unsigned char
1089 *pixels;
1090
cristy3ed852e2009-09-05 21:47:34 +00001091 /*
1092 Allocate memory for pixels.
1093 */
1094 assert(image_info != (const ImageInfo *) NULL);
1095 assert(image_info->signature == MagickSignature);
1096 assert(image != (Image *) NULL);
1097 assert(image->signature == MagickSignature);
1098 if (image->debug != MagickFalse)
1099 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1100 if (image_info->interlace != PartitionInterlace)
1101 {
1102 /*
1103 Open output image file.
1104 */
1105 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1106 if (status == MagickFalse)
1107 return(status);
1108 }
1109 quantum_type=RGBQuantum;
cristy90dbac72010-08-22 15:08:40 +00001110 if (LocaleCompare(image_info->magick,"RGBA") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001111 {
cristy90dbac72010-08-22 15:08:40 +00001112 quantum_type=RGBAQuantum;
1113 image->matte=MagickTrue;
cristy3ed852e2009-09-05 21:47:34 +00001114 }
cristy90dbac72010-08-22 15:08:40 +00001115 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1116 {
1117 quantum_type=RGBOQuantum;
1118 image->matte=MagickTrue;
1119 }
cristy3ed852e2009-09-05 21:47:34 +00001120 scene=0;
1121 do
1122 {
1123 /*
1124 Convert MIFF to RGB raster pixels.
1125 */
1126 if (image->colorspace != RGBColorspace)
1127 (void) TransformImageColorspace(image,RGBColorspace);
1128 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1129 (image->matte == MagickFalse))
1130 (void) SetImageAlphaChannel(image,ResetAlphaChannel);
1131 quantum_info=AcquireQuantumInfo(image_info,image);
1132 if (quantum_info == (QuantumInfo *) NULL)
1133 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1134 pixels=GetQuantumPixels(quantum_info);
1135 switch (image_info->interlace)
1136 {
1137 case NoInterlace:
1138 default:
1139 {
cristy3ed852e2009-09-05 21:47:34 +00001140 /*
1141 No interlacing: RGBRGBRGBRGBRGBRGB...
1142 */
cristybb503372010-05-27 20:51:26 +00001143 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001144 {
cristy90dbac72010-08-22 15:08:40 +00001145 register const PixelPacket
1146 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001147
cristy90dbac72010-08-22 15:08:40 +00001148 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1149 if (p == (const PixelPacket *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001150 break;
cristy90dbac72010-08-22 15:08:40 +00001151 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1152 quantum_info,quantum_type,pixels,&image->exception);
cristy3ed852e2009-09-05 21:47:34 +00001153 count=WriteBlob(image,length,pixels);
1154 if (count != (ssize_t) length)
1155 break;
1156 if (image->previous == (Image *) NULL)
1157 {
cristycee97112010-05-28 00:44:52 +00001158 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1159 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001160 if (status == MagickFalse)
1161 break;
1162 }
1163 }
cristy3ed852e2009-09-05 21:47:34 +00001164 break;
1165 }
1166 case LineInterlace:
1167 {
1168 /*
1169 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1170 */
cristybb503372010-05-27 20:51:26 +00001171 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001172 {
1173 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001174 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001175
1176 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1177 if (p == (const PixelPacket *) NULL)
1178 break;
cristy90dbac72010-08-22 15:08:40 +00001179 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1180 quantum_info,RedQuantum,pixels,&image->exception);
1181 count=WriteBlob(image,length,pixels);
1182 if (count != (ssize_t) length)
1183 break;
1184 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1185 quantum_info,GreenQuantum,pixels,&image->exception);
1186 count=WriteBlob(image,length,pixels);
1187 if (count != (ssize_t) length)
1188 break;
1189 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1190 quantum_info,BlueQuantum,pixels,&image->exception);
1191 count=WriteBlob(image,length,pixels);
1192 if (count != (ssize_t) length)
1193 break;
1194 if (quantum_type == RGBAQuantum)
1195 {
1196 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1197 quantum_info,AlphaQuantum,pixels,&image->exception);
1198 count=WriteBlob(image,length,pixels);
1199 if (count != (ssize_t) length)
1200 break;
1201 }
1202 if (quantum_type == RGBOQuantum)
1203 {
1204 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1205 quantum_info,OpacityQuantum,pixels,&image->exception);
1206 count=WriteBlob(image,length,pixels);
1207 if (count != (ssize_t) length)
1208 break;
1209 }
cristy3ed852e2009-09-05 21:47:34 +00001210 if (image->previous == (Image *) NULL)
1211 {
cristycee97112010-05-28 00:44:52 +00001212 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1213 image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001214 if (status == MagickFalse)
1215 break;
1216 }
1217 }
1218 break;
1219 }
1220 case PlaneInterlace:
1221 {
1222 /*
1223 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1224 */
cristy90dbac72010-08-22 15:08:40 +00001225 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001226 {
cristy90dbac72010-08-22 15:08:40 +00001227 register const PixelPacket
1228 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001229
cristy90dbac72010-08-22 15:08:40 +00001230 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1231 if (p == (const PixelPacket *) NULL)
1232 break;
1233 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1234 quantum_info,RedQuantum,pixels,&image->exception);
1235 count=WriteBlob(image,length,pixels);
1236 if (count != (ssize_t) length)
1237 break;
cristy3ed852e2009-09-05 21:47:34 +00001238 }
1239 if (image->previous == (Image *) NULL)
1240 {
cristy90dbac72010-08-22 15:08:40 +00001241 status=SetImageProgress(image,SaveImageTag,1,6);
1242 if (status == MagickFalse)
1243 break;
1244 }
1245 for (y=0; y < (ssize_t) image->rows; y++)
1246 {
1247 register const PixelPacket
1248 *restrict p;
1249
1250 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1251 if (p == (const PixelPacket *) NULL)
1252 break;
1253 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1254 quantum_info,GreenQuantum,pixels,&image->exception);
1255 count=WriteBlob(image,length,pixels);
1256 if (count != (ssize_t) length)
1257 break;
1258 }
1259 if (image->previous == (Image *) NULL)
1260 {
1261 status=SetImageProgress(image,SaveImageTag,2,6);
1262 if (status == MagickFalse)
1263 break;
1264 }
1265 for (y=0; y < (ssize_t) image->rows; y++)
1266 {
1267 register const PixelPacket
1268 *restrict p;
1269
1270 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1271 if (p == (const PixelPacket *) NULL)
1272 break;
1273 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1274 quantum_info,BlueQuantum,pixels,&image->exception);
1275 count=WriteBlob(image,length,pixels);
1276 if (count != (ssize_t) length)
1277 break;
1278 }
1279 if (image->previous == (Image *) NULL)
1280 {
1281 status=SetImageProgress(image,SaveImageTag,3,6);
1282 if (status == MagickFalse)
1283 break;
1284 }
1285 if (quantum_type == RGBAQuantum)
1286 {
1287 for (y=0; y < (ssize_t) image->rows; y++)
1288 {
1289 register const PixelPacket
1290 *restrict p;
1291
1292 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1293 if (p == (const PixelPacket *) NULL)
1294 break;
1295 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1296 quantum_info,AlphaQuantum,pixels,&image->exception);
1297 count=WriteBlob(image,length,pixels);
1298 if (count != (ssize_t) length)
1299 break;
1300 }
1301 if (image->previous == (Image *) NULL)
1302 {
1303 status=SetImageProgress(image,SaveImageTag,5,6);
1304 if (status == MagickFalse)
1305 break;
1306 }
1307 }
1308 if (image_info->interlace == PartitionInterlace)
1309 (void) CopyMagickString(image->filename,image_info->filename,
1310 MaxTextExtent);
1311 if (image->previous == (Image *) NULL)
1312 {
1313 status=SetImageProgress(image,SaveImageTag,6,6);
cristy3ed852e2009-09-05 21:47:34 +00001314 if (status == MagickFalse)
1315 break;
1316 }
1317 break;
1318 }
1319 case PartitionInterlace:
1320 {
cristy3ed852e2009-09-05 21:47:34 +00001321 /*
1322 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1323 */
cristy90dbac72010-08-22 15:08:40 +00001324 AppendImageFormat("R",image->filename);
1325 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1326 AppendBinaryBlobMode,&image->exception);
1327 if (status == MagickFalse)
1328 return(status);
1329 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001330 {
cristy90dbac72010-08-22 15:08:40 +00001331 register const PixelPacket
1332 *restrict p;
cristy3ed852e2009-09-05 21:47:34 +00001333
cristy90dbac72010-08-22 15:08:40 +00001334 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1335 if (p == (const PixelPacket *) NULL)
1336 break;
1337 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1338 quantum_info,RedQuantum,pixels,&image->exception);
1339 count=WriteBlob(image,length,pixels);
1340 if (count != (ssize_t) length)
1341 break;
1342 }
1343 if (image->previous == (Image *) NULL)
1344 {
1345 status=SetImageProgress(image,SaveImageTag,1,6);
1346 if (status == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00001347 break;
1348 }
cristy90dbac72010-08-22 15:08:40 +00001349 (void) CloseBlob(image);
1350 AppendImageFormat("G",image->filename);
1351 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1352 AppendBinaryBlobMode,&image->exception);
1353 if (status == MagickFalse)
1354 return(status);
1355 for (y=0; y < (ssize_t) image->rows; y++)
1356 {
1357 register const PixelPacket
1358 *restrict p;
1359
1360 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1361 if (p == (const PixelPacket *) NULL)
1362 break;
1363 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1364 quantum_info,GreenQuantum,pixels,&image->exception);
1365 count=WriteBlob(image,length,pixels);
1366 if (count != (ssize_t) length)
1367 break;
1368 }
1369 if (image->previous == (Image *) NULL)
1370 {
1371 status=SetImageProgress(image,SaveImageTag,2,6);
1372 if (status == MagickFalse)
1373 break;
1374 }
1375 (void) CloseBlob(image);
1376 AppendImageFormat("B",image->filename);
1377 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1378 AppendBinaryBlobMode,&image->exception);
1379 if (status == MagickFalse)
1380 return(status);
1381 for (y=0; y < (ssize_t) image->rows; y++)
1382 {
1383 register const PixelPacket
1384 *restrict p;
1385
1386 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1387 if (p == (const PixelPacket *) NULL)
1388 break;
1389 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1390 quantum_info,BlueQuantum,pixels,&image->exception);
1391 count=WriteBlob(image,length,pixels);
1392 if (count != (ssize_t) length)
1393 break;
1394 }
1395 if (image->previous == (Image *) NULL)
1396 {
1397 status=SetImageProgress(image,SaveImageTag,3,6);
1398 if (status == MagickFalse)
1399 break;
1400 }
1401 (void) CloseBlob(image);
1402 if (quantum_type == RGBAQuantum)
1403 {
1404 (void) CloseBlob(image);
1405 AppendImageFormat("A",image->filename);
1406 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1407 AppendBinaryBlobMode,&image->exception);
1408 if (status == MagickFalse)
1409 return(status);
1410 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +00001411 {
cristy90dbac72010-08-22 15:08:40 +00001412 register const PixelPacket
1413 *restrict p;
1414
1415 p=GetVirtualPixels(image,0,y,image->columns,1,
1416 &image->exception);
1417 if (p == (const PixelPacket *) NULL)
1418 break;
1419 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1420 quantum_info,AlphaQuantum,pixels,&image->exception);
1421 count=WriteBlob(image,length,pixels);
1422 if (count != (ssize_t) length)
cristy3ed852e2009-09-05 21:47:34 +00001423 break;
1424 }
cristy90dbac72010-08-22 15:08:40 +00001425 if (image->previous == (Image *) NULL)
1426 {
1427 status=SetImageProgress(image,SaveImageTag,5,6);
1428 if (status == MagickFalse)
1429 break;
1430 }
1431 }
1432 (void) CloseBlob(image);
cristy3ed852e2009-09-05 21:47:34 +00001433 (void) CopyMagickString(image->filename,image_info->filename,
1434 MaxTextExtent);
1435 if (image->previous == (Image *) NULL)
1436 {
cristy90dbac72010-08-22 15:08:40 +00001437 status=SetImageProgress(image,SaveImageTag,6,6);
cristy3ed852e2009-09-05 21:47:34 +00001438 if (status == MagickFalse)
1439 break;
1440 }
1441 break;
1442 }
1443 }
1444 quantum_info=DestroyQuantumInfo(quantum_info);
1445 if (GetNextImageInList(image) == (Image *) NULL)
1446 break;
1447 image=SyncNextImageInList(image);
1448 status=SetImageProgress(image,SaveImagesTag,scene++,
1449 GetImageListLength(image));
1450 if (status == MagickFalse)
1451 break;
1452 } while (image_info->adjoin != MagickFalse);
1453 (void) CloseBlob(image);
1454 return(MagickTrue);
1455}