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