]> granicus.if.org Git - imagemagick/blob - coders/bgr.c
(no commit message)
[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   image->colorspace=RGBColorspace;
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   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     image->colorspace=RGBColorspace;
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->matte != MagickFalse)
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->matte != MagickFalse ? 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->matte != MagickFalse)
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->matte != MagickFalse)
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   InheritException(&image->exception,&canvas_image->exception);
948   canvas_image=DestroyImage(canvas_image);
949   (void) CloseBlob(image);
950   return(GetFirstImageInList(image));
951 }
952 \f
953 /*
954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
955 %                                                                             %
956 %                                                                             %
957 %                                                                             %
958 %   R e g i s t e r B G R I m a g e                                           %
959 %                                                                             %
960 %                                                                             %
961 %                                                                             %
962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
963 %
964 %  RegisterBGRImage() adds attributes for the BGR image format to
965 %  the list of supported formats.  The attributes include the image format
966 %  tag, a method to read and/or write the format, whether the format
967 %  supports the saving of more than one frame to the same file or blob,
968 %  whether the format supports native in-memory I/O, and a brief
969 %  description of the format.
970 %
971 %  The format of the RegisterBGRImage method is:
972 %
973 %      size_t RegisterBGRImage(void)
974 %
975 */
976 ModuleExport size_t RegisterBGRImage(void)
977 {
978   MagickInfo
979     *entry;
980
981   entry=SetMagickInfo("BGR");
982   entry->decoder=(DecodeImageHandler *) ReadBGRImage;
983   entry->encoder=(EncodeImageHandler *) WriteBGRImage;
984   entry->raw=MagickTrue;
985   entry->endian_support=MagickTrue;
986   entry->description=ConstantString("Raw blue, green, and red samples");
987   entry->module=ConstantString("BGR");
988   (void) RegisterMagickInfo(entry);
989   entry=SetMagickInfo("BGRA");
990   entry->decoder=(DecodeImageHandler *) ReadBGRImage;
991   entry->encoder=(EncodeImageHandler *) WriteBGRImage;
992   entry->raw=MagickTrue;
993   entry->endian_support=MagickTrue;
994   entry->description=ConstantString("Raw blue, green, red, and alpha samples");
995   entry->module=ConstantString("BGR");
996   (void) RegisterMagickInfo(entry);
997   return(MagickImageCoderSignature);
998 }
999 \f
1000 /*
1001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1002 %                                                                             %
1003 %                                                                             %
1004 %                                                                             %
1005 %   U n r e g i s t e r B G R I m a g e                                       %
1006 %                                                                             %
1007 %                                                                             %
1008 %                                                                             %
1009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1010 %
1011 %  UnregisterBGRImage() removes format registrations made by the BGR module
1012 %  from the list of supported formats.
1013 %
1014 %  The format of the UnregisterBGRImage method is:
1015 %
1016 %      UnregisterBGRImage(void)
1017 %
1018 */
1019 ModuleExport void UnregisterBGRImage(void)
1020 {
1021   (void) UnregisterMagickInfo("BGRA");
1022   (void) UnregisterMagickInfo("BGR");
1023 }
1024 \f
1025 /*
1026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1027 %                                                                             %
1028 %                                                                             %
1029 %                                                                             %
1030 %   W r i t e B G R I m a g e                                                 %
1031 %                                                                             %
1032 %                                                                             %
1033 %                                                                             %
1034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035 %
1036 %  WriteBGRImage() writes an image to a file in the BGR or BGRA
1037 %  rasterfile format.
1038 %
1039 %  The format of the WriteBGRImage method is:
1040 %
1041 %      MagickBooleanType WriteBGRImage(const ImageInfo *image_info,
1042 %        Image *image,ExceptionInfo *exception)
1043 %
1044 %  A description of each parameter follows.
1045 %
1046 %    o image_info: the image info.
1047 %
1048 %    o image:  The image.
1049 %
1050 %    o exception: return any errors or warnings in this structure.
1051 %
1052 */
1053 static MagickBooleanType WriteBGRImage(const ImageInfo *image_info,Image *image,
1054   ExceptionInfo *exception)
1055 {
1056   MagickBooleanType
1057     status;
1058
1059   MagickOffsetType
1060     scene;
1061
1062   QuantumInfo
1063     *quantum_info;
1064
1065   QuantumType
1066     quantum_type;
1067
1068   size_t
1069     length;
1070
1071   ssize_t
1072     count,
1073     y;
1074
1075   unsigned char
1076     *pixels;
1077
1078   /*
1079     Allocate memory for pixels.
1080   */
1081   assert(image_info != (const ImageInfo *) NULL);
1082   assert(image_info->signature == MagickSignature);
1083   assert(image != (Image *) NULL);
1084   assert(image->signature == MagickSignature);
1085   if (image->debug != MagickFalse)
1086     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1087   if (image_info->interlace != PartitionInterlace)
1088     {
1089       /*
1090         Open output image file.
1091       */
1092       assert(exception != (ExceptionInfo *) NULL);
1093   assert(exception->signature == MagickSignature);
1094   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1095       if (status == MagickFalse)
1096         return(status);
1097     }
1098   quantum_type=BGRQuantum;
1099   if (LocaleCompare(image_info->magick,"BGRA") == 0)
1100     {
1101       quantum_type=BGRAQuantum;
1102       image->matte=MagickTrue;
1103     }
1104   scene=0;
1105   do
1106   {
1107     /*
1108       Convert MIFF to BGR raster pixels.
1109     */
1110     if (IsRGBColorspace(image->colorspace) == MagickFalse)
1111       (void) TransformImageColorspace(image,RGBColorspace);
1112     if ((LocaleCompare(image_info->magick,"BGRA") == 0) &&
1113         (image->matte == MagickFalse))
1114       (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1115     quantum_info=AcquireQuantumInfo(image_info,image);
1116     if (quantum_info == (QuantumInfo *) NULL)
1117       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1118     pixels=GetQuantumPixels(quantum_info);
1119     switch (image_info->interlace)
1120     {
1121       case NoInterlace:
1122       default:
1123       {
1124         /*
1125           No interlacing:  BGRBGRBGRBGRBGRBGR...
1126         */
1127         for (y=0; y < (ssize_t) image->rows; y++)
1128         {
1129           register const Quantum
1130             *restrict p;
1131
1132           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1133           if (p == (const Quantum *) NULL)
1134             break;
1135           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1136             quantum_type,pixels,exception);
1137           count=WriteBlob(image,length,pixels);
1138           if (count != (ssize_t) length)
1139             break;
1140           if (image->previous == (Image *) NULL)
1141             {
1142               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1143                 image->rows);
1144               if (status == MagickFalse)
1145                 break;
1146             }
1147         }
1148         break;
1149       }
1150       case LineInterlace:
1151       {
1152         /*
1153           Line interlacing:  BBB...GGG...RRR...RRR...GGG...BBB...
1154         */
1155         for (y=0; y < (ssize_t) image->rows; y++)
1156         {
1157           register const Quantum
1158             *restrict p;
1159
1160           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1161           if (p == (const Quantum *) NULL)
1162             break;
1163           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1164             BlueQuantum,pixels,exception);
1165           count=WriteBlob(image,length,pixels);
1166           if (count != (ssize_t) length)
1167             break;
1168           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1169             GreenQuantum,pixels,exception);
1170           count=WriteBlob(image,length,pixels);
1171           if (count != (ssize_t) length)
1172             break;
1173           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1174             RedQuantum,pixels,exception);
1175           count=WriteBlob(image,length,pixels);
1176           if (count != (ssize_t) length)
1177             break;
1178           if (quantum_type == BGRAQuantum)
1179             {
1180               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1181                 AlphaQuantum,pixels,exception);
1182               count=WriteBlob(image,length,pixels);
1183               if (count != (ssize_t) length)
1184                 break;
1185             }
1186           if (image->previous == (Image *) NULL)
1187             {
1188               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1189                 image->rows);
1190               if (status == MagickFalse)
1191                 break;
1192             }
1193         }
1194         break;
1195       }
1196       case PlaneInterlace:
1197       {
1198         /*
1199           Plane interlacing:  RRRRRR...GGGGGG...BBBBBB...
1200         */
1201         for (y=0; y < (ssize_t) image->rows; y++)
1202         {
1203           register const Quantum
1204             *restrict p;
1205
1206           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1207           if (p == (const Quantum *) NULL)
1208             break;
1209           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1210             RedQuantum,pixels,exception);
1211           count=WriteBlob(image,length,pixels);
1212           if (count != (ssize_t) length)
1213             break;
1214         }
1215         if (image->previous == (Image *) NULL)
1216           {
1217             status=SetImageProgress(image,SaveImageTag,1,6);
1218             if (status == MagickFalse)
1219               break;
1220           }
1221         for (y=0; y < (ssize_t) image->rows; y++)
1222         {
1223           register const Quantum
1224             *restrict p;
1225
1226           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1227           if (p == (const Quantum *) NULL)
1228             break;
1229           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1230             GreenQuantum,pixels,exception);
1231           count=WriteBlob(image,length,pixels);
1232           if (count != (ssize_t) length)
1233             break;
1234         }
1235         if (image->previous == (Image *) NULL)
1236           {
1237             status=SetImageProgress(image,SaveImageTag,2,6);
1238             if (status == MagickFalse)
1239               break;
1240           }
1241         for (y=0; y < (ssize_t) image->rows; y++)
1242         {
1243           register const Quantum
1244             *restrict p;
1245
1246           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1247           if (p == (const Quantum *) NULL)
1248             break;
1249           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1250             BlueQuantum,pixels,exception);
1251           count=WriteBlob(image,length,pixels);
1252           if (count != (ssize_t) length)
1253             break;
1254         }
1255         if (image->previous == (Image *) NULL)
1256           {
1257             status=SetImageProgress(image,SaveImageTag,3,6);
1258             if (status == MagickFalse)
1259               break;
1260           }
1261         if (quantum_type == BGRAQuantum)
1262           {
1263             for (y=0; y < (ssize_t) image->rows; y++)
1264             {
1265               register const Quantum
1266                 *restrict p;
1267
1268               p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1269               if (p == (const Quantum *) NULL)
1270                 break;
1271               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1272                 AlphaQuantum,pixels,exception);
1273               count=WriteBlob(image,length,pixels);
1274               if (count != (ssize_t) length)
1275               break;
1276             }
1277             if (image->previous == (Image *) NULL)
1278               {
1279                 status=SetImageProgress(image,SaveImageTag,5,6);
1280                 if (status == MagickFalse)
1281                   break;
1282               }
1283           }
1284         if (image_info->interlace == PartitionInterlace)
1285           (void) CopyMagickString(image->filename,image_info->filename,
1286             MaxTextExtent);
1287         if (image->previous == (Image *) NULL)
1288           {
1289             status=SetImageProgress(image,SaveImageTag,6,6);
1290             if (status == MagickFalse)
1291               break;
1292           }
1293         break;
1294       }
1295       case PartitionInterlace:
1296       {
1297         /*
1298           Partition interlacing:  BBBBBB..., GGGGGG..., RRRRRR...
1299         */
1300         AppendImageFormat("B",image->filename);
1301         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1302           AppendBinaryBlobMode,exception);
1303         if (status == MagickFalse)
1304           return(status);
1305         for (y=0; y < (ssize_t) image->rows; y++)
1306         {
1307           register const Quantum
1308             *restrict p;
1309
1310           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1311           if (p == (const Quantum *) NULL)
1312             break;
1313           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1314             BlueQuantum,pixels,exception);
1315           count=WriteBlob(image,length,pixels);
1316           if (count != (ssize_t) length)
1317             break;
1318         }
1319         if (image->previous == (Image *) NULL)
1320           {
1321             status=SetImageProgress(image,SaveImageTag,1,6);
1322             if (status == MagickFalse)
1323               break;
1324           }
1325         (void) CloseBlob(image);
1326         AppendImageFormat("G",image->filename);
1327         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1328           AppendBinaryBlobMode,exception);
1329         if (status == MagickFalse)
1330           return(status);
1331         for (y=0; y < (ssize_t) image->rows; y++)
1332         {
1333           register const Quantum
1334             *restrict p;
1335
1336           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1337           if (p == (const Quantum *) NULL)
1338             break;
1339           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1340             GreenQuantum,pixels,exception);
1341           count=WriteBlob(image,length,pixels);
1342           if (count != (ssize_t) length)
1343             break;
1344         }
1345         if (image->previous == (Image *) NULL)
1346           {
1347             status=SetImageProgress(image,SaveImageTag,2,6);
1348             if (status == MagickFalse)
1349               break;
1350           }
1351         (void) CloseBlob(image);
1352         AppendImageFormat("R",image->filename);
1353         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1354           AppendBinaryBlobMode,exception);
1355         if (status == MagickFalse)
1356           return(status);
1357         for (y=0; y < (ssize_t) image->rows; y++)
1358         {
1359           register const Quantum
1360             *restrict p;
1361
1362           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1363           if (p == (const Quantum *) NULL)
1364             break;
1365           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1366             RedQuantum,pixels,exception);
1367           count=WriteBlob(image,length,pixels);
1368           if (count != (ssize_t) length)
1369             break;
1370         }
1371         if (image->previous == (Image *) NULL)
1372           {
1373             status=SetImageProgress(image,SaveImageTag,3,6);
1374             if (status == MagickFalse)
1375               break;
1376           }
1377         (void) CloseBlob(image);
1378         if (quantum_type == BGRAQuantum)
1379           {
1380             (void) CloseBlob(image);
1381             AppendImageFormat("A",image->filename);
1382             status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1383               AppendBinaryBlobMode,exception);
1384             if (status == MagickFalse)
1385               return(status);
1386             for (y=0; y < (ssize_t) image->rows; y++)
1387             {
1388               register const Quantum
1389                 *restrict p;
1390
1391               p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1392               if (p == (const Quantum *) NULL)
1393                 break;
1394               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1395                 AlphaQuantum,pixels,exception);
1396               count=WriteBlob(image,length,pixels);
1397               if (count != (ssize_t) length)
1398                 break;
1399             }
1400             if (image->previous == (Image *) NULL)
1401               {
1402                 status=SetImageProgress(image,SaveImageTag,5,6);
1403                 if (status == MagickFalse)
1404                   break;
1405               }
1406           }
1407         (void) CloseBlob(image);
1408         (void) CopyMagickString(image->filename,image_info->filename,
1409           MaxTextExtent);
1410         if (image->previous == (Image *) NULL)
1411           {
1412             status=SetImageProgress(image,SaveImageTag,6,6);
1413             if (status == MagickFalse)
1414               break;
1415           }
1416         break;
1417       }
1418     }
1419     quantum_info=DestroyQuantumInfo(quantum_info);
1420     if (GetNextImageInList(image) == (Image *) NULL)
1421       break;
1422     image=SyncNextImageInList(image);
1423     status=SetImageProgress(image,SaveImagesTag,scene++,
1424       GetImageListLength(image));
1425     if (status == MagickFalse)
1426       break;
1427   } while (image_info->adjoin != MagickFalse);
1428   (void) CloseBlob(image);
1429   return(MagickTrue);
1430 }