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