]> granicus.if.org Git - imagemagick/blob - coders/bgr.c
Accommodate background color index in PLTE chunk
[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 %                                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   WriteBGRImage(const ImageInfo *,Image *,ExceptionInfo *);
71 \f
72 /*
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74 %                                                                             %
75 %                                                                             %
76 %                                                                             %
77 %   R e a d B G R I m a g e                                                   %
78 %                                                                             %
79 %                                                                             %
80 %                                                                             %
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 %
83 %  ReadBGRImage() reads an image of raw BGR, or BGRA 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 ReadBGRImage method is:
88 %
89 %      Image *ReadBGRImage(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 *ReadBGRImage(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   if (image_info->interlace != PartitionInterlace)
145     {
146       status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
147       if (status == MagickFalse)
148         {
149           image=DestroyImageList(image);
150           return((Image *) NULL);
151         }
152       if (DiscardBlobBytes(image,image->offset) == MagickFalse)
153         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
154           image->filename);
155     }
156   /*
157     Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
158   */
159   canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
160     exception);
161   (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
162     exception);
163   quantum_info=AcquireQuantumInfo(image_info,canvas_image);
164   if (quantum_info == (QuantumInfo *) NULL)
165     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
166   pixels=GetQuantumPixels(quantum_info);
167   quantum_type=BGRQuantum;
168   if (LocaleCompare(image_info->magick,"BGRA") == 0)
169     {
170       quantum_type=BGRAQuantum;
171       image->matte=MagickTrue;
172     }
173   if (image_info->number_scenes != 0)
174     while (image->scene < image_info->scene)
175     {
176       /*
177         Skip to next image.
178       */
179       image->scene++;
180       length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
181       for (y=0; y < (ssize_t) image->rows; y++)
182       {
183         count=ReadBlob(image,length,pixels);
184         if (count != (ssize_t) length)
185           break;
186       }
187     }
188   count=0;
189   length=0;
190   scene=0;
191   do
192   {
193     /*
194       Read pixels to virtual canvas image then push to image.
195     */
196     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
197       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
198         break;
199     switch (image_info->interlace)
200     {
201       case NoInterlace:
202       default:
203       {
204         /*
205           No interlacing:  BGRBGRBGRBGRBGRBGR...
206         */
207         if (scene == 0)
208           {
209             length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
210             count=ReadBlob(image,length,pixels);
211           }
212         for (y=0; y < (ssize_t) image->extract_info.height; y++)
213         {
214           register const Quantum
215             *restrict p;
216
217           register Quantum
218             *restrict q;
219
220           register ssize_t
221             x;
222
223           if (count != (ssize_t) length)
224             {
225               ThrowFileException(exception,CorruptImageError,
226                 "UnexpectedEndOfFile",image->filename);
227               break;
228             }
229           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
230             exception);
231           if (q == (Quantum *) NULL)
232             break;
233           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
234             quantum_info,quantum_type,pixels,exception);
235           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
236             break;
237           if (((y-image->extract_info.y) >= 0) && 
238               ((y-image->extract_info.y) < (ssize_t) image->rows))
239             {
240               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
241                 canvas_image->columns,1,exception);
242               q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
243                 image->columns,1,exception);
244               if ((p == (const Quantum *) NULL) ||
245                   (q == (Quantum *) NULL))
246                 break;
247               for (x=0; x < (ssize_t) image->columns; x++)
248               {
249                 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
250                 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
251                 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
252                 SetPixelAlpha(image,OpaqueAlpha,q);
253                 if (image->matte != MagickFalse)
254                   SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
255                 p+=GetPixelChannels(canvas_image);
256                 q+=GetPixelChannels(image);
257               }
258               if (SyncAuthenticPixels(image,exception) == MagickFalse)
259                 break;
260             }
261           if (image->previous == (Image *) NULL)
262             {
263               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
264                 image->rows);
265               if (status == MagickFalse)
266                 break;
267             }
268           count=ReadBlob(image,length,pixels);
269         }
270         break;
271       }
272       case LineInterlace:
273       {
274         static QuantumType
275           quantum_types[4] =
276           {
277             BlueQuantum,
278             GreenQuantum,
279             RedQuantum,
280             AlphaQuantum
281           };
282
283         /*
284           Line interlacing:  BBB...GGG...RRR...RRR...GGG...BBB...
285         */
286         if (scene == 0)
287           {
288             length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
289             count=ReadBlob(image,length,pixels);
290           }
291         for (y=0; y < (ssize_t) image->extract_info.height; y++)
292         {
293           register const Quantum
294             *restrict p;
295
296           register Quantum
297             *restrict q;
298
299           register ssize_t
300             x;
301
302           if (count != (ssize_t) length)
303             {
304               ThrowFileException(exception,CorruptImageError,
305                 "UnexpectedEndOfFile",image->filename);
306               break;
307             }
308           for (i=0; i < (ssize_t) (image->matte != MagickFalse ? 4 : 3); i++)
309           {
310             quantum_type=quantum_types[i];
311             q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
312               exception);
313             if (q == (Quantum *) NULL)
314               break;
315             length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
316               quantum_info,quantum_type,pixels,exception);
317             if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
318               break;
319             if (((y-image->extract_info.y) >= 0) && 
320                 ((y-image->extract_info.y) < (ssize_t) image->rows))
321               {
322                 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
323                   canvas_image->columns,1,exception);
324                 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
325                   image->columns,1,exception);
326                 if ((p == (const Quantum *) NULL) ||
327                     (q == (Quantum *) NULL))
328                   break;
329                 for (x=0; x < (ssize_t) image->columns; x++)
330                 {
331                   switch (quantum_type)
332                   {
333                     case RedQuantum:
334                     {
335                       SetPixelRed(image,GetPixelRed(canvas_image,p),q);
336                       break;
337                     }
338                     case GreenQuantum:
339                     {
340                       SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
341                       break;
342                     }
343                     case BlueQuantum:
344                     {
345                       SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
346                       break;
347                     }
348                     case OpacityQuantum:
349                     {
350                       SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
351                       break;
352                     }
353                     case AlphaQuantum:
354                     {
355                       SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
356                       break;
357                     }
358                     default:
359                       break;
360                   }
361                   p+=GetPixelChannels(canvas_image);
362                   q+=GetPixelChannels(image);
363                 }
364                 if (SyncAuthenticPixels(image,exception) == MagickFalse)
365                   break;
366               }
367             count=ReadBlob(image,length,pixels);
368           }
369           if (image->previous == (Image *) NULL)
370             {
371               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
372                 image->rows);
373               if (status == MagickFalse)
374                 break;
375             }
376         }
377         break;
378       }
379       case PlaneInterlace:
380       {
381         /*
382           Plane interlacing:  RRRRRR...GGGGGG...BBBBBB...
383         */
384         if (scene == 0)
385           {
386             length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
387             count=ReadBlob(image,length,pixels);
388           }
389         for (y=0; y < (ssize_t) image->extract_info.height; y++)
390         {
391           register const Quantum
392             *restrict p;
393
394           register Quantum
395             *restrict q;
396
397           register ssize_t
398             x;
399
400           if (count != (ssize_t) length)
401             {
402               ThrowFileException(exception,CorruptImageError,
403                 "UnexpectedEndOfFile",image->filename);
404               break;
405             }
406           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
407             exception);
408           if (q == (Quantum *) NULL)
409             break;
410           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
411             quantum_info,RedQuantum,pixels,exception);
412           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
413             break;
414           if (((y-image->extract_info.y) >= 0) && 
415               ((y-image->extract_info.y) < (ssize_t) image->rows))
416             {
417               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
418                 canvas_image->columns,1,exception);
419               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
420                 image->columns,1,exception);
421               if ((p == (const Quantum *) NULL) ||
422                   (q == (Quantum *) NULL))
423                 break;
424               for (x=0; x < (ssize_t) image->columns; x++)
425               {
426                 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
427                 p+=GetPixelChannels(canvas_image);
428                 q+=GetPixelChannels(image);
429               }
430               if (SyncAuthenticPixels(image,exception) == MagickFalse)
431                 break;
432             }
433           count=ReadBlob(image,length,pixels);
434         }
435         if (image->previous == (Image *) NULL)
436           {
437             status=SetImageProgress(image,LoadImageTag,1,6);
438             if (status == MagickFalse)
439               break;
440           }
441         for (y=0; y < (ssize_t) image->extract_info.height; y++)
442         {
443           register const Quantum
444             *restrict p;
445
446           register Quantum
447             *restrict q;
448
449           register ssize_t
450             x;
451
452           if (count != (ssize_t) length)
453             {
454               ThrowFileException(exception,CorruptImageError,
455                 "UnexpectedEndOfFile",image->filename);
456               break;
457             }
458           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
459             exception);
460           if (q == (Quantum *) NULL)
461             break;
462           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
463             quantum_info,GreenQuantum,pixels,exception);
464           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
465             break;
466           if (((y-image->extract_info.y) >= 0) && 
467               ((y-image->extract_info.y) < (ssize_t) image->rows))
468             {
469               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
470                 canvas_image->columns,1,exception);
471               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
472                 image->columns,1,exception);
473               if ((p == (const Quantum *) NULL) ||
474                   (q == (Quantum *) NULL))
475                 break;
476               for (x=0; x < (ssize_t) image->columns; x++)
477               {
478                 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
479                 p+=GetPixelChannels(canvas_image);
480                 q+=GetPixelChannels(image);
481               }
482               if (SyncAuthenticPixels(image,exception) == MagickFalse)
483                 break;
484            }
485           count=ReadBlob(image,length,pixels);
486         }
487         if (image->previous == (Image *) NULL)
488           {
489             status=SetImageProgress(image,LoadImageTag,2,6);
490             if (status == MagickFalse)
491               break;
492           }
493         for (y=0; y < (ssize_t) image->extract_info.height; y++)
494         {
495           register const Quantum
496             *restrict p;
497
498           register Quantum
499             *restrict q;
500
501           register ssize_t
502             x;
503
504           if (count != (ssize_t) length)
505             {
506               ThrowFileException(exception,CorruptImageError,
507                 "UnexpectedEndOfFile",image->filename);
508               break;
509             }
510           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
511             exception);
512           if (q == (Quantum *) NULL)
513             break;
514           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
515             quantum_info,BlueQuantum,pixels,exception);
516           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
517             break;
518           if (((y-image->extract_info.y) >= 0) && 
519               ((y-image->extract_info.y) < (ssize_t) image->rows))
520             {
521               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
522                 canvas_image->columns,1,exception);
523               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
524                 image->columns,1,exception);
525               if ((p == (const Quantum *) NULL) ||
526                   (q == (Quantum *) NULL))
527                 break;
528               for (x=0; x < (ssize_t) image->columns; x++)
529               {
530                 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
531                 p+=GetPixelChannels(canvas_image);
532                 q+=GetPixelChannels(image);
533               }
534               if (SyncAuthenticPixels(image,exception) == MagickFalse)
535                 break;
536             }
537           count=ReadBlob(image,length,pixels);
538         }
539         if (image->previous == (Image *) NULL)
540           {
541             status=SetImageProgress(image,LoadImageTag,3,6);
542             if (status == MagickFalse)
543               break;
544           }
545         if (image->previous == (Image *) NULL)
546           {
547             status=SetImageProgress(image,LoadImageTag,4,6);
548             if (status == MagickFalse)
549               break;
550           }
551         if (image->matte != MagickFalse)
552           {
553             for (y=0; y < (ssize_t) image->extract_info.height; y++)
554             {
555               register const Quantum
556                 *restrict p;
557
558               register Quantum
559                 *restrict q;
560
561               register ssize_t
562                 x;
563
564               if (count != (ssize_t) length)
565                 {
566                   ThrowFileException(exception,CorruptImageError,
567                     "UnexpectedEndOfFile",image->filename);
568                   break;
569                 }
570               q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
571                 exception);
572               if (q == (Quantum *) NULL)
573                 break;
574               length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
575                 quantum_info,AlphaQuantum,pixels,exception);
576               if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
577                 break;
578               if (((y-image->extract_info.y) >= 0) && 
579                   ((y-image->extract_info.y) < (ssize_t) image->rows))
580                 {
581                   p=GetVirtualPixels(canvas_image,
582                     canvas_image->extract_info.x,0,canvas_image->columns,1,
583                     exception);
584                   q=GetAuthenticPixels(image,0,y-image->extract_info.y,
585                     image->columns,1,exception);
586                   if ((p == (const Quantum *) NULL) ||
587                       (q == (Quantum *) NULL))
588                     break;
589                   for (x=0; x < (ssize_t) image->columns; x++)
590                   {
591                     SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
592                     p+=GetPixelChannels(canvas_image);
593                     q+=GetPixelChannels(image);
594                   }
595                   if (SyncAuthenticPixels(image,exception) == MagickFalse)
596                     break;
597                 }
598               count=ReadBlob(image,length,pixels);
599             }
600             if (image->previous == (Image *) NULL)
601               {
602                 status=SetImageProgress(image,LoadImageTag,5,6);
603                 if (status == MagickFalse)
604                   break;
605               }
606           }
607         if (image->previous == (Image *) NULL)
608           {
609             status=SetImageProgress(image,LoadImageTag,6,6);
610             if (status == MagickFalse)
611               break;
612           }
613         break;
614       }
615       case PartitionInterlace:
616       {
617         /*
618           Partition interlacing:  BBBBBB..., GGGGGG..., RRRRRR...
619         */
620         AppendImageFormat("B",image->filename);
621         status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
622         if (status == MagickFalse)
623           {
624             canvas_image=DestroyImageList(canvas_image);
625             image=DestroyImageList(image);
626             return((Image *) NULL);
627           }
628         if (DiscardBlobBytes(image,image->offset) == MagickFalse)
629           ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
630             image->filename);
631         length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
632         for (i=0; i < (ssize_t) scene; i++)
633           for (y=0; y < (ssize_t) image->extract_info.height; y++)
634             if (ReadBlob(image,length,pixels) != (ssize_t) length)
635               {
636                 ThrowFileException(exception,CorruptImageError,
637                   "UnexpectedEndOfFile",image->filename);
638                 break;
639               }
640         count=ReadBlob(image,length,pixels);
641         for (y=0; y < (ssize_t) image->extract_info.height; y++)
642         {
643           register const Quantum
644             *restrict p;
645
646           register Quantum
647             *restrict q;
648
649           register ssize_t
650             x;
651
652           if (count != (ssize_t) length)
653             {
654               ThrowFileException(exception,CorruptImageError,
655                 "UnexpectedEndOfFile",image->filename);
656               break;
657             }
658           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
659             exception);
660           if (q == (Quantum *) NULL)
661             break;
662           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
663             quantum_info,BlueQuantum,pixels,exception);
664           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
665             break;
666           if (((y-image->extract_info.y) >= 0) && 
667               ((y-image->extract_info.y) < (ssize_t) image->rows))
668             {
669               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
670                 canvas_image->columns,1,exception);
671               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
672                 image->columns,1,exception);
673               if ((p == (const Quantum *) NULL) ||
674                   (q == (Quantum *) NULL))
675                 break;
676               for (x=0; x < (ssize_t) image->columns; x++)
677               {
678                 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
679                 p+=GetPixelChannels(canvas_image);
680                 q+=GetPixelChannels(image);
681               }
682               if (SyncAuthenticPixels(image,exception) == MagickFalse)
683                 break;
684             }
685           count=ReadBlob(image,length,pixels);
686         }
687         if (image->previous == (Image *) NULL)
688           {
689             status=SetImageProgress(image,LoadImageTag,1,5);
690             if (status == MagickFalse)
691               break;
692           }
693         (void) CloseBlob(image);
694         AppendImageFormat("G",image->filename);
695         status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
696         if (status == MagickFalse)
697           {
698             canvas_image=DestroyImageList(canvas_image);
699             image=DestroyImageList(image);
700             return((Image *) NULL);
701           }
702         length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
703         for (i=0; i < (ssize_t) scene; i++)
704           for (y=0; y < (ssize_t) image->extract_info.height; y++)
705             if (ReadBlob(image,length,pixels) != (ssize_t) length)
706               {
707                 ThrowFileException(exception,CorruptImageError,
708                   "UnexpectedEndOfFile",image->filename);
709                 break;
710               }
711         count=ReadBlob(image,length,pixels);
712         for (y=0; y < (ssize_t) image->extract_info.height; y++)
713         {
714           register const Quantum
715             *restrict p;
716
717           register Quantum
718             *restrict q;
719
720           register ssize_t
721             x;
722
723           if (count != (ssize_t) length)
724             {
725               ThrowFileException(exception,CorruptImageError,
726                 "UnexpectedEndOfFile",image->filename);
727               break;
728             }
729           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
730             exception);
731           if (q == (Quantum *) NULL)
732             break;
733           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
734             quantum_info,GreenQuantum,pixels,exception);
735           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
736             break;
737           if (((y-image->extract_info.y) >= 0) && 
738               ((y-image->extract_info.y) < (ssize_t) image->rows))
739             {
740               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
741                 canvas_image->columns,1,exception);
742               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
743                 image->columns,1,exception);
744               if ((p == (const Quantum *) NULL) ||
745                   (q == (Quantum *) NULL))
746                 break;
747               for (x=0; x < (ssize_t) image->columns; x++)
748               {
749                 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
750                 p+=GetPixelChannels(canvas_image);
751                 q+=GetPixelChannels(image);
752               }
753               if (SyncAuthenticPixels(image,exception) == MagickFalse)
754                 break;
755            }
756           count=ReadBlob(image,length,pixels);
757         }
758         if (image->previous == (Image *) NULL)
759           {
760             status=SetImageProgress(image,LoadImageTag,2,5);
761             if (status == MagickFalse)
762               break;
763           }
764         (void) CloseBlob(image);
765         AppendImageFormat("R",image->filename);
766         status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
767         if (status == MagickFalse)
768           {
769             canvas_image=DestroyImageList(canvas_image);
770             image=DestroyImageList(image);
771             return((Image *) NULL);
772           }
773         length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
774         for (i=0; i < (ssize_t) scene; i++)
775           for (y=0; y < (ssize_t) image->extract_info.height; y++)
776             if (ReadBlob(image,length,pixels) != (ssize_t) length)
777               {
778                 ThrowFileException(exception,CorruptImageError,
779                   "UnexpectedEndOfFile",image->filename);
780                 break;
781               }
782         count=ReadBlob(image,length,pixels);
783         for (y=0; y < (ssize_t) image->extract_info.height; y++)
784         {
785           register const Quantum
786             *restrict p;
787
788           register Quantum
789             *restrict q;
790
791           register ssize_t
792             x;
793
794           if (count != (ssize_t) length)
795             {
796               ThrowFileException(exception,CorruptImageError,
797                 "UnexpectedEndOfFile",image->filename);
798               break;
799             }
800           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
801             exception);
802           if (q == (Quantum *) NULL)
803             break;
804           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
805             quantum_info,RedQuantum,pixels,exception);
806           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
807             break;
808           if (((y-image->extract_info.y) >= 0) && 
809               ((y-image->extract_info.y) < (ssize_t) image->rows))
810             {
811               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
812                 canvas_image->columns,1,exception);
813               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
814                 image->columns,1,exception);
815               if ((p == (const Quantum *) NULL) ||
816                   (q == (Quantum *) NULL))
817                 break;
818               for (x=0; x < (ssize_t) image->columns; x++)
819               {
820                 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
821                 p+=GetPixelChannels(canvas_image);
822                 q+=GetPixelChannels(image);
823               }
824               if (SyncAuthenticPixels(image,exception) == MagickFalse)
825                 break;
826            }
827           count=ReadBlob(image,length,pixels);
828         }
829         if (image->previous == (Image *) NULL)
830           {
831             status=SetImageProgress(image,LoadImageTag,3,5);
832             if (status == MagickFalse)
833               break;
834           }
835         if (image->matte != MagickFalse)
836           {
837             (void) CloseBlob(image);
838             AppendImageFormat("A",image->filename);
839             status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
840             if (status == MagickFalse)
841               {
842                 canvas_image=DestroyImageList(canvas_image);
843                 image=DestroyImageList(image);
844                 return((Image *) NULL);
845               }
846             length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
847             for (i=0; i < (ssize_t) scene; i++)
848               for (y=0; y < (ssize_t) image->extract_info.height; y++)
849                 if (ReadBlob(image,length,pixels) != (ssize_t) length)
850                   {
851                     ThrowFileException(exception,CorruptImageError,
852                       "UnexpectedEndOfFile",image->filename);
853                     break;
854                   }
855             count=ReadBlob(image,length,pixels);
856             for (y=0; y < (ssize_t) image->extract_info.height; y++)
857             {
858               register const Quantum
859                 *restrict p;
860
861               register Quantum
862                 *restrict q;
863
864               register ssize_t
865                 x;
866
867               if (count != (ssize_t) length)
868                 {
869                   ThrowFileException(exception,CorruptImageError,
870                     "UnexpectedEndOfFile",image->filename);
871                   break;
872                 }
873               q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
874                 exception);
875               if (q == (Quantum *) NULL)
876                 break;
877               length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
878                 quantum_info,BlueQuantum,pixels,exception);
879               if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
880                 break;
881               if (((y-image->extract_info.y) >= 0) && 
882                   ((y-image->extract_info.y) < (ssize_t) image->rows))
883                 {
884                   p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
885                     0,canvas_image->columns,1,exception);
886                   q=GetAuthenticPixels(image,0,y-image->extract_info.y,
887                     image->columns,1,exception);
888                   if ((p == (const Quantum *) NULL) ||
889                       (q == (Quantum *) NULL))
890                     break;
891                   for (x=0; x < (ssize_t) image->columns; x++)
892                   {
893                     SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
894                     p+=GetPixelChannels(canvas_image);
895                     q+=GetPixelChannels(image);
896                   }
897                   if (SyncAuthenticPixels(image,exception) == MagickFalse)
898                     break;
899                }
900               count=ReadBlob(image,length,pixels);
901             }
902             if (image->previous == (Image *) NULL)
903               {
904                 status=SetImageProgress(image,LoadImageTag,4,5);
905                 if (status == MagickFalse)
906                   break;
907               }
908           }
909         (void) CloseBlob(image);
910         if (image->previous == (Image *) NULL)
911           {
912             status=SetImageProgress(image,LoadImageTag,5,5);
913             if (status == MagickFalse)
914               break;
915           }
916         break;
917       }
918     }
919     SetQuantumImageType(image,quantum_type);
920     /*
921       Proceed to next image.
922     */
923     if (image_info->number_scenes != 0)
924       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
925         break;
926     if (count == (ssize_t) length)
927       {
928         /*
929           Allocate next image structure.
930         */
931         AcquireNextImage(image_info,image,exception);
932         if (GetNextImageInList(image) == (Image *) NULL)
933           {
934             image=DestroyImageList(image);
935             return((Image *) NULL);
936           }
937         image=SyncNextImageInList(image);
938         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
939           GetBlobSize(image));
940         if (status == MagickFalse)
941           break;
942       }
943     scene++;
944   } while (count == (ssize_t) length);
945   quantum_info=DestroyQuantumInfo(quantum_info);
946   canvas_image=DestroyImage(canvas_image);
947   (void) CloseBlob(image);
948   return(GetFirstImageInList(image));
949 }
950 \f
951 /*
952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953 %                                                                             %
954 %                                                                             %
955 %                                                                             %
956 %   R e g i s t e r B G R I m a g e                                           %
957 %                                                                             %
958 %                                                                             %
959 %                                                                             %
960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
961 %
962 %  RegisterBGRImage() adds attributes for the BGR image format to
963 %  the list of supported formats.  The attributes include the image format
964 %  tag, a method to read and/or write the format, whether the format
965 %  supports the saving of more than one frame to the same file or blob,
966 %  whether the format supports native in-memory I/O, and a brief
967 %  description of the format.
968 %
969 %  The format of the RegisterBGRImage method is:
970 %
971 %      size_t RegisterBGRImage(void)
972 %
973 */
974 ModuleExport size_t RegisterBGRImage(void)
975 {
976   MagickInfo
977     *entry;
978
979   entry=SetMagickInfo("BGR");
980   entry->decoder=(DecodeImageHandler *) ReadBGRImage;
981   entry->encoder=(EncodeImageHandler *) WriteBGRImage;
982   entry->raw=MagickTrue;
983   entry->endian_support=MagickTrue;
984   entry->description=ConstantString("Raw blue, green, and red samples");
985   entry->module=ConstantString("BGR");
986   (void) RegisterMagickInfo(entry);
987   entry=SetMagickInfo("BGRA");
988   entry->decoder=(DecodeImageHandler *) ReadBGRImage;
989   entry->encoder=(EncodeImageHandler *) WriteBGRImage;
990   entry->raw=MagickTrue;
991   entry->endian_support=MagickTrue;
992   entry->description=ConstantString("Raw blue, green, red, and alpha samples");
993   entry->module=ConstantString("BGR");
994   (void) RegisterMagickInfo(entry);
995   return(MagickImageCoderSignature);
996 }
997 \f
998 /*
999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1000 %                                                                             %
1001 %                                                                             %
1002 %                                                                             %
1003 %   U n r e g i s t e r B G R I m a g e                                       %
1004 %                                                                             %
1005 %                                                                             %
1006 %                                                                             %
1007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1008 %
1009 %  UnregisterBGRImage() removes format registrations made by the BGR module
1010 %  from the list of supported formats.
1011 %
1012 %  The format of the UnregisterBGRImage method is:
1013 %
1014 %      UnregisterBGRImage(void)
1015 %
1016 */
1017 ModuleExport void UnregisterBGRImage(void)
1018 {
1019   (void) UnregisterMagickInfo("BGRA");
1020   (void) UnregisterMagickInfo("BGR");
1021 }
1022 \f
1023 /*
1024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025 %                                                                             %
1026 %                                                                             %
1027 %                                                                             %
1028 %   W r i t e B G R I m a g e                                                 %
1029 %                                                                             %
1030 %                                                                             %
1031 %                                                                             %
1032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1033 %
1034 %  WriteBGRImage() writes an image to a file in the BGR or BGRA
1035 %  rasterfile format.
1036 %
1037 %  The format of the WriteBGRImage method is:
1038 %
1039 %      MagickBooleanType WriteBGRImage(const ImageInfo *image_info,
1040 %        Image *image,ExceptionInfo *exception)
1041 %
1042 %  A description of each parameter follows.
1043 %
1044 %    o image_info: the image info.
1045 %
1046 %    o image:  The image.
1047 %
1048 %    o exception: return any errors or warnings in this structure.
1049 %
1050 */
1051 static MagickBooleanType WriteBGRImage(const ImageInfo *image_info,Image *image,
1052   ExceptionInfo *exception)
1053 {
1054   MagickBooleanType
1055     status;
1056
1057   MagickOffsetType
1058     scene;
1059
1060   QuantumInfo
1061     *quantum_info;
1062
1063   QuantumType
1064     quantum_type;
1065
1066   size_t
1067     length;
1068
1069   ssize_t
1070     count,
1071     y;
1072
1073   unsigned char
1074     *pixels;
1075
1076   /*
1077     Allocate memory for pixels.
1078   */
1079   assert(image_info != (const ImageInfo *) NULL);
1080   assert(image_info->signature == MagickSignature);
1081   assert(image != (Image *) NULL);
1082   assert(image->signature == MagickSignature);
1083   if (image->debug != MagickFalse)
1084     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1085   if (image_info->interlace != PartitionInterlace)
1086     {
1087       /*
1088         Open output image file.
1089       */
1090       assert(exception != (ExceptionInfo *) NULL);
1091   assert(exception->signature == MagickSignature);
1092   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1093       if (status == MagickFalse)
1094         return(status);
1095     }
1096   quantum_type=BGRQuantum;
1097   if (LocaleCompare(image_info->magick,"BGRA") == 0)
1098     {
1099       quantum_type=BGRAQuantum;
1100       image->matte=MagickTrue;
1101     }
1102   scene=0;
1103   do
1104   {
1105     /*
1106       Convert MIFF to BGR raster pixels.
1107     */
1108     if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
1109       (void) TransformImageColorspace(image,sRGBColorspace,exception);
1110     if ((LocaleCompare(image_info->magick,"BGRA") == 0) &&
1111         (image->matte == MagickFalse))
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 }