1 /*
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 % Cristy %
17 % July 1992 %
18 % %
19 % %
20 % Copyright 1999-2019 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 Include declarations.
41 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/cache.h"
46 #include "MagickCore/channel.h"
47 #include "MagickCore/colorspace.h"
48 #include "MagickCore/colorspace-private.h"
49 #include "MagickCore/constitute.h"
50 #include "MagickCore/exception.h"
51 #include "MagickCore/exception-private.h"
52 #include "MagickCore/image.h"
53 #include "MagickCore/image-private.h"
54 #include "MagickCore/list.h"
55 #include "MagickCore/magick.h"
56 #include "MagickCore/memory_.h"
57 #include "MagickCore/monitor.h"
58 #include "MagickCore/monitor-private.h"
59 #include "MagickCore/pixel-accessor.h"
60 #include "MagickCore/quantum-private.h"
61 #include "MagickCore/static.h"
62 #include "MagickCore/statistic.h"
63 #include "MagickCore/string_.h"
64 #include "MagickCore/module.h"
65 #include "MagickCore/utility.h"
66
67 /*
68 Forward declarations.
69 */
70 static MagickBooleanType
71 WriteRGBImage(const ImageInfo *,Image *,ExceptionInfo *);
72
73 /*
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75 % %
76 % %
77 % %
78 % R e a d R G B I m a g e %
79 % %
80 % %
81 % %
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 %
84 % ReadRGBImage() reads an image of raw RGB, RGBA, or RGBO samples and returns
85 % it. It allocates the memory necessary for the new Image structure and
86 % returns a pointer to the new image.
87 %
88 % The format of the ReadRGBImage method is:
89 %
90 % Image *ReadRGBImage(const ImageInfo *image_info,
91 % ExceptionInfo *exception)
92 %
93 % A description of each parameter follows:
94 %
95 % o image_info: the image info.
96 %
97 % o exception: return any errors or warnings in this structure.
98 %
99 */
ReadRGBImage(const ImageInfo * image_info,ExceptionInfo * exception)100 static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception)
101 {
102 const unsigned char
103 *pixels;
104
105 Image
106 *canvas_image,
107 *image;
108
109 MagickBooleanType
110 status;
111
112 MagickOffsetType
113 scene;
114
115 QuantumInfo
116 *quantum_info;
117
118 QuantumType
119 quantum_type;
120
121 register ssize_t
122 i;
123
124 size_t
125 length;
126
127 ssize_t
128 count,
129 y;
130
131 /*
132 Open image file.
133 */
134 assert(image_info != (const ImageInfo *) NULL);
135 assert(image_info->signature == MagickCoreSignature);
136 if (image_info->debug != MagickFalse)
137 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
138 image_info->filename);
139 assert(exception != (ExceptionInfo *) NULL);
140 assert(exception->signature == MagickCoreSignature);
141 image=AcquireImage(image_info,exception);
142 if ((image->columns == 0) || (image->rows == 0))
143 ThrowReaderException(OptionError,"MustSpecifyImageSize");
144 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 }
152 if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
153 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
154 image->filename);
155 }
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 if(canvas_image == (Image *) NULL)
162 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
163 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
164 exception);
165 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
166 if (quantum_info == (QuantumInfo *) NULL)
167 {
168 canvas_image=DestroyImage(canvas_image);
169 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
170 }
171 quantum_type=RGBQuantum;
172 if (LocaleCompare(image_info->magick,"RGBA") == 0)
173 {
174 quantum_type=RGBAQuantum;
175 image->alpha_trait=BlendPixelTrait;
176 canvas_image->alpha_trait=BlendPixelTrait;
177 }
178 if (LocaleCompare(image_info->magick,"RGBO") == 0)
179 {
180 quantum_type=RGBOQuantum;
181 image->alpha_trait=BlendPixelTrait;
182 canvas_image->alpha_trait=BlendPixelTrait;
183 }
184 pixels=(const unsigned char *) NULL;
185 if (image_info->number_scenes != 0)
186 while (image->scene < image_info->scene)
187 {
188 /*
189 Skip to next image.
190 */
191 image->scene++;
192 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
193 for (y=0; y < (ssize_t) image->rows; y++)
194 {
195 pixels=(const unsigned char *) ReadBlobStream(image,length,
196 GetQuantumPixels(quantum_info),&count);
197 if (count != (ssize_t) length)
198 break;
199 }
200 }
201 count=0;
202 length=0;
203 scene=0;
204 status=MagickTrue;
205 do
206 {
207 /*
208 Read pixels to virtual canvas image then push to image.
209 */
210 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
211 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
212 break;
213 status=SetImageExtent(image,image->columns,image->rows,exception);
214 if (status == MagickFalse)
215 break;
216 switch (image_info->interlace)
217 {
218 case NoInterlace:
219 default:
220 {
221 /*
222 No interlacing: RGBRGBRGBRGBRGBRGB...
223 */
224 if (scene == 0)
225 {
226 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
227 pixels=(const unsigned char *) ReadBlobStream(image,length,
228 GetQuantumPixels(quantum_info),&count);
229 }
230 for (y=0; y < (ssize_t) image->extract_info.height; y++)
231 {
232 register const Quantum
233 *magick_restrict p;
234
235 register Quantum
236 *magick_restrict q;
237
238 register ssize_t
239 x;
240
241 if (count != (ssize_t) length)
242 {
243 status=MagickFalse;
244 ThrowFileException(exception,CorruptImageError,
245 "UnexpectedEndOfFile",image->filename);
246 break;
247 }
248 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
249 exception);
250 if (q == (Quantum *) NULL)
251 break;
252 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
253 quantum_info,quantum_type,pixels,exception);
254 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
255 break;
256 if (((y-image->extract_info.y) >= 0) &&
257 ((y-image->extract_info.y) < (ssize_t) image->rows))
258 {
259 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
260 canvas_image->columns,1,exception);
261 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
262 image->columns,1,exception);
263 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
264 break;
265 for (x=0; x < (ssize_t) image->columns; x++)
266 {
267 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
268 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
269 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
270 SetPixelAlpha(image,OpaqueAlpha,q);
271 if (image->alpha_trait != UndefinedPixelTrait)
272 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
273 p+=GetPixelChannels(canvas_image);
274 q+=GetPixelChannels(image);
275 }
276 if (SyncAuthenticPixels(image,exception) == MagickFalse)
277 break;
278 }
279 if (image->previous == (Image *) NULL)
280 {
281 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
282 image->rows);
283 if (status == MagickFalse)
284 break;
285 }
286 pixels=(const unsigned char *) ReadBlobStream(image,length,
287 GetQuantumPixels(quantum_info),&count);
288 }
289 break;
290 }
291 case LineInterlace:
292 {
293 static QuantumType
294 quantum_types[4] =
295 {
296 RedQuantum,
297 GreenQuantum,
298 BlueQuantum,
299 AlphaQuantum
300 };
301
302 /*
303 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
304 */
305 if (LocaleCompare(image_info->magick,"RGBO") == 0)
306 quantum_types[3]=OpacityQuantum;
307 if (scene == 0)
308 {
309 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
310 pixels=(const unsigned char *) ReadBlobStream(image,length,
311 GetQuantumPixels(quantum_info),&count);
312 }
313 for (y=0; y < (ssize_t) image->extract_info.height; y++)
314 {
315 for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 4 : 3); i++)
316 {
317 register const Quantum
318 *magick_restrict p;
319
320 register Quantum
321 *magick_restrict q;
322
323 register ssize_t
324 x;
325
326 if (count != (ssize_t) length)
327 {
328 status=MagickFalse;
329 ThrowFileException(exception,CorruptImageError,
330 "UnexpectedEndOfFile",image->filename);
331 break;
332 }
333 quantum_type=quantum_types[i];
334 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
335 exception);
336 if (q == (Quantum *) NULL)
337 break;
338 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
339 quantum_info,quantum_type,pixels,exception);
340 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
341 break;
342 if (((y-image->extract_info.y) >= 0) &&
343 ((y-image->extract_info.y) < (ssize_t) image->rows))
344 {
345 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
346 0,canvas_image->columns,1,exception);
347 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
348 image->columns,1,exception);
349 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
350 break;
351 for (x=0; x < (ssize_t) image->columns; x++)
352 {
353 switch (quantum_type)
354 {
355 case RedQuantum:
356 {
357 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
358 break;
359 }
360 case GreenQuantum:
361 {
362 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
363 break;
364 }
365 case BlueQuantum:
366 {
367 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
368 break;
369 }
370 case OpacityQuantum:
371 {
372 SetPixelOpacity(image,GetPixelOpacity(canvas_image,p),q);
373 break;
374 }
375 case AlphaQuantum:
376 {
377 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
378 break;
379 }
380 default:
381 break;
382 }
383 p+=GetPixelChannels(canvas_image);
384 q+=GetPixelChannels(image);
385 }
386 if (SyncAuthenticPixels(image,exception) == MagickFalse)
387 break;
388 }
389 pixels=(const unsigned char *) ReadBlobStream(image,length,
390 GetQuantumPixels(quantum_info),&count);
391 }
392 if (image->previous == (Image *) NULL)
393 {
394 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
395 image->rows);
396 if (status == MagickFalse)
397 break;
398 }
399 }
400 break;
401 }
402 case PlaneInterlace:
403 {
404 /*
405 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
406 */
407 if (scene == 0)
408 {
409 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
410 pixels=(const unsigned char *) ReadBlobStream(image,length,
411 GetQuantumPixels(quantum_info),&count);
412 }
413 for (y=0; y < (ssize_t) image->extract_info.height; y++)
414 {
415 register const Quantum
416 *magick_restrict p;
417
418 register Quantum
419 *magick_restrict q;
420
421 register ssize_t
422 x;
423
424 if (count != (ssize_t) length)
425 {
426 status=MagickFalse;
427 ThrowFileException(exception,CorruptImageError,
428 "UnexpectedEndOfFile",image->filename);
429 break;
430 }
431 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
432 exception);
433 if (q == (Quantum *) NULL)
434 break;
435 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
436 quantum_info,RedQuantum,pixels,exception);
437 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
438 break;
439 if (((y-image->extract_info.y) >= 0) &&
440 ((y-image->extract_info.y) < (ssize_t) image->rows))
441 {
442 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
443 canvas_image->columns,1,exception);
444 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
445 image->columns,1,exception);
446 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
447 break;
448 for (x=0; x < (ssize_t) image->columns; x++)
449 {
450 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
451 p+=GetPixelChannels(canvas_image);
452 q+=GetPixelChannels(image);
453 }
454 if (SyncAuthenticPixels(image,exception) == MagickFalse)
455 break;
456 }
457 pixels=(const unsigned char *) ReadBlobStream(image,length,
458 GetQuantumPixels(quantum_info),&count);
459 }
460 if (image->previous == (Image *) NULL)
461 {
462 status=SetImageProgress(image,LoadImageTag,1,6);
463 if (status == MagickFalse)
464 break;
465 }
466 for (y=0; y < (ssize_t) image->extract_info.height; y++)
467 {
468 register const Quantum
469 *magick_restrict p;
470
471 register Quantum
472 *magick_restrict q;
473
474 register ssize_t
475 x;
476
477 if (count != (ssize_t) length)
478 {
479 status=MagickFalse;
480 ThrowFileException(exception,CorruptImageError,
481 "UnexpectedEndOfFile",image->filename);
482 break;
483 }
484 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
485 exception);
486 if (q == (Quantum *) NULL)
487 break;
488 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
489 quantum_info,GreenQuantum,pixels,exception);
490 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
491 break;
492 if (((y-image->extract_info.y) >= 0) &&
493 ((y-image->extract_info.y) < (ssize_t) image->rows))
494 {
495 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
496 canvas_image->columns,1,exception);
497 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
498 image->columns,1,exception);
499 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
500 break;
501 for (x=0; x < (ssize_t) image->columns; x++)
502 {
503 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
504 p+=GetPixelChannels(canvas_image);
505 q+=GetPixelChannels(image);
506 }
507 if (SyncAuthenticPixels(image,exception) == MagickFalse)
508 break;
509 }
510 pixels=(const unsigned char *) ReadBlobStream(image,length,
511 GetQuantumPixels(quantum_info),&count);
512 }
513 if (image->previous == (Image *) NULL)
514 {
515 status=SetImageProgress(image,LoadImageTag,2,6);
516 if (status == MagickFalse)
517 break;
518 }
519 for (y=0; y < (ssize_t) image->extract_info.height; y++)
520 {
521 register const Quantum
522 *magick_restrict p;
523
524 register Quantum
525 *magick_restrict q;
526
527 register ssize_t
528 x;
529
530 if (count != (ssize_t) length)
531 {
532 status=MagickFalse;
533 ThrowFileException(exception,CorruptImageError,
534 "UnexpectedEndOfFile",image->filename);
535 break;
536 }
537 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
538 exception);
539 if (q == (Quantum *) NULL)
540 break;
541 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
542 quantum_info,BlueQuantum,pixels,exception);
543 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
544 break;
545 if (((y-image->extract_info.y) >= 0) &&
546 ((y-image->extract_info.y) < (ssize_t) image->rows))
547 {
548 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
549 canvas_image->columns,1,exception);
550 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
551 image->columns,1,exception);
552 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
553 break;
554 for (x=0; x < (ssize_t) image->columns; x++)
555 {
556 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
557 p+=GetPixelChannels(canvas_image);
558 q+=GetPixelChannels(image);
559 }
560 if (SyncAuthenticPixels(image,exception) == MagickFalse)
561 break;
562 }
563 pixels=(const unsigned char *) ReadBlobStream(image,length,
564 GetQuantumPixels(quantum_info),&count);
565 }
566 if (image->previous == (Image *) NULL)
567 {
568 status=SetImageProgress(image,LoadImageTag,4,6);
569 if (status == MagickFalse)
570 break;
571 }
572 if (image->alpha_trait != UndefinedPixelTrait)
573 {
574 for (y=0; y < (ssize_t) image->extract_info.height; y++)
575 {
576 register const Quantum
577 *magick_restrict p;
578
579 register Quantum
580 *magick_restrict q;
581
582 register ssize_t
583 x;
584
585 if (count != (ssize_t) length)
586 {
587 status=MagickFalse;
588 ThrowFileException(exception,CorruptImageError,
589 "UnexpectedEndOfFile",image->filename);
590 break;
591 }
592 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
593 exception);
594 if (q == (Quantum *) NULL)
595 break;
596 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
597 quantum_info,AlphaQuantum,pixels,exception);
598 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
599 break;
600 if (((y-image->extract_info.y) >= 0) &&
601 ((y-image->extract_info.y) < (ssize_t) image->rows))
602 {
603 p=GetVirtualPixels(canvas_image,
604 canvas_image->extract_info.x,0,canvas_image->columns,1,
605 exception);
606 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
607 image->columns,1,exception);
608 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
609 break;
610 for (x=0; x < (ssize_t) image->columns; x++)
611 {
612 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
613 p+=GetPixelChannels(canvas_image);
614 q+=GetPixelChannels(image);
615 }
616 if (SyncAuthenticPixels(image,exception) == MagickFalse)
617 break;
618 }
619 pixels=(const unsigned char *) ReadBlobStream(image,length,
620 GetQuantumPixels(quantum_info),&count);
621 }
622 if (image->previous == (Image *) NULL)
623 {
624 status=SetImageProgress(image,LoadImageTag,5,6);
625 if (status == MagickFalse)
626 break;
627 }
628 }
629 if (image->previous == (Image *) NULL)
630 {
631 status=SetImageProgress(image,LoadImageTag,6,6);
632 if (status == MagickFalse)
633 break;
634 }
635 break;
636 }
637 case PartitionInterlace:
638 {
639 /*
640 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
641 */
642 AppendImageFormat("R",image->filename);
643 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
644 if (status == MagickFalse)
645 break;
646 if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
647 {
648 status=MagickFalse;
649 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
650 image->filename);
651 break;
652 }
653 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
654 for (i=0; i < (ssize_t) scene; i++)
655 {
656 for (y=0; y < (ssize_t) image->extract_info.height; y++)
657 {
658 pixels=(const unsigned char *) ReadBlobStream(image,length,
659 GetQuantumPixels(quantum_info),&count);
660 if (count != (ssize_t) length)
661 break;
662 }
663 if (count != (ssize_t) length)
664 break;
665 }
666 pixels=(const unsigned char *) ReadBlobStream(image,length,
667 GetQuantumPixels(quantum_info),&count);
668 for (y=0; y < (ssize_t) image->extract_info.height; y++)
669 {
670 register const Quantum
671 *magick_restrict p;
672
673 register Quantum
674 *magick_restrict q;
675
676 register ssize_t
677 x;
678
679 if (count != (ssize_t) length)
680 {
681 status=MagickFalse;
682 ThrowFileException(exception,CorruptImageError,
683 "UnexpectedEndOfFile",image->filename);
684 break;
685 }
686 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
687 exception);
688 if (q == (Quantum *) NULL)
689 break;
690 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
691 quantum_info,RedQuantum,pixels,exception);
692 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
693 break;
694 if (((y-image->extract_info.y) >= 0) &&
695 ((y-image->extract_info.y) < (ssize_t) image->rows))
696 {
697 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
698 canvas_image->columns,1,exception);
699 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
700 image->columns,1,exception);
701 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
702 break;
703 for (x=0; x < (ssize_t) image->columns; x++)
704 {
705 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
706 p+=GetPixelChannels(canvas_image);
707 q+=GetPixelChannels(image);
708 }
709 if (SyncAuthenticPixels(image,exception) == MagickFalse)
710 break;
711 }
712 pixels=(const unsigned char *) ReadBlobStream(image,length,
713 GetQuantumPixels(quantum_info),&count);
714 }
715 if (image->previous == (Image *) NULL)
716 {
717 status=SetImageProgress(image,LoadImageTag,1,5);
718 if (status == MagickFalse)
719 break;
720 }
721 (void) CloseBlob(image);
722 AppendImageFormat("G",image->filename);
723 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
724 if (status == MagickFalse)
725 break;
726 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
727 for (i=0; i < (ssize_t) scene; i++)
728 {
729 for (y=0; y < (ssize_t) image->extract_info.height; y++)
730 {
731 pixels=(const unsigned char *) ReadBlobStream(image,length,
732 GetQuantumPixels(quantum_info),&count);
733 if (count != (ssize_t) length)
734 break;
735 }
736 if (count != (ssize_t) length)
737 break;
738 }
739 pixels=(const unsigned char *) ReadBlobStream(image,length,
740 GetQuantumPixels(quantum_info),&count);
741 for (y=0; y < (ssize_t) image->extract_info.height; y++)
742 {
743 register const Quantum
744 *magick_restrict p;
745
746 register Quantum
747 *magick_restrict q;
748
749 register ssize_t
750 x;
751
752 if (count != (ssize_t) length)
753 {
754 status=MagickFalse;
755 ThrowFileException(exception,CorruptImageError,
756 "UnexpectedEndOfFile",image->filename);
757 break;
758 }
759 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
760 exception);
761 if (q == (Quantum *) NULL)
762 break;
763 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
764 quantum_info,GreenQuantum,pixels,exception);
765 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
766 break;
767 if (((y-image->extract_info.y) >= 0) &&
768 ((y-image->extract_info.y) < (ssize_t) image->rows))
769 {
770 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
771 canvas_image->columns,1,exception);
772 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
773 image->columns,1,exception);
774 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
775 break;
776 for (x=0; x < (ssize_t) image->columns; x++)
777 {
778 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
779 p+=GetPixelChannels(canvas_image);
780 q+=GetPixelChannels(image);
781 }
782 if (SyncAuthenticPixels(image,exception) == MagickFalse)
783 break;
784 }
785 pixels=(const unsigned char *) ReadBlobStream(image,length,
786 GetQuantumPixels(quantum_info),&count);
787 }
788 if (image->previous == (Image *) NULL)
789 {
790 status=SetImageProgress(image,LoadImageTag,2,5);
791 if (status == MagickFalse)
792 break;
793 }
794 (void) CloseBlob(image);
795 AppendImageFormat("B",image->filename);
796 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
797 if (status == MagickFalse)
798 break;
799 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
800 for (i=0; i < (ssize_t) scene; i++)
801 {
802 for (y=0; y < (ssize_t) image->extract_info.height; y++)
803 {
804 pixels=(const unsigned char *) ReadBlobStream(image,length,
805 GetQuantumPixels(quantum_info),&count);
806 if (count != (ssize_t) length)
807 break;
808 }
809 if (count != (ssize_t) length)
810 break;
811 }
812 pixels=(const unsigned char *) ReadBlobStream(image,length,
813 GetQuantumPixels(quantum_info),&count);
814 for (y=0; y < (ssize_t) image->extract_info.height; y++)
815 {
816 register const Quantum
817 *magick_restrict p;
818
819 register Quantum
820 *magick_restrict q;
821
822 register ssize_t
823 x;
824
825 if (count != (ssize_t) length)
826 {
827 status=MagickFalse;
828 ThrowFileException(exception,CorruptImageError,
829 "UnexpectedEndOfFile",image->filename);
830 break;
831 }
832 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
833 exception);
834 if (q == (Quantum *) NULL)
835 break;
836 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
837 quantum_info,BlueQuantum,pixels,exception);
838 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
839 break;
840 if (((y-image->extract_info.y) >= 0) &&
841 ((y-image->extract_info.y) < (ssize_t) image->rows))
842 {
843 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
844 canvas_image->columns,1,exception);
845 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
846 image->columns,1,exception);
847 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
848 break;
849 for (x=0; x < (ssize_t) image->columns; x++)
850 {
851 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
852 p+=GetPixelChannels(canvas_image);
853 q+=GetPixelChannels(image);
854 }
855 if (SyncAuthenticPixels(image,exception) == MagickFalse)
856 break;
857 }
858 pixels=(const unsigned char *) ReadBlobStream(image,length,
859 GetQuantumPixels(quantum_info),&count);
860 }
861 if (image->previous == (Image *) NULL)
862 {
863 status=SetImageProgress(image,LoadImageTag,3,5);
864 if (status == MagickFalse)
865 break;
866 }
867 if (image->alpha_trait != UndefinedPixelTrait)
868 {
869 (void) CloseBlob(image);
870 AppendImageFormat("A",image->filename);
871 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
872 if (status == MagickFalse)
873 break;
874 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
875 for (i=0; i < (ssize_t) scene; i++)
876 {
877 for (y=0; y < (ssize_t) image->extract_info.height; y++)
878 {
879 pixels=(const unsigned char *) ReadBlobStream(image,length,
880 GetQuantumPixels(quantum_info),&count);
881 if (count != (ssize_t) length)
882 break;
883 }
884 if (count != (ssize_t) length)
885 break;
886 }
887 pixels=(const unsigned char *) ReadBlobStream(image,length,
888 GetQuantumPixels(quantum_info),&count);
889 for (y=0; y < (ssize_t) image->extract_info.height; y++)
890 {
891 register const Quantum
892 *magick_restrict p;
893
894 register Quantum
895 *magick_restrict q;
896
897 register ssize_t
898 x;
899
900 if (count != (ssize_t) length)
901 {
902 status=MagickFalse;
903 ThrowFileException(exception,CorruptImageError,
904 "UnexpectedEndOfFile",image->filename);
905 break;
906 }
907 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
908 exception);
909 if (q == (Quantum *) NULL)
910 break;
911 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
912 quantum_info,BlueQuantum,pixels,exception);
913 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
914 break;
915 if (((y-image->extract_info.y) >= 0) &&
916 ((y-image->extract_info.y) < (ssize_t) image->rows))
917 {
918 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
919 0,canvas_image->columns,1,exception);
920 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
921 image->columns,1,exception);
922 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
923 break;
924 for (x=0; x < (ssize_t) image->columns; x++)
925 {
926 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
927 p+=GetPixelChannels(canvas_image);
928 q+=GetPixelChannels(image);
929 }
930 if (SyncAuthenticPixels(image,exception) == MagickFalse)
931 break;
932 }
933 pixels=(const unsigned char *) ReadBlobStream(image,length,
934 GetQuantumPixels(quantum_info),&count);
935 }
936 if (image->previous == (Image *) NULL)
937 {
938 status=SetImageProgress(image,LoadImageTag,4,5);
939 if (status == MagickFalse)
940 break;
941 }
942 }
943 (void) CloseBlob(image);
944 if (image->previous == (Image *) NULL)
945 {
946 status=SetImageProgress(image,LoadImageTag,5,5);
947 if (status == MagickFalse)
948 break;
949 }
950 break;
951 }
952 }
953 if (status == MagickFalse)
954 break;
955 SetQuantumImageType(image,quantum_type);
956 /*
957 Proceed to next image.
958 */
959 if (image_info->number_scenes != 0)
960 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
961 break;
962 if (count == (ssize_t) length)
963 {
964 /*
965 Allocate next image structure.
966 */
967 AcquireNextImage(image_info,image,exception);
968 if (GetNextImageInList(image) == (Image *) NULL)
969 {
970 status=MagickFalse;
971 break;
972 }
973 image=SyncNextImageInList(image);
974 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
975 GetBlobSize(image));
976 if (status == MagickFalse)
977 break;
978 }
979 scene++;
980 } while (count == (ssize_t) length);
981 quantum_info=DestroyQuantumInfo(quantum_info);
982 canvas_image=DestroyImage(canvas_image);
983 (void) CloseBlob(image);
984 if (status == MagickFalse)
985 return(DestroyImageList(image));
986 return(GetFirstImageInList(image));
987 }
988
989 /*
990 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
991 % %
992 % %
993 % %
994 % R e g i s t e r R G B I m a g e %
995 % %
996 % %
997 % %
998 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
999 %
1000 % RegisterRGBImage() adds attributes for the RGB image format to
1001 % the list of supported formats. The attributes include the image format
1002 % tag, a method to read and/or write the format, whether the format
1003 % supports the saving of more than one frame to the same file or blob,
1004 % whether the format supports native in-memory I/O, and a brief
1005 % description of the format.
1006 %
1007 % The format of the RegisterRGBImage method is:
1008 %
1009 % size_t RegisterRGBImage(void)
1010 %
1011 */
RegisterRGBImage(void)1012 ModuleExport size_t RegisterRGBImage(void)
1013 {
1014 MagickInfo
1015 *entry;
1016
1017 entry=AcquireMagickInfo("RGB","RGB",
1018 "Raw red, green, and blue samples");
1019 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1020 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1021 entry->flags|=CoderRawSupportFlag;
1022 entry->flags|=CoderEndianSupportFlag;
1023 (void) RegisterMagickInfo(entry);
1024 entry=AcquireMagickInfo("RGB","RGBA",
1025 "Raw red, green, blue, and alpha samples");
1026 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1027 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1028 entry->flags|=CoderRawSupportFlag;
1029 entry->flags|=CoderEndianSupportFlag;
1030 (void) RegisterMagickInfo(entry);
1031 entry=AcquireMagickInfo("RGB","RGBO",
1032 "Raw red, green, blue, and opacity samples");
1033 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1034 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1035 entry->flags|=CoderRawSupportFlag;
1036 entry->flags|=CoderEndianSupportFlag;
1037 (void) RegisterMagickInfo(entry);
1038 return(MagickImageCoderSignature);
1039 }
1040
1041 /*
1042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1043 % %
1044 % %
1045 % %
1046 % U n r e g i s t e r R G B I m a g e %
1047 % %
1048 % %
1049 % %
1050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1051 %
1052 % UnregisterRGBImage() removes format registrations made by the RGB module
1053 % from the list of supported formats.
1054 %
1055 % The format of the UnregisterRGBImage method is:
1056 %
1057 % UnregisterRGBImage(void)
1058 %
1059 */
UnregisterRGBImage(void)1060 ModuleExport void UnregisterRGBImage(void)
1061 {
1062 (void) UnregisterMagickInfo("RGBO");
1063 (void) UnregisterMagickInfo("RGBA");
1064 (void) UnregisterMagickInfo("RGB");
1065 }
1066
1067 /*
1068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1069 % %
1070 % %
1071 % %
1072 % W r i t e R G B I m a g e %
1073 % %
1074 % %
1075 % %
1076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1077 %
1078 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1079 % rasterfile format.
1080 %
1081 % The format of the WriteRGBImage method is:
1082 %
1083 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1084 % Image *image,ExceptionInfo *exception)
1085 %
1086 % A description of each parameter follows.
1087 %
1088 % o image_info: the image info.
1089 %
1090 % o image: The image.
1091 %
1092 % o exception: return any errors or warnings in this structure.
1093 %
1094 */
WriteRGBImage(const ImageInfo * image_info,Image * image,ExceptionInfo * exception)1095 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1096 Image *image,ExceptionInfo *exception)
1097 {
1098 MagickBooleanType
1099 status;
1100
1101 MagickOffsetType
1102 scene;
1103
1104 QuantumInfo
1105 *quantum_info;
1106
1107 QuantumType
1108 quantum_type;
1109
1110 size_t
1111 imageListLength,
1112 length;
1113
1114 ssize_t
1115 count,
1116 y;
1117
1118 unsigned char
1119 *pixels;
1120
1121 /*
1122 Allocate memory for pixels.
1123 */
1124 assert(image_info != (const ImageInfo *) NULL);
1125 assert(image_info->signature == MagickCoreSignature);
1126 assert(image != (Image *) NULL);
1127 assert(image->signature == MagickCoreSignature);
1128 if (image->debug != MagickFalse)
1129 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1130 if (image_info->interlace != PartitionInterlace)
1131 {
1132 /*
1133 Open output image file.
1134 */
1135 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1136 if (status == MagickFalse)
1137 return(status);
1138 }
1139 quantum_type=RGBQuantum;
1140 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1141 quantum_type=RGBAQuantum;
1142 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1143 quantum_type=RGBOQuantum;
1144 scene=0;
1145 imageListLength=GetImageListLength(image);
1146 do
1147 {
1148 /*
1149 Convert MIFF to RGB raster pixels.
1150 */
1151 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1152 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1153 (image->alpha_trait == UndefinedPixelTrait))
1154 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1155 quantum_info=AcquireQuantumInfo(image_info,image);
1156 if (quantum_info == (QuantumInfo *) NULL)
1157 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1158 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
1159 switch (image_info->interlace)
1160 {
1161 case NoInterlace:
1162 default:
1163 {
1164 /*
1165 No interlacing: RGBRGBRGBRGBRGBRGB...
1166 */
1167 for (y=0; y < (ssize_t) image->rows; y++)
1168 {
1169 register const Quantum
1170 *magick_restrict p;
1171
1172 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1173 if (p == (const Quantum *) NULL)
1174 break;
1175 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1176 quantum_type,pixels,exception);
1177 count=WriteBlob(image,length,pixels);
1178 if (count != (ssize_t) length)
1179 break;
1180 if (image->previous == (Image *) NULL)
1181 {
1182 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1183 image->rows);
1184 if (status == MagickFalse)
1185 break;
1186 }
1187 }
1188 break;
1189 }
1190 case LineInterlace:
1191 {
1192 /*
1193 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1194 */
1195 for (y=0; y < (ssize_t) image->rows; y++)
1196 {
1197 register const Quantum
1198 *magick_restrict p;
1199
1200 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1201 if (p == (const Quantum *) NULL)
1202 break;
1203 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1204 RedQuantum,pixels,exception);
1205 count=WriteBlob(image,length,pixels);
1206 if (count != (ssize_t) length)
1207 break;
1208 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1209 GreenQuantum,pixels,exception);
1210 count=WriteBlob(image,length,pixels);
1211 if (count != (ssize_t) length)
1212 break;
1213 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1214 BlueQuantum,pixels,exception);
1215 count=WriteBlob(image,length,pixels);
1216 if (count != (ssize_t) length)
1217 break;
1218 if (quantum_type == RGBAQuantum)
1219 {
1220 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1221 AlphaQuantum,pixels,exception);
1222 count=WriteBlob(image,length,pixels);
1223 if (count != (ssize_t) length)
1224 break;
1225 }
1226 if (quantum_type == RGBOQuantum)
1227 {
1228 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1229 OpacityQuantum,pixels,exception);
1230 count=WriteBlob(image,length,pixels);
1231 if (count != (ssize_t) length)
1232 break;
1233 }
1234 if (image->previous == (Image *) NULL)
1235 {
1236 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1237 image->rows);
1238 if (status == MagickFalse)
1239 break;
1240 }
1241 }
1242 break;
1243 }
1244 case PlaneInterlace:
1245 {
1246 /*
1247 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1248 */
1249 for (y=0; y < (ssize_t) image->rows; y++)
1250 {
1251 register const Quantum
1252 *magick_restrict p;
1253
1254 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1255 if (p == (const Quantum *) NULL)
1256 break;
1257 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1258 RedQuantum,pixels,exception);
1259 count=WriteBlob(image,length,pixels);
1260 if (count != (ssize_t) length)
1261 break;
1262 }
1263 if (image->previous == (Image *) NULL)
1264 {
1265 status=SetImageProgress(image,SaveImageTag,1,6);
1266 if (status == MagickFalse)
1267 break;
1268 }
1269 for (y=0; y < (ssize_t) image->rows; y++)
1270 {
1271 register const Quantum
1272 *magick_restrict p;
1273
1274 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1275 if (p == (const Quantum *) NULL)
1276 break;
1277 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1278 GreenQuantum,pixels,exception);
1279 count=WriteBlob(image,length,pixels);
1280 if (count != (ssize_t) length)
1281 break;
1282 }
1283 if (image->previous == (Image *) NULL)
1284 {
1285 status=SetImageProgress(image,SaveImageTag,2,6);
1286 if (status == MagickFalse)
1287 break;
1288 }
1289 for (y=0; y < (ssize_t) image->rows; y++)
1290 {
1291 register const Quantum
1292 *magick_restrict p;
1293
1294 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1295 if (p == (const Quantum *) NULL)
1296 break;
1297 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1298 BlueQuantum,pixels,exception);
1299 count=WriteBlob(image,length,pixels);
1300 if (count != (ssize_t) length)
1301 break;
1302 }
1303 if (image->previous == (Image *) NULL)
1304 {
1305 status=SetImageProgress(image,SaveImageTag,3,6);
1306 if (status == MagickFalse)
1307 break;
1308 }
1309 if (quantum_type == RGBAQuantum)
1310 {
1311 for (y=0; y < (ssize_t) image->rows; y++)
1312 {
1313 register const Quantum
1314 *magick_restrict p;
1315
1316 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1317 if (p == (const Quantum *) NULL)
1318 break;
1319 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1320 AlphaQuantum,pixels,exception);
1321 count=WriteBlob(image,length,pixels);
1322 if (count != (ssize_t) length)
1323 break;
1324 }
1325 if (image->previous == (Image *) NULL)
1326 {
1327 status=SetImageProgress(image,SaveImageTag,5,6);
1328 if (status == MagickFalse)
1329 break;
1330 }
1331 }
1332 if (image_info->interlace == PartitionInterlace)
1333 (void) CopyMagickString(image->filename,image_info->filename,
1334 MagickPathExtent);
1335 if (image->previous == (Image *) NULL)
1336 {
1337 status=SetImageProgress(image,SaveImageTag,6,6);
1338 if (status == MagickFalse)
1339 break;
1340 }
1341 break;
1342 }
1343 case PartitionInterlace:
1344 {
1345 /*
1346 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1347 */
1348 AppendImageFormat("R",image->filename);
1349 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1350 AppendBinaryBlobMode,exception);
1351 if (status == MagickFalse)
1352 return(status);
1353 for (y=0; y < (ssize_t) image->rows; y++)
1354 {
1355 register const Quantum
1356 *magick_restrict p;
1357
1358 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1359 if (p == (const Quantum *) NULL)
1360 break;
1361 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1362 RedQuantum,pixels,exception);
1363 count=WriteBlob(image,length,pixels);
1364 if (count != (ssize_t) length)
1365 break;
1366 }
1367 if (image->previous == (Image *) NULL)
1368 {
1369 status=SetImageProgress(image,SaveImageTag,1,6);
1370 if (status == MagickFalse)
1371 break;
1372 }
1373 (void) CloseBlob(image);
1374 AppendImageFormat("G",image->filename);
1375 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1376 AppendBinaryBlobMode,exception);
1377 if (status == MagickFalse)
1378 return(status);
1379 for (y=0; y < (ssize_t) image->rows; y++)
1380 {
1381 register const Quantum
1382 *magick_restrict p;
1383
1384 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1385 if (p == (const Quantum *) NULL)
1386 break;
1387 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1388 GreenQuantum,pixels,exception);
1389 count=WriteBlob(image,length,pixels);
1390 if (count != (ssize_t) length)
1391 break;
1392 }
1393 if (image->previous == (Image *) NULL)
1394 {
1395 status=SetImageProgress(image,SaveImageTag,2,6);
1396 if (status == MagickFalse)
1397 break;
1398 }
1399 (void) CloseBlob(image);
1400 AppendImageFormat("B",image->filename);
1401 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1402 AppendBinaryBlobMode,exception);
1403 if (status == MagickFalse)
1404 return(status);
1405 for (y=0; y < (ssize_t) image->rows; y++)
1406 {
1407 register const Quantum
1408 *magick_restrict p;
1409
1410 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1411 if (p == (const Quantum *) NULL)
1412 break;
1413 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1414 BlueQuantum,pixels,exception);
1415 count=WriteBlob(image,length,pixels);
1416 if (count != (ssize_t) length)
1417 break;
1418 }
1419 if (image->previous == (Image *) NULL)
1420 {
1421 status=SetImageProgress(image,SaveImageTag,3,6);
1422 if (status == MagickFalse)
1423 break;
1424 }
1425 if (quantum_type == RGBAQuantum)
1426 {
1427 (void) CloseBlob(image);
1428 AppendImageFormat("A",image->filename);
1429 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1430 AppendBinaryBlobMode,exception);
1431 if (status == MagickFalse)
1432 return(status);
1433 for (y=0; y < (ssize_t) image->rows; y++)
1434 {
1435 register const Quantum
1436 *magick_restrict p;
1437
1438 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1439 if (p == (const Quantum *) NULL)
1440 break;
1441 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1442 AlphaQuantum,pixels,exception);
1443 count=WriteBlob(image,length,pixels);
1444 if (count != (ssize_t) length)
1445 break;
1446 }
1447 if (image->previous == (Image *) NULL)
1448 {
1449 status=SetImageProgress(image,SaveImageTag,5,6);
1450 if (status == MagickFalse)
1451 break;
1452 }
1453 }
1454 (void) CloseBlob(image);
1455 (void) CopyMagickString(image->filename,image_info->filename,
1456 MagickPathExtent);
1457 if (image->previous == (Image *) NULL)
1458 {
1459 status=SetImageProgress(image,SaveImageTag,6,6);
1460 if (status == MagickFalse)
1461 break;
1462 }
1463 break;
1464 }
1465 }
1466 quantum_info=DestroyQuantumInfo(quantum_info);
1467 if (GetNextImageInList(image) == (Image *) NULL)
1468 break;
1469 image=SyncNextImageInList(image);
1470 status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
1471 if (status == MagickFalse)
1472 break;
1473 } while (image_info->adjoin != MagickFalse);
1474 (void) CloseBlob(image);
1475 return(MagickTrue);
1476 }
1477