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