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