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