2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Raw BGR Image Format %
20 % Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/cache.h"
46 #include "MagickCore/channel.h"
47 #include "MagickCore/colorspace.h"
48 #include "MagickCore/colorspace-private.h"
49 #include "MagickCore/constitute.h"
50 #include "MagickCore/exception.h"
51 #include "MagickCore/exception-private.h"
52 #include "MagickCore/image.h"
53 #include "MagickCore/image-private.h"
54 #include "MagickCore/list.h"
55 #include "MagickCore/magick.h"
56 #include "MagickCore/memory_.h"
57 #include "MagickCore/monitor.h"
58 #include "MagickCore/monitor-private.h"
59 #include "MagickCore/pixel-accessor.h"
60 #include "MagickCore/quantum-private.h"
61 #include "MagickCore/static.h"
62 #include "MagickCore/statistic.h"
63 #include "MagickCore/string_.h"
64 #include "MagickCore/module.h"
65 #include "MagickCore/utility.h"
70 static MagickBooleanType
71 WriteBGRImage(const ImageInfo *,Image *,ExceptionInfo *);
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 % R e a d B G R I m a g e %
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 % ReadBGRImage() reads an image of raw BGR, or BGRA samples and returns
85 % it. It allocates the memory necessary for the new Image structure and
86 % returns a pointer to the new image.
88 % The format of the ReadBGRImage method is:
90 % Image *ReadBGRImage(const ImageInfo *image_info,
91 % ExceptionInfo *exception)
93 % A description of each parameter follows:
95 % o image_info: the image info.
97 % o exception: return any errors or warnings in this structure.
100 static Image *ReadBGRImage(const ImageInfo *image_info,
101 ExceptionInfo *exception)
135 assert(image_info != (const ImageInfo *) NULL);
136 assert(image_info->signature == MagickSignature);
137 if (image_info->debug != MagickFalse)
138 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
139 image_info->filename);
140 assert(exception != (ExceptionInfo *) NULL);
141 assert(exception->signature == MagickSignature);
142 image=AcquireImage(image_info,exception);
143 if ((image->columns == 0) || (image->rows == 0))
144 ThrowReaderException(OptionError,"MustSpecifyImageSize");
145 if (image_info->interlace != PartitionInterlace)
147 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
148 if (status == MagickFalse)
150 image=DestroyImageList(image);
151 return((Image *) NULL);
153 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
154 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
158 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
160 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
162 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
164 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
165 if (quantum_info == (QuantumInfo *) NULL)
166 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
167 quantum_type=BGRQuantum;
168 if (LocaleCompare(image_info->magick,"BGRA") == 0)
170 quantum_type=BGRAQuantum;
171 image->alpha_trait=BlendPixelTrait;
172 canvas_image->alpha_trait=BlendPixelTrait;
174 if (LocaleCompare(image_info->magick,"BGRO") == 0)
176 quantum_type=BGROQuantum;
177 image->alpha_trait=BlendPixelTrait;
178 canvas_image->alpha_trait=BlendPixelTrait;
180 pixels=(const void *) NULL;
181 if (image_info->number_scenes != 0)
182 while (image->scene < image_info->scene)
188 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
189 for (y=0; y < (ssize_t) image->rows; y++)
191 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
193 if (count != (ssize_t) length)
203 Read pixels to virtual canvas image then push to image.
205 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
206 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
208 status=SetImageExtent(image,image->columns,image->rows,exception);
209 if (status == MagickFalse)
210 return(DestroyImageList(image));
211 switch (image_info->interlace)
217 No interlacing: BGRBGRBGRBGRBGRBGR...
221 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
222 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
225 for (y=0; y < (ssize_t) image->extract_info.height; y++)
227 register const Quantum
236 if (count != (ssize_t) length)
238 ThrowFileException(exception,CorruptImageError,
239 "UnexpectedEndOfFile",image->filename);
242 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
244 if (q == (Quantum *) NULL)
246 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
247 quantum_info,quantum_type,pixels,exception);
248 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
250 if (((y-image->extract_info.y) >= 0) &&
251 ((y-image->extract_info.y) < (ssize_t) image->rows))
253 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
254 canvas_image->columns,1,exception);
255 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
256 image->columns,1,exception);
257 if ((p == (const Quantum *) NULL) ||
258 (q == (Quantum *) NULL))
260 for (x=0; x < (ssize_t) image->columns; x++)
262 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
263 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
264 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
265 SetPixelAlpha(image,OpaqueAlpha,q);
266 if (image->alpha_trait != UndefinedPixelTrait)
267 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
268 p+=GetPixelChannels(canvas_image);
269 q+=GetPixelChannels(image);
271 if (SyncAuthenticPixels(image,exception) == MagickFalse)
274 if (image->previous == (Image *) NULL)
276 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
278 if (status == MagickFalse)
281 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
298 Line interlacing: BBB...GGG...RRR...RRR...GGG...BBB...
302 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
303 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
306 for (y=0; y < (ssize_t) image->extract_info.height; y++)
308 register const Quantum
317 if (count != (ssize_t) length)
319 ThrowFileException(exception,CorruptImageError,
320 "UnexpectedEndOfFile",image->filename);
323 for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 4 : 3); i++)
325 quantum_type=quantum_types[i];
326 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
328 if (q == (Quantum *) NULL)
330 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
331 quantum_info,quantum_type,pixels,exception);
332 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
334 if (((y-image->extract_info.y) >= 0) &&
335 ((y-image->extract_info.y) < (ssize_t) image->rows))
337 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
338 canvas_image->columns,1,exception);
339 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
340 image->columns,1,exception);
341 if ((p == (const Quantum *) NULL) ||
342 (q == (Quantum *) NULL))
344 for (x=0; x < (ssize_t) image->columns; x++)
346 switch (quantum_type)
350 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
355 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
360 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
365 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
370 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
376 p+=GetPixelChannels(canvas_image);
377 q+=GetPixelChannels(image);
379 if (SyncAuthenticPixels(image,exception) == MagickFalse)
382 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
385 if (image->previous == (Image *) NULL)
387 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
389 if (status == MagickFalse)
398 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
402 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
403 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
406 for (y=0; y < (ssize_t) image->extract_info.height; y++)
408 register const Quantum
417 if (count != (ssize_t) length)
419 ThrowFileException(exception,CorruptImageError,
420 "UnexpectedEndOfFile",image->filename);
423 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
425 if (q == (Quantum *) NULL)
427 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
428 quantum_info,RedQuantum,pixels,exception);
429 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
431 if (((y-image->extract_info.y) >= 0) &&
432 ((y-image->extract_info.y) < (ssize_t) image->rows))
434 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
435 canvas_image->columns,1,exception);
436 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
437 image->columns,1,exception);
438 if ((p == (const Quantum *) NULL) ||
439 (q == (Quantum *) NULL))
441 for (x=0; x < (ssize_t) image->columns; x++)
443 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
444 p+=GetPixelChannels(canvas_image);
445 q+=GetPixelChannels(image);
447 if (SyncAuthenticPixels(image,exception) == MagickFalse)
450 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
453 if (image->previous == (Image *) NULL)
455 status=SetImageProgress(image,LoadImageTag,1,6);
456 if (status == MagickFalse)
459 for (y=0; y < (ssize_t) image->extract_info.height; y++)
461 register const Quantum
470 if (count != (ssize_t) length)
472 ThrowFileException(exception,CorruptImageError,
473 "UnexpectedEndOfFile",image->filename);
476 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
478 if (q == (Quantum *) NULL)
480 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
481 quantum_info,GreenQuantum,pixels,exception);
482 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
484 if (((y-image->extract_info.y) >= 0) &&
485 ((y-image->extract_info.y) < (ssize_t) image->rows))
487 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
488 canvas_image->columns,1,exception);
489 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
490 image->columns,1,exception);
491 if ((p == (const Quantum *) NULL) ||
492 (q == (Quantum *) NULL))
494 for (x=0; x < (ssize_t) image->columns; x++)
496 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
497 p+=GetPixelChannels(canvas_image);
498 q+=GetPixelChannels(image);
500 if (SyncAuthenticPixels(image,exception) == MagickFalse)
503 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
506 if (image->previous == (Image *) NULL)
508 status=SetImageProgress(image,LoadImageTag,2,6);
509 if (status == MagickFalse)
512 for (y=0; y < (ssize_t) image->extract_info.height; y++)
514 register const Quantum
523 if (count != (ssize_t) length)
525 ThrowFileException(exception,CorruptImageError,
526 "UnexpectedEndOfFile",image->filename);
529 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
531 if (q == (Quantum *) NULL)
533 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
534 quantum_info,BlueQuantum,pixels,exception);
535 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
537 if (((y-image->extract_info.y) >= 0) &&
538 ((y-image->extract_info.y) < (ssize_t) image->rows))
540 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
541 canvas_image->columns,1,exception);
542 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
543 image->columns,1,exception);
544 if ((p == (const Quantum *) NULL) ||
545 (q == (Quantum *) NULL))
547 for (x=0; x < (ssize_t) image->columns; x++)
549 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
550 p+=GetPixelChannels(canvas_image);
551 q+=GetPixelChannels(image);
553 if (SyncAuthenticPixels(image,exception) == MagickFalse)
556 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
559 if (image->previous == (Image *) NULL)
561 status=SetImageProgress(image,LoadImageTag,3,6);
562 if (status == MagickFalse)
565 if (image->previous == (Image *) NULL)
567 status=SetImageProgress(image,LoadImageTag,4,6);
568 if (status == MagickFalse)
571 if (image->alpha_trait != UndefinedPixelTrait)
573 for (y=0; y < (ssize_t) image->extract_info.height; y++)
575 register const Quantum
584 if (count != (ssize_t) length)
586 ThrowFileException(exception,CorruptImageError,
587 "UnexpectedEndOfFile",image->filename);
590 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
592 if (q == (Quantum *) NULL)
594 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
595 quantum_info,AlphaQuantum,pixels,exception);
596 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
598 if (((y-image->extract_info.y) >= 0) &&
599 ((y-image->extract_info.y) < (ssize_t) image->rows))
601 p=GetVirtualPixels(canvas_image,
602 canvas_image->extract_info.x,0,canvas_image->columns,1,
604 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
605 image->columns,1,exception);
606 if ((p == (const Quantum *) NULL) ||
607 (q == (Quantum *) NULL))
609 for (x=0; x < (ssize_t) image->columns; x++)
611 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
612 p+=GetPixelChannels(canvas_image);
613 q+=GetPixelChannels(image);
615 if (SyncAuthenticPixels(image,exception) == MagickFalse)
618 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
621 if (image->previous == (Image *) NULL)
623 status=SetImageProgress(image,LoadImageTag,5,6);
624 if (status == MagickFalse)
628 if (image->previous == (Image *) NULL)
630 status=SetImageProgress(image,LoadImageTag,6,6);
631 if (status == MagickFalse)
636 case PartitionInterlace:
639 Partition interlacing: BBBBBB..., GGGGGG..., RRRRRR...
641 AppendImageFormat("B",image->filename);
642 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
643 if (status == MagickFalse)
645 canvas_image=DestroyImageList(canvas_image);
646 image=DestroyImageList(image);
647 return((Image *) NULL);
649 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
650 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
652 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
653 for (i=0; i < (ssize_t) scene; i++)
654 for (y=0; y < (ssize_t) image->extract_info.height; y++)
656 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
658 if (count != (ssize_t) length)
660 ThrowFileException(exception,CorruptImageError,
661 "UnexpectedEndOfFile",image->filename);
665 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
667 for (y=0; y < (ssize_t) image->extract_info.height; y++)
669 register const Quantum
678 if (count != (ssize_t) length)
680 ThrowFileException(exception,CorruptImageError,
681 "UnexpectedEndOfFile",image->filename);
684 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
686 if (q == (Quantum *) NULL)
688 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
689 quantum_info,BlueQuantum,pixels,exception);
690 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
692 if (((y-image->extract_info.y) >= 0) &&
693 ((y-image->extract_info.y) < (ssize_t) image->rows))
695 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
696 canvas_image->columns,1,exception);
697 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
698 image->columns,1,exception);
699 if ((p == (const Quantum *) NULL) ||
700 (q == (Quantum *) NULL))
702 for (x=0; x < (ssize_t) image->columns; x++)
704 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
705 p+=GetPixelChannels(canvas_image);
706 q+=GetPixelChannels(image);
708 if (SyncAuthenticPixels(image,exception) == MagickFalse)
711 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
714 if (image->previous == (Image *) NULL)
716 status=SetImageProgress(image,LoadImageTag,1,5);
717 if (status == MagickFalse)
720 (void) CloseBlob(image);
721 AppendImageFormat("G",image->filename);
722 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
723 if (status == MagickFalse)
725 canvas_image=DestroyImageList(canvas_image);
726 image=DestroyImageList(image);
727 return((Image *) NULL);
729 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
730 for (i=0; i < (ssize_t) scene; i++)
731 for (y=0; y < (ssize_t) image->extract_info.height; y++)
733 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
735 if (count != (ssize_t) length)
737 ThrowFileException(exception,CorruptImageError,
738 "UnexpectedEndOfFile",image->filename);
742 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
744 for (y=0; y < (ssize_t) image->extract_info.height; y++)
746 register const Quantum
755 if (count != (ssize_t) length)
757 ThrowFileException(exception,CorruptImageError,
758 "UnexpectedEndOfFile",image->filename);
761 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
763 if (q == (Quantum *) NULL)
765 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
766 quantum_info,GreenQuantum,pixels,exception);
767 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
769 if (((y-image->extract_info.y) >= 0) &&
770 ((y-image->extract_info.y) < (ssize_t) image->rows))
772 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
773 canvas_image->columns,1,exception);
774 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
775 image->columns,1,exception);
776 if ((p == (const Quantum *) NULL) ||
777 (q == (Quantum *) NULL))
779 for (x=0; x < (ssize_t) image->columns; x++)
781 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
782 p+=GetPixelChannels(canvas_image);
783 q+=GetPixelChannels(image);
785 if (SyncAuthenticPixels(image,exception) == MagickFalse)
788 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
791 if (image->previous == (Image *) NULL)
793 status=SetImageProgress(image,LoadImageTag,2,5);
794 if (status == MagickFalse)
797 (void) CloseBlob(image);
798 AppendImageFormat("R",image->filename);
799 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
800 if (status == MagickFalse)
802 canvas_image=DestroyImageList(canvas_image);
803 image=DestroyImageList(image);
804 return((Image *) NULL);
806 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
807 for (i=0; i < (ssize_t) scene; i++)
808 for (y=0; y < (ssize_t) image->extract_info.height; y++)
810 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
812 if (count != (ssize_t) length)
814 ThrowFileException(exception,CorruptImageError,
815 "UnexpectedEndOfFile",image->filename);
819 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
821 for (y=0; y < (ssize_t) image->extract_info.height; y++)
823 register const Quantum
832 if (count != (ssize_t) length)
834 ThrowFileException(exception,CorruptImageError,
835 "UnexpectedEndOfFile",image->filename);
838 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
840 if (q == (Quantum *) NULL)
842 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
843 quantum_info,RedQuantum,pixels,exception);
844 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
846 if (((y-image->extract_info.y) >= 0) &&
847 ((y-image->extract_info.y) < (ssize_t) image->rows))
849 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
850 canvas_image->columns,1,exception);
851 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
852 image->columns,1,exception);
853 if ((p == (const Quantum *) NULL) ||
854 (q == (Quantum *) NULL))
856 for (x=0; x < (ssize_t) image->columns; x++)
858 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
859 p+=GetPixelChannels(canvas_image);
860 q+=GetPixelChannels(image);
862 if (SyncAuthenticPixels(image,exception) == MagickFalse)
865 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
868 if (image->previous == (Image *) NULL)
870 status=SetImageProgress(image,LoadImageTag,3,5);
871 if (status == MagickFalse)
874 if (image->alpha_trait != UndefinedPixelTrait)
876 (void) CloseBlob(image);
877 AppendImageFormat("A",image->filename);
878 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
879 if (status == MagickFalse)
881 canvas_image=DestroyImageList(canvas_image);
882 image=DestroyImageList(image);
883 return((Image *) NULL);
885 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
886 for (i=0; i < (ssize_t) scene; i++)
887 for (y=0; y < (ssize_t) image->extract_info.height; y++)
889 pixels=ReadBlobStream(image,length,
890 GetQuantumPixels(quantum_info),&count);
891 if (count != (ssize_t) length)
893 ThrowFileException(exception,CorruptImageError,
894 "UnexpectedEndOfFile",image->filename);
898 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
900 for (y=0; y < (ssize_t) image->extract_info.height; y++)
902 register const Quantum
911 if (count != (ssize_t) length)
913 ThrowFileException(exception,CorruptImageError,
914 "UnexpectedEndOfFile",image->filename);
917 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
919 if (q == (Quantum *) NULL)
921 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
922 quantum_info,BlueQuantum,pixels,exception);
923 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
925 if (((y-image->extract_info.y) >= 0) &&
926 ((y-image->extract_info.y) < (ssize_t) image->rows))
928 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
929 0,canvas_image->columns,1,exception);
930 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
931 image->columns,1,exception);
932 if ((p == (const Quantum *) NULL) ||
933 (q == (Quantum *) NULL))
935 for (x=0; x < (ssize_t) image->columns; x++)
937 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
938 p+=GetPixelChannels(canvas_image);
939 q+=GetPixelChannels(image);
941 if (SyncAuthenticPixels(image,exception) == MagickFalse)
944 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
947 if (image->previous == (Image *) NULL)
949 status=SetImageProgress(image,LoadImageTag,4,5);
950 if (status == MagickFalse)
954 (void) CloseBlob(image);
955 if (image->previous == (Image *) NULL)
957 status=SetImageProgress(image,LoadImageTag,5,5);
958 if (status == MagickFalse)
964 SetQuantumImageType(image,quantum_type);
966 Proceed to next image.
968 if (image_info->number_scenes != 0)
969 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
971 if (count == (ssize_t) length)
974 Allocate next image structure.
976 AcquireNextImage(image_info,image,exception);
977 if (GetNextImageInList(image) == (Image *) NULL)
979 image=DestroyImageList(image);
980 return((Image *) NULL);
982 image=SyncNextImageInList(image);
983 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
985 if (status == MagickFalse)
989 } while (count == (ssize_t) length);
990 quantum_info=DestroyQuantumInfo(quantum_info);
991 canvas_image=DestroyImage(canvas_image);
992 (void) CloseBlob(image);
993 return(GetFirstImageInList(image));
997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1001 % R e g i s t e r B G R I m a g e %
1005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1007 % RegisterBGRImage() adds attributes for the BGR image format to
1008 % the list of supported formats. The attributes include the image format
1009 % tag, a method to read and/or write the format, whether the format
1010 % supports the saving of more than one frame to the same file or blob,
1011 % whether the format supports native in-memory I/O, and a brief
1012 % description of the format.
1014 % The format of the RegisterBGRImage method is:
1016 % size_t RegisterBGRImage(void)
1019 ModuleExport size_t RegisterBGRImage(void)
1024 entry=SetMagickInfo("BGR");
1025 entry->decoder=(DecodeImageHandler *) ReadBGRImage;
1026 entry->encoder=(EncodeImageHandler *) WriteBGRImage;
1027 entry->flags|=CoderRawSupportFlag;
1028 entry->flags|=CoderEndianSupportFlag;
1029 entry->description=ConstantString("Raw blue, green, and red samples");
1030 entry->module=ConstantString("BGR");
1031 (void) RegisterMagickInfo(entry);
1032 entry=SetMagickInfo("BGRA");
1033 entry->decoder=(DecodeImageHandler *) ReadBGRImage;
1034 entry->encoder=(EncodeImageHandler *) WriteBGRImage;
1035 entry->flags|=CoderRawSupportFlag;
1036 entry->flags|=CoderEndianSupportFlag;
1037 entry->description=ConstantString("Raw blue, green, red, and alpha samples");
1038 entry->module=ConstantString("BGR");
1039 (void) RegisterMagickInfo(entry);
1040 entry=SetMagickInfo("BGRO");
1041 entry->decoder=(DecodeImageHandler *) ReadBGRImage;
1042 entry->encoder=(EncodeImageHandler *) WriteBGRImage;
1043 entry->flags|=CoderRawSupportFlag;
1044 entry->flags|=CoderEndianSupportFlag;
1045 entry->description=ConstantString("Raw blue, green, red, and opacity samples");
1046 entry->module=ConstantString("BGR");
1047 (void) RegisterMagickInfo(entry);
1048 return(MagickImageCoderSignature);
1052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1056 % U n r e g i s t e r B G R I m a g e %
1060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1062 % UnregisterBGRImage() removes format registrations made by the BGR module
1063 % from the list of supported formats.
1065 % The format of the UnregisterBGRImage method is:
1067 % UnregisterBGRImage(void)
1070 ModuleExport void UnregisterBGRImage(void)
1072 (void) UnregisterMagickInfo("BGRA");
1073 (void) UnregisterMagickInfo("BGR");
1077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1081 % W r i t e B G R I m a g e %
1085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1087 % WriteBGRImage() writes an image to a file in the BGR or BGRA
1088 % rasterfile format.
1090 % The format of the WriteBGRImage method is:
1092 % MagickBooleanType WriteBGRImage(const ImageInfo *image_info,
1093 % Image *image,ExceptionInfo *exception)
1095 % A description of each parameter follows.
1097 % o image_info: the image info.
1099 % o image: The image.
1101 % o exception: return any errors or warnings in this structure.
1104 static MagickBooleanType WriteBGRImage(const ImageInfo *image_info,Image *image,
1105 ExceptionInfo *exception)
1130 Allocate memory for pixels.
1132 assert(image_info != (const ImageInfo *) NULL);
1133 assert(image_info->signature == MagickSignature);
1134 assert(image != (Image *) NULL);
1135 assert(image->signature == MagickSignature);
1136 if (image->debug != MagickFalse)
1137 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1138 if (image_info->interlace != PartitionInterlace)
1141 Open output image file.
1143 assert(exception != (ExceptionInfo *) NULL);
1144 assert(exception->signature == MagickSignature);
1145 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1146 if (status == MagickFalse)
1149 quantum_type=BGRQuantum;
1150 if (LocaleCompare(image_info->magick,"BGRA") == 0)
1152 quantum_type=BGRAQuantum;
1153 image->alpha_trait=BlendPixelTrait;
1159 Convert MIFF to BGR raster pixels.
1161 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1162 if ((LocaleCompare(image_info->magick,"BGRA") == 0) &&
1163 (image->alpha_trait == UndefinedPixelTrait))
1164 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1165 quantum_info=AcquireQuantumInfo(image_info,image);
1166 if (quantum_info == (QuantumInfo *) NULL)
1167 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1168 pixels=GetQuantumPixels(quantum_info);
1169 switch (image_info->interlace)
1175 No interlacing: BGRBGRBGRBGRBGRBGR...
1177 for (y=0; y < (ssize_t) image->rows; y++)
1179 register const Quantum
1182 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1183 if (p == (const Quantum *) NULL)
1185 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1186 quantum_type,pixels,exception);
1187 count=WriteBlob(image,length,pixels);
1188 if (count != (ssize_t) length)
1190 if (image->previous == (Image *) NULL)
1192 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1194 if (status == MagickFalse)
1203 Line interlacing: BBB...GGG...RRR...RRR...GGG...BBB...
1205 for (y=0; y < (ssize_t) image->rows; y++)
1207 register const Quantum
1210 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1211 if (p == (const Quantum *) NULL)
1213 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1214 BlueQuantum,pixels,exception);
1215 count=WriteBlob(image,length,pixels);
1216 if (count != (ssize_t) length)
1218 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1219 GreenQuantum,pixels,exception);
1220 count=WriteBlob(image,length,pixels);
1221 if (count != (ssize_t) length)
1223 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1224 RedQuantum,pixels,exception);
1225 count=WriteBlob(image,length,pixels);
1226 if (count != (ssize_t) length)
1228 if (quantum_type == BGRAQuantum)
1230 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1231 AlphaQuantum,pixels,exception);
1232 count=WriteBlob(image,length,pixels);
1233 if (count != (ssize_t) length)
1236 if (image->previous == (Image *) NULL)
1238 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1240 if (status == MagickFalse)
1246 case PlaneInterlace:
1249 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1251 for (y=0; y < (ssize_t) image->rows; y++)
1253 register const Quantum
1256 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1257 if (p == (const Quantum *) NULL)
1259 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1260 RedQuantum,pixels,exception);
1261 count=WriteBlob(image,length,pixels);
1262 if (count != (ssize_t) length)
1265 if (image->previous == (Image *) NULL)
1267 status=SetImageProgress(image,SaveImageTag,1,6);
1268 if (status == MagickFalse)
1271 for (y=0; y < (ssize_t) image->rows; y++)
1273 register const Quantum
1276 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1277 if (p == (const Quantum *) NULL)
1279 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1280 GreenQuantum,pixels,exception);
1281 count=WriteBlob(image,length,pixels);
1282 if (count != (ssize_t) length)
1285 if (image->previous == (Image *) NULL)
1287 status=SetImageProgress(image,SaveImageTag,2,6);
1288 if (status == MagickFalse)
1291 for (y=0; y < (ssize_t) image->rows; y++)
1293 register const Quantum
1296 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1297 if (p == (const Quantum *) NULL)
1299 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1300 BlueQuantum,pixels,exception);
1301 count=WriteBlob(image,length,pixels);
1302 if (count != (ssize_t) length)
1305 if (image->previous == (Image *) NULL)
1307 status=SetImageProgress(image,SaveImageTag,3,6);
1308 if (status == MagickFalse)
1311 if (quantum_type == BGRAQuantum)
1313 for (y=0; y < (ssize_t) image->rows; y++)
1315 register const Quantum
1318 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1319 if (p == (const Quantum *) NULL)
1321 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1322 AlphaQuantum,pixels,exception);
1323 count=WriteBlob(image,length,pixels);
1324 if (count != (ssize_t) length)
1327 if (image->previous == (Image *) NULL)
1329 status=SetImageProgress(image,SaveImageTag,5,6);
1330 if (status == MagickFalse)
1334 if (image_info->interlace == PartitionInterlace)
1335 (void) CopyMagickString(image->filename,image_info->filename,
1337 if (image->previous == (Image *) NULL)
1339 status=SetImageProgress(image,SaveImageTag,6,6);
1340 if (status == MagickFalse)
1345 case PartitionInterlace:
1348 Partition interlacing: BBBBBB..., GGGGGG..., RRRRRR...
1350 AppendImageFormat("B",image->filename);
1351 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1352 AppendBinaryBlobMode,exception);
1353 if (status == MagickFalse)
1355 for (y=0; y < (ssize_t) image->rows; y++)
1357 register const Quantum
1360 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1361 if (p == (const Quantum *) NULL)
1363 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1364 BlueQuantum,pixels,exception);
1365 count=WriteBlob(image,length,pixels);
1366 if (count != (ssize_t) length)
1369 if (image->previous == (Image *) NULL)
1371 status=SetImageProgress(image,SaveImageTag,1,6);
1372 if (status == MagickFalse)
1375 (void) CloseBlob(image);
1376 AppendImageFormat("G",image->filename);
1377 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1378 AppendBinaryBlobMode,exception);
1379 if (status == MagickFalse)
1381 for (y=0; y < (ssize_t) image->rows; y++)
1383 register const Quantum
1386 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1387 if (p == (const Quantum *) NULL)
1389 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1390 GreenQuantum,pixels,exception);
1391 count=WriteBlob(image,length,pixels);
1392 if (count != (ssize_t) length)
1395 if (image->previous == (Image *) NULL)
1397 status=SetImageProgress(image,SaveImageTag,2,6);
1398 if (status == MagickFalse)
1401 (void) CloseBlob(image);
1402 AppendImageFormat("R",image->filename);
1403 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1404 AppendBinaryBlobMode,exception);
1405 if (status == MagickFalse)
1407 for (y=0; y < (ssize_t) image->rows; y++)
1409 register const Quantum
1412 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1413 if (p == (const Quantum *) NULL)
1415 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1416 RedQuantum,pixels,exception);
1417 count=WriteBlob(image,length,pixels);
1418 if (count != (ssize_t) length)
1421 if (image->previous == (Image *) NULL)
1423 status=SetImageProgress(image,SaveImageTag,3,6);
1424 if (status == MagickFalse)
1427 (void) CloseBlob(image);
1428 if (quantum_type == BGRAQuantum)
1430 (void) CloseBlob(image);
1431 AppendImageFormat("A",image->filename);
1432 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1433 AppendBinaryBlobMode,exception);
1434 if (status == MagickFalse)
1436 for (y=0; y < (ssize_t) image->rows; y++)
1438 register const Quantum
1441 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1442 if (p == (const Quantum *) NULL)
1444 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1445 AlphaQuantum,pixels,exception);
1446 count=WriteBlob(image,length,pixels);
1447 if (count != (ssize_t) length)
1450 if (image->previous == (Image *) NULL)
1452 status=SetImageProgress(image,SaveImageTag,5,6);
1453 if (status == MagickFalse)
1457 (void) CloseBlob(image);
1458 (void) CopyMagickString(image->filename,image_info->filename,
1460 if (image->previous == (Image *) NULL)
1462 status=SetImageProgress(image,SaveImageTag,6,6);
1463 if (status == MagickFalse)
1469 quantum_info=DestroyQuantumInfo(quantum_info);
1470 if (GetNextImageInList(image) == (Image *) NULL)
1472 image=SyncNextImageInList(image);
1473 status=SetImageProgress(image,SaveImagesTag,scene++,
1474 GetImageListLength(image));
1475 if (status == MagickFalse)
1477 } while (image_info->adjoin != MagickFalse);
1478 (void) CloseBlob(image);