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