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