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