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