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