]> 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     exception);
164   quantum_info=AcquireQuantumInfo(image_info,canvas_image);
165   if (quantum_info == (QuantumInfo *) NULL)
166     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
167   pixels=GetQuantumPixels(quantum_info);
168   quantum_type=BGRQuantum;
169   if (LocaleCompare(image_info->magick,"BGRA") == 0)
170     {
171       quantum_type=BGRAQuantum;
172       image->matte=MagickTrue;
173     }
174   if (image_info->number_scenes != 0)
175     while (image->scene < image_info->scene)
176     {
177       /*
178         Skip to next image.
179       */
180       image->scene++;
181       length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
182       for (y=0; y < (ssize_t) image->rows; y++)
183       {
184         count=ReadBlob(image,length,pixels);
185         if (count != (ssize_t) length)
186           break;
187       }
188     }
189   count=0;
190   length=0;
191   scene=0;
192   do
193   {
194     /*
195       Read pixels to virtual canvas image then push to image.
196     */
197     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
198       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
199         break;
200     image->colorspace=RGBColorspace;
201     switch (image_info->interlace)
202     {
203       case NoInterlace:
204       default:
205       {
206         /*
207           No interlacing:  BGRBGRBGRBGRBGRBGR...
208         */
209         if (scene == 0)
210           {
211             length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
212             count=ReadBlob(image,length,pixels);
213           }
214         for (y=0; y < (ssize_t) image->extract_info.height; y++)
215         {
216           register const Quantum
217             *restrict p;
218
219           register Quantum
220             *restrict q;
221
222           register ssize_t
223             x;
224
225           if (count != (ssize_t) length)
226             {
227               ThrowFileException(exception,CorruptImageError,
228                 "UnexpectedEndOfFile",image->filename);
229               break;
230             }
231           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
232             exception);
233           if (q == (Quantum *) NULL)
234             break;
235           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
236             quantum_info,quantum_type,pixels,exception);
237           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
238             break;
239           if (((y-image->extract_info.y) >= 0) && 
240               ((y-image->extract_info.y) < (ssize_t) image->rows))
241             {
242               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
243                 canvas_image->columns,1,exception);
244               q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
245                 image->columns,1,exception);
246               if ((p == (const Quantum *) NULL) ||
247                   (q == (Quantum *) NULL))
248                 break;
249               for (x=0; x < (ssize_t) image->columns; x++)
250               {
251                 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
252                 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
253                 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
254                 SetPixelAlpha(image,OpaqueAlpha,q);
255                 if (image->matte != MagickFalse)
256                   SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
257                 p+=GetPixelChannels(canvas_image);
258                 q+=GetPixelChannels(image);
259               }
260               if (SyncAuthenticPixels(image,exception) == MagickFalse)
261                 break;
262             }
263           if (image->previous == (Image *) NULL)
264             {
265               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
266                 image->rows);
267               if (status == MagickFalse)
268                 break;
269             }
270           count=ReadBlob(image,length,pixels);
271         }
272         break;
273       }
274       case LineInterlace:
275       {
276         static QuantumType
277           quantum_types[4] =
278           {
279             BlueQuantum,
280             GreenQuantum,
281             RedQuantum,
282             AlphaQuantum
283           };
284
285         /*
286           Line interlacing:  BBB...GGG...RRR...RRR...GGG...BBB...
287         */
288         if (scene == 0)
289           {
290             length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
291             count=ReadBlob(image,length,pixels);
292           }
293         for (y=0; y < (ssize_t) image->extract_info.height; y++)
294         {
295           register const Quantum
296             *restrict p;
297
298           register Quantum
299             *restrict q;
300
301           register ssize_t
302             x;
303
304           if (count != (ssize_t) length)
305             {
306               ThrowFileException(exception,CorruptImageError,
307                 "UnexpectedEndOfFile",image->filename);
308               break;
309             }
310           for (i=0; i < (ssize_t) (image->matte != MagickFalse ? 4 : 3); i++)
311           {
312             quantum_type=quantum_types[i];
313             q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
314               exception);
315             if (q == (Quantum *) NULL)
316               break;
317             length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
318               quantum_info,quantum_type,pixels,exception);
319             if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
320               break;
321             if (((y-image->extract_info.y) >= 0) && 
322                 ((y-image->extract_info.y) < (ssize_t) image->rows))
323               {
324                 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
325                   canvas_image->columns,1,exception);
326                 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
327                   image->columns,1,exception);
328                 if ((p == (const Quantum *) NULL) ||
329                     (q == (Quantum *) NULL))
330                   break;
331                 for (x=0; x < (ssize_t) image->columns; x++)
332                 {
333                   switch (quantum_type)
334                   {
335                     case RedQuantum:
336                     {
337                       SetPixelRed(image,GetPixelRed(canvas_image,p),q);
338                       break;
339                     }
340                     case GreenQuantum:
341                     {
342                       SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
343                       break;
344                     }
345                     case BlueQuantum:
346                     {
347                       SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
348                       break;
349                     }
350                     case OpacityQuantum:
351                     {
352                       SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
353                       break;
354                     }
355                     case AlphaQuantum:
356                     {
357                       SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
358                       break;
359                     }
360                     default:
361                       break;
362                   }
363                   p+=GetPixelChannels(canvas_image);
364                   q+=GetPixelChannels(image);
365                 }
366                 if (SyncAuthenticPixels(image,exception) == MagickFalse)
367                   break;
368               }
369             count=ReadBlob(image,length,pixels);
370           }
371           if (image->previous == (Image *) NULL)
372             {
373               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
374                 image->rows);
375               if (status == MagickFalse)
376                 break;
377             }
378         }
379         break;
380       }
381       case PlaneInterlace:
382       {
383         /*
384           Plane interlacing:  RRRRRR...GGGGGG...BBBBBB...
385         */
386         if (scene == 0)
387           {
388             length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
389             count=ReadBlob(image,length,pixels);
390           }
391         for (y=0; y < (ssize_t) image->extract_info.height; y++)
392         {
393           register const Quantum
394             *restrict p;
395
396           register Quantum
397             *restrict q;
398
399           register ssize_t
400             x;
401
402           if (count != (ssize_t) length)
403             {
404               ThrowFileException(exception,CorruptImageError,
405                 "UnexpectedEndOfFile",image->filename);
406               break;
407             }
408           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
409             exception);
410           if (q == (Quantum *) NULL)
411             break;
412           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
413             quantum_info,RedQuantum,pixels,exception);
414           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
415             break;
416           if (((y-image->extract_info.y) >= 0) && 
417               ((y-image->extract_info.y) < (ssize_t) image->rows))
418             {
419               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
420                 canvas_image->columns,1,exception);
421               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
422                 image->columns,1,exception);
423               if ((p == (const Quantum *) NULL) ||
424                   (q == (Quantum *) NULL))
425                 break;
426               for (x=0; x < (ssize_t) image->columns; x++)
427               {
428                 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
429                 p+=GetPixelChannels(canvas_image);
430                 q+=GetPixelChannels(image);
431               }
432               if (SyncAuthenticPixels(image,exception) == MagickFalse)
433                 break;
434             }
435           count=ReadBlob(image,length,pixels);
436         }
437         if (image->previous == (Image *) NULL)
438           {
439             status=SetImageProgress(image,LoadImageTag,1,6);
440             if (status == MagickFalse)
441               break;
442           }
443         for (y=0; y < (ssize_t) image->extract_info.height; y++)
444         {
445           register const Quantum
446             *restrict p;
447
448           register Quantum
449             *restrict q;
450
451           register ssize_t
452             x;
453
454           if (count != (ssize_t) length)
455             {
456               ThrowFileException(exception,CorruptImageError,
457                 "UnexpectedEndOfFile",image->filename);
458               break;
459             }
460           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
461             exception);
462           if (q == (Quantum *) NULL)
463             break;
464           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
465             quantum_info,GreenQuantum,pixels,exception);
466           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
467             break;
468           if (((y-image->extract_info.y) >= 0) && 
469               ((y-image->extract_info.y) < (ssize_t) image->rows))
470             {
471               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
472                 canvas_image->columns,1,exception);
473               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
474                 image->columns,1,exception);
475               if ((p == (const Quantum *) NULL) ||
476                   (q == (Quantum *) NULL))
477                 break;
478               for (x=0; x < (ssize_t) image->columns; x++)
479               {
480                 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
481                 p+=GetPixelChannels(canvas_image);
482                 q+=GetPixelChannels(image);
483               }
484               if (SyncAuthenticPixels(image,exception) == MagickFalse)
485                 break;
486            }
487           count=ReadBlob(image,length,pixels);
488         }
489         if (image->previous == (Image *) NULL)
490           {
491             status=SetImageProgress(image,LoadImageTag,2,6);
492             if (status == MagickFalse)
493               break;
494           }
495         for (y=0; y < (ssize_t) image->extract_info.height; y++)
496         {
497           register const Quantum
498             *restrict p;
499
500           register Quantum
501             *restrict q;
502
503           register ssize_t
504             x;
505
506           if (count != (ssize_t) length)
507             {
508               ThrowFileException(exception,CorruptImageError,
509                 "UnexpectedEndOfFile",image->filename);
510               break;
511             }
512           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
513             exception);
514           if (q == (Quantum *) NULL)
515             break;
516           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
517             quantum_info,BlueQuantum,pixels,exception);
518           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
519             break;
520           if (((y-image->extract_info.y) >= 0) && 
521               ((y-image->extract_info.y) < (ssize_t) image->rows))
522             {
523               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
524                 canvas_image->columns,1,exception);
525               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
526                 image->columns,1,exception);
527               if ((p == (const Quantum *) NULL) ||
528                   (q == (Quantum *) NULL))
529                 break;
530               for (x=0; x < (ssize_t) image->columns; x++)
531               {
532                 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
533                 p+=GetPixelChannels(canvas_image);
534                 q+=GetPixelChannels(image);
535               }
536               if (SyncAuthenticPixels(image,exception) == MagickFalse)
537                 break;
538             }
539           count=ReadBlob(image,length,pixels);
540         }
541         if (image->previous == (Image *) NULL)
542           {
543             status=SetImageProgress(image,LoadImageTag,3,6);
544             if (status == MagickFalse)
545               break;
546           }
547         if (image->previous == (Image *) NULL)
548           {
549             status=SetImageProgress(image,LoadImageTag,4,6);
550             if (status == MagickFalse)
551               break;
552           }
553         if (image->matte != MagickFalse)
554           {
555             for (y=0; y < (ssize_t) image->extract_info.height; y++)
556             {
557               register const Quantum
558                 *restrict p;
559
560               register Quantum
561                 *restrict q;
562
563               register ssize_t
564                 x;
565
566               if (count != (ssize_t) length)
567                 {
568                   ThrowFileException(exception,CorruptImageError,
569                     "UnexpectedEndOfFile",image->filename);
570                   break;
571                 }
572               q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
573                 exception);
574               if (q == (Quantum *) NULL)
575                 break;
576               length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
577                 quantum_info,AlphaQuantum,pixels,exception);
578               if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
579                 break;
580               if (((y-image->extract_info.y) >= 0) && 
581                   ((y-image->extract_info.y) < (ssize_t) image->rows))
582                 {
583                   p=GetVirtualPixels(canvas_image,
584                     canvas_image->extract_info.x,0,canvas_image->columns,1,
585                     exception);
586                   q=GetAuthenticPixels(image,0,y-image->extract_info.y,
587                     image->columns,1,exception);
588                   if ((p == (const Quantum *) NULL) ||
589                       (q == (Quantum *) NULL))
590                     break;
591                   for (x=0; x < (ssize_t) image->columns; x++)
592                   {
593                     SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
594                     p+=GetPixelChannels(canvas_image);
595                     q+=GetPixelChannels(image);
596                   }
597                   if (SyncAuthenticPixels(image,exception) == MagickFalse)
598                     break;
599                 }
600               count=ReadBlob(image,length,pixels);
601             }
602             if (image->previous == (Image *) NULL)
603               {
604                 status=SetImageProgress(image,LoadImageTag,5,6);
605                 if (status == MagickFalse)
606                   break;
607               }
608           }
609         if (image->previous == (Image *) NULL)
610           {
611             status=SetImageProgress(image,LoadImageTag,6,6);
612             if (status == MagickFalse)
613               break;
614           }
615         break;
616       }
617       case PartitionInterlace:
618       {
619         /*
620           Partition interlacing:  BBBBBB..., GGGGGG..., RRRRRR...
621         */
622         AppendImageFormat("B",image->filename);
623         status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
624         if (status == MagickFalse)
625           {
626             canvas_image=DestroyImageList(canvas_image);
627             image=DestroyImageList(image);
628             return((Image *) NULL);
629           }
630         if (DiscardBlobBytes(image,image->offset) == MagickFalse)
631           ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
632             image->filename);
633         length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
634         for (i=0; i < (ssize_t) scene; i++)
635           for (y=0; y < (ssize_t) image->extract_info.height; y++)
636             if (ReadBlob(image,length,pixels) != (ssize_t) length)
637               {
638                 ThrowFileException(exception,CorruptImageError,
639                   "UnexpectedEndOfFile",image->filename);
640                 break;
641               }
642         count=ReadBlob(image,length,pixels);
643         for (y=0; y < (ssize_t) image->extract_info.height; y++)
644         {
645           register const Quantum
646             *restrict p;
647
648           register Quantum
649             *restrict q;
650
651           register ssize_t
652             x;
653
654           if (count != (ssize_t) length)
655             {
656               ThrowFileException(exception,CorruptImageError,
657                 "UnexpectedEndOfFile",image->filename);
658               break;
659             }
660           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
661             exception);
662           if (q == (Quantum *) NULL)
663             break;
664           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
665             quantum_info,BlueQuantum,pixels,exception);
666           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
667             break;
668           if (((y-image->extract_info.y) >= 0) && 
669               ((y-image->extract_info.y) < (ssize_t) image->rows))
670             {
671               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
672                 canvas_image->columns,1,exception);
673               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
674                 image->columns,1,exception);
675               if ((p == (const Quantum *) NULL) ||
676                   (q == (Quantum *) NULL))
677                 break;
678               for (x=0; x < (ssize_t) image->columns; x++)
679               {
680                 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
681                 p+=GetPixelChannels(canvas_image);
682                 q+=GetPixelChannels(image);
683               }
684               if (SyncAuthenticPixels(image,exception) == MagickFalse)
685                 break;
686             }
687           count=ReadBlob(image,length,pixels);
688         }
689         if (image->previous == (Image *) NULL)
690           {
691             status=SetImageProgress(image,LoadImageTag,1,5);
692             if (status == MagickFalse)
693               break;
694           }
695         (void) CloseBlob(image);
696         AppendImageFormat("G",image->filename);
697         status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
698         if (status == MagickFalse)
699           {
700             canvas_image=DestroyImageList(canvas_image);
701             image=DestroyImageList(image);
702             return((Image *) NULL);
703           }
704         length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
705         for (i=0; i < (ssize_t) scene; i++)
706           for (y=0; y < (ssize_t) image->extract_info.height; y++)
707             if (ReadBlob(image,length,pixels) != (ssize_t) length)
708               {
709                 ThrowFileException(exception,CorruptImageError,
710                   "UnexpectedEndOfFile",image->filename);
711                 break;
712               }
713         count=ReadBlob(image,length,pixels);
714         for (y=0; y < (ssize_t) image->extract_info.height; y++)
715         {
716           register const Quantum
717             *restrict p;
718
719           register Quantum
720             *restrict q;
721
722           register ssize_t
723             x;
724
725           if (count != (ssize_t) length)
726             {
727               ThrowFileException(exception,CorruptImageError,
728                 "UnexpectedEndOfFile",image->filename);
729               break;
730             }
731           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
732             exception);
733           if (q == (Quantum *) NULL)
734             break;
735           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
736             quantum_info,GreenQuantum,pixels,exception);
737           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
738             break;
739           if (((y-image->extract_info.y) >= 0) && 
740               ((y-image->extract_info.y) < (ssize_t) image->rows))
741             {
742               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
743                 canvas_image->columns,1,exception);
744               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
745                 image->columns,1,exception);
746               if ((p == (const Quantum *) NULL) ||
747                   (q == (Quantum *) NULL))
748                 break;
749               for (x=0; x < (ssize_t) image->columns; x++)
750               {
751                 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
752                 p+=GetPixelChannels(canvas_image);
753                 q+=GetPixelChannels(image);
754               }
755               if (SyncAuthenticPixels(image,exception) == MagickFalse)
756                 break;
757            }
758           count=ReadBlob(image,length,pixels);
759         }
760         if (image->previous == (Image *) NULL)
761           {
762             status=SetImageProgress(image,LoadImageTag,2,5);
763             if (status == MagickFalse)
764               break;
765           }
766         (void) CloseBlob(image);
767         AppendImageFormat("R",image->filename);
768         status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
769         if (status == MagickFalse)
770           {
771             canvas_image=DestroyImageList(canvas_image);
772             image=DestroyImageList(image);
773             return((Image *) NULL);
774           }
775         length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
776         for (i=0; i < (ssize_t) scene; i++)
777           for (y=0; y < (ssize_t) image->extract_info.height; y++)
778             if (ReadBlob(image,length,pixels) != (ssize_t) length)
779               {
780                 ThrowFileException(exception,CorruptImageError,
781                   "UnexpectedEndOfFile",image->filename);
782                 break;
783               }
784         count=ReadBlob(image,length,pixels);
785         for (y=0; y < (ssize_t) image->extract_info.height; y++)
786         {
787           register const Quantum
788             *restrict p;
789
790           register Quantum
791             *restrict q;
792
793           register ssize_t
794             x;
795
796           if (count != (ssize_t) length)
797             {
798               ThrowFileException(exception,CorruptImageError,
799                 "UnexpectedEndOfFile",image->filename);
800               break;
801             }
802           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
803             exception);
804           if (q == (Quantum *) NULL)
805             break;
806           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
807             quantum_info,RedQuantum,pixels,exception);
808           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
809             break;
810           if (((y-image->extract_info.y) >= 0) && 
811               ((y-image->extract_info.y) < (ssize_t) image->rows))
812             {
813               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
814                 canvas_image->columns,1,exception);
815               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
816                 image->columns,1,exception);
817               if ((p == (const Quantum *) NULL) ||
818                   (q == (Quantum *) NULL))
819                 break;
820               for (x=0; x < (ssize_t) image->columns; x++)
821               {
822                 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
823                 p+=GetPixelChannels(canvas_image);
824                 q+=GetPixelChannels(image);
825               }
826               if (SyncAuthenticPixels(image,exception) == MagickFalse)
827                 break;
828            }
829           count=ReadBlob(image,length,pixels);
830         }
831         if (image->previous == (Image *) NULL)
832           {
833             status=SetImageProgress(image,LoadImageTag,3,5);
834             if (status == MagickFalse)
835               break;
836           }
837         if (image->matte != MagickFalse)
838           {
839             (void) CloseBlob(image);
840             AppendImageFormat("A",image->filename);
841             status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
842             if (status == MagickFalse)
843               {
844                 canvas_image=DestroyImageList(canvas_image);
845                 image=DestroyImageList(image);
846                 return((Image *) NULL);
847               }
848             length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
849             for (i=0; i < (ssize_t) scene; i++)
850               for (y=0; y < (ssize_t) image->extract_info.height; y++)
851                 if (ReadBlob(image,length,pixels) != (ssize_t) length)
852                   {
853                     ThrowFileException(exception,CorruptImageError,
854                       "UnexpectedEndOfFile",image->filename);
855                     break;
856                   }
857             count=ReadBlob(image,length,pixels);
858             for (y=0; y < (ssize_t) image->extract_info.height; y++)
859             {
860               register const Quantum
861                 *restrict p;
862
863               register Quantum
864                 *restrict q;
865
866               register ssize_t
867                 x;
868
869               if (count != (ssize_t) length)
870                 {
871                   ThrowFileException(exception,CorruptImageError,
872                     "UnexpectedEndOfFile",image->filename);
873                   break;
874                 }
875               q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
876                 exception);
877               if (q == (Quantum *) NULL)
878                 break;
879               length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
880                 quantum_info,BlueQuantum,pixels,exception);
881               if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
882                 break;
883               if (((y-image->extract_info.y) >= 0) && 
884                   ((y-image->extract_info.y) < (ssize_t) image->rows))
885                 {
886                   p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
887                     0,canvas_image->columns,1,exception);
888                   q=GetAuthenticPixels(image,0,y-image->extract_info.y,
889                     image->columns,1,exception);
890                   if ((p == (const Quantum *) NULL) ||
891                       (q == (Quantum *) NULL))
892                     break;
893                   for (x=0; x < (ssize_t) image->columns; x++)
894                   {
895                     SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
896                     p+=GetPixelChannels(canvas_image);
897                     q+=GetPixelChannels(image);
898                   }
899                   if (SyncAuthenticPixels(image,exception) == MagickFalse)
900                     break;
901                }
902               count=ReadBlob(image,length,pixels);
903             }
904             if (image->previous == (Image *) NULL)
905               {
906                 status=SetImageProgress(image,LoadImageTag,4,5);
907                 if (status == MagickFalse)
908                   break;
909               }
910           }
911         (void) CloseBlob(image);
912         if (image->previous == (Image *) NULL)
913           {
914             status=SetImageProgress(image,LoadImageTag,5,5);
915             if (status == MagickFalse)
916               break;
917           }
918         break;
919       }
920     }
921     SetQuantumImageType(image,quantum_type);
922     /*
923       Proceed to next image.
924     */
925     if (image_info->number_scenes != 0)
926       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
927         break;
928     if (count == (ssize_t) length)
929       {
930         /*
931           Allocate next image structure.
932         */
933         AcquireNextImage(image_info,image,exception);
934         if (GetNextImageInList(image) == (Image *) NULL)
935           {
936             image=DestroyImageList(image);
937             return((Image *) NULL);
938           }
939         image=SyncNextImageInList(image);
940         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
941           GetBlobSize(image));
942         if (status == MagickFalse)
943           break;
944       }
945     scene++;
946   } while (count == (ssize_t) length);
947   quantum_info=DestroyQuantumInfo(quantum_info);
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,sRGBColorspace,exception);
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 }