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