2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Raw BGR Image Format %
20 % Copyright 1999-2017 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 == MagickCoreSignature);
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 == MagickCoreSignature);
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 unsigned char *) 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=(const unsigned char *) ReadBlobStream(image,length,
192 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
223 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
282 GetQuantumPixels(quantum_info),&count);
298 Line interlacing: BBB...GGG...RRR...RRR...GGG...BBB...
302 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
303 pixels=(const unsigned char *) ReadBlobStream(image,length,
304 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
383 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
404 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
451 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
504 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
557 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
619 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
657 GetQuantumPixels(quantum_info),&count);
658 if (count != (ssize_t) length)
660 ThrowFileException(exception,CorruptImageError,
661 "UnexpectedEndOfFile",image->filename);
665 pixels=(const unsigned char *) ReadBlobStream(image,length,
666 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
712 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
734 GetQuantumPixels(quantum_info),&count);
735 if (count != (ssize_t) length)
737 ThrowFileException(exception,CorruptImageError,
738 "UnexpectedEndOfFile",image->filename);
742 pixels=(const unsigned char *) ReadBlobStream(image,length,
743 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
789 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
811 GetQuantumPixels(quantum_info),&count);
812 if (count != (ssize_t) length)
814 ThrowFileException(exception,CorruptImageError,
815 "UnexpectedEndOfFile",image->filename);
819 pixels=(const unsigned char *) ReadBlobStream(image,length,
820 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
866 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
890 GetQuantumPixels(quantum_info),&count);
891 if (count != (ssize_t) length)
893 ThrowFileException(exception,CorruptImageError,
894 "UnexpectedEndOfFile",image->filename);
898 pixels=(const unsigned char *) ReadBlobStream(image,length,
899 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
945 GetQuantumPixels(quantum_info),&count);
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=AcquireMagickInfo("BGR","BGR","Raw blue, green, and red samples");
1025 entry->decoder=(DecodeImageHandler *) ReadBGRImage;
1026 entry->encoder=(EncodeImageHandler *) WriteBGRImage;
1027 entry->flags|=CoderRawSupportFlag;
1028 entry->flags|=CoderEndianSupportFlag;
1029 (void) RegisterMagickInfo(entry);
1030 entry=AcquireMagickInfo("BGR","BGRA",
1031 "Raw blue, green, red, and alpha samples");
1032 entry->decoder=(DecodeImageHandler *) ReadBGRImage;
1033 entry->encoder=(EncodeImageHandler *) WriteBGRImage;
1034 entry->flags|=CoderRawSupportFlag;
1035 entry->flags|=CoderEndianSupportFlag;
1036 (void) RegisterMagickInfo(entry);
1037 entry=AcquireMagickInfo("BGR","BGRO",
1038 "Raw blue, green, red, and opacity samples");
1039 entry->decoder=(DecodeImageHandler *) ReadBGRImage;
1040 entry->encoder=(EncodeImageHandler *) WriteBGRImage;
1041 entry->flags|=CoderRawSupportFlag;
1042 entry->flags|=CoderEndianSupportFlag;
1043 (void) RegisterMagickInfo(entry);
1044 return(MagickImageCoderSignature);
1048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1052 % U n r e g i s t e r B G R I m a g e %
1056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1058 % UnregisterBGRImage() removes format registrations made by the BGR module
1059 % from the list of supported formats.
1061 % The format of the UnregisterBGRImage method is:
1063 % UnregisterBGRImage(void)
1066 ModuleExport void UnregisterBGRImage(void)
1068 (void) UnregisterMagickInfo("BGRA");
1069 (void) UnregisterMagickInfo("BGR");
1073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1077 % W r i t e B G R I m a g e %
1081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1083 % WriteBGRImage() writes an image to a file in the BGR or BGRA
1084 % rasterfile format.
1086 % The format of the WriteBGRImage method is:
1088 % MagickBooleanType WriteBGRImage(const ImageInfo *image_info,
1089 % Image *image,ExceptionInfo *exception)
1091 % A description of each parameter follows.
1093 % o image_info: the image info.
1095 % o image: The image.
1097 % o exception: return any errors or warnings in this structure.
1100 static MagickBooleanType WriteBGRImage(const ImageInfo *image_info,Image *image,
1101 ExceptionInfo *exception)
1126 Allocate memory for pixels.
1128 assert(image_info != (const ImageInfo *) NULL);
1129 assert(image_info->signature == MagickCoreSignature);
1130 assert(image != (Image *) NULL);
1131 assert(image->signature == MagickCoreSignature);
1132 if (image->debug != MagickFalse)
1133 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1134 if (image_info->interlace != PartitionInterlace)
1137 Open output image file.
1139 assert(exception != (ExceptionInfo *) NULL);
1140 assert(exception->signature == MagickCoreSignature);
1141 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1142 if (status == MagickFalse)
1145 quantum_type=BGRQuantum;
1146 if (LocaleCompare(image_info->magick,"BGRA") == 0)
1148 quantum_type=BGRAQuantum;
1149 image->alpha_trait=BlendPixelTrait;
1155 Convert MIFF to BGR raster pixels.
1157 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1158 if ((LocaleCompare(image_info->magick,"BGRA") == 0) &&
1159 (image->alpha_trait == UndefinedPixelTrait))
1160 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1161 quantum_info=AcquireQuantumInfo(image_info,image);
1162 if (quantum_info == (QuantumInfo *) NULL)
1163 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1164 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
1165 switch (image_info->interlace)
1171 No interlacing: BGRBGRBGRBGRBGRBGR...
1173 for (y=0; y < (ssize_t) image->rows; y++)
1175 register const Quantum
1178 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1179 if (p == (const Quantum *) NULL)
1181 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1182 quantum_type,pixels,exception);
1183 count=WriteBlob(image,length,pixels);
1184 if (count != (ssize_t) length)
1186 if (image->previous == (Image *) NULL)
1188 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1190 if (status == MagickFalse)
1199 Line interlacing: BBB...GGG...RRR...RRR...GGG...BBB...
1201 for (y=0; y < (ssize_t) image->rows; y++)
1203 register const Quantum
1206 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1207 if (p == (const Quantum *) NULL)
1209 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1210 BlueQuantum,pixels,exception);
1211 count=WriteBlob(image,length,pixels);
1212 if (count != (ssize_t) length)
1214 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1215 GreenQuantum,pixels,exception);
1216 count=WriteBlob(image,length,pixels);
1217 if (count != (ssize_t) length)
1219 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1220 RedQuantum,pixels,exception);
1221 count=WriteBlob(image,length,pixels);
1222 if (count != (ssize_t) length)
1224 if (quantum_type == BGRAQuantum)
1226 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1227 AlphaQuantum,pixels,exception);
1228 count=WriteBlob(image,length,pixels);
1229 if (count != (ssize_t) length)
1232 if (image->previous == (Image *) NULL)
1234 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1236 if (status == MagickFalse)
1242 case PlaneInterlace:
1245 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1247 for (y=0; y < (ssize_t) image->rows; y++)
1249 register const Quantum
1252 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1253 if (p == (const Quantum *) NULL)
1255 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1256 RedQuantum,pixels,exception);
1257 count=WriteBlob(image,length,pixels);
1258 if (count != (ssize_t) length)
1261 if (image->previous == (Image *) NULL)
1263 status=SetImageProgress(image,SaveImageTag,1,6);
1264 if (status == MagickFalse)
1267 for (y=0; y < (ssize_t) image->rows; y++)
1269 register const Quantum
1272 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1273 if (p == (const Quantum *) NULL)
1275 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1276 GreenQuantum,pixels,exception);
1277 count=WriteBlob(image,length,pixels);
1278 if (count != (ssize_t) length)
1281 if (image->previous == (Image *) NULL)
1283 status=SetImageProgress(image,SaveImageTag,2,6);
1284 if (status == MagickFalse)
1287 for (y=0; y < (ssize_t) image->rows; y++)
1289 register const Quantum
1292 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1293 if (p == (const Quantum *) NULL)
1295 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1296 BlueQuantum,pixels,exception);
1297 count=WriteBlob(image,length,pixels);
1298 if (count != (ssize_t) length)
1301 if (image->previous == (Image *) NULL)
1303 status=SetImageProgress(image,SaveImageTag,3,6);
1304 if (status == MagickFalse)
1307 if (quantum_type == BGRAQuantum)
1309 for (y=0; y < (ssize_t) image->rows; y++)
1311 register const Quantum
1314 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1315 if (p == (const Quantum *) NULL)
1317 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1318 AlphaQuantum,pixels,exception);
1319 count=WriteBlob(image,length,pixels);
1320 if (count != (ssize_t) length)
1323 if (image->previous == (Image *) NULL)
1325 status=SetImageProgress(image,SaveImageTag,5,6);
1326 if (status == MagickFalse)
1330 if (image_info->interlace == PartitionInterlace)
1331 (void) CopyMagickString(image->filename,image_info->filename,
1333 if (image->previous == (Image *) NULL)
1335 status=SetImageProgress(image,SaveImageTag,6,6);
1336 if (status == MagickFalse)
1341 case PartitionInterlace:
1344 Partition interlacing: BBBBBB..., GGGGGG..., RRRRRR...
1346 AppendImageFormat("B",image->filename);
1347 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1348 AppendBinaryBlobMode,exception);
1349 if (status == MagickFalse)
1351 for (y=0; y < (ssize_t) image->rows; y++)
1353 register const Quantum
1356 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1357 if (p == (const Quantum *) NULL)
1359 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1360 BlueQuantum,pixels,exception);
1361 count=WriteBlob(image,length,pixels);
1362 if (count != (ssize_t) length)
1365 if (image->previous == (Image *) NULL)
1367 status=SetImageProgress(image,SaveImageTag,1,6);
1368 if (status == MagickFalse)
1371 (void) CloseBlob(image);
1372 AppendImageFormat("G",image->filename);
1373 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1374 AppendBinaryBlobMode,exception);
1375 if (status == MagickFalse)
1377 for (y=0; y < (ssize_t) image->rows; y++)
1379 register const Quantum
1382 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1383 if (p == (const Quantum *) NULL)
1385 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1386 GreenQuantum,pixels,exception);
1387 count=WriteBlob(image,length,pixels);
1388 if (count != (ssize_t) length)
1391 if (image->previous == (Image *) NULL)
1393 status=SetImageProgress(image,SaveImageTag,2,6);
1394 if (status == MagickFalse)
1397 (void) CloseBlob(image);
1398 AppendImageFormat("R",image->filename);
1399 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1400 AppendBinaryBlobMode,exception);
1401 if (status == MagickFalse)
1403 for (y=0; y < (ssize_t) image->rows; y++)
1405 register const Quantum
1408 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1409 if (p == (const Quantum *) NULL)
1411 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1412 RedQuantum,pixels,exception);
1413 count=WriteBlob(image,length,pixels);
1414 if (count != (ssize_t) length)
1417 if (image->previous == (Image *) NULL)
1419 status=SetImageProgress(image,SaveImageTag,3,6);
1420 if (status == MagickFalse)
1423 (void) CloseBlob(image);
1424 if (quantum_type == BGRAQuantum)
1426 (void) CloseBlob(image);
1427 AppendImageFormat("A",image->filename);
1428 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1429 AppendBinaryBlobMode,exception);
1430 if (status == MagickFalse)
1432 for (y=0; y < (ssize_t) image->rows; y++)
1434 register const Quantum
1437 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1438 if (p == (const Quantum *) NULL)
1440 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1441 AlphaQuantum,pixels,exception);
1442 count=WriteBlob(image,length,pixels);
1443 if (count != (ssize_t) length)
1446 if (image->previous == (Image *) NULL)
1448 status=SetImageProgress(image,SaveImageTag,5,6);
1449 if (status == MagickFalse)
1453 (void) CloseBlob(image);
1454 (void) CopyMagickString(image->filename,image_info->filename,
1456 if (image->previous == (Image *) NULL)
1458 status=SetImageProgress(image,SaveImageTag,6,6);
1459 if (status == MagickFalse)
1465 quantum_info=DestroyQuantumInfo(quantum_info);
1466 if (GetNextImageInList(image) == (Image *) NULL)
1468 image=SyncNextImageInList(image);
1469 status=SetImageProgress(image,SaveImagesTag,scene++,
1470 GetImageListLength(image));
1471 if (status == MagickFalse)
1473 } while (image_info->adjoin != MagickFalse);
1474 (void) CloseBlob(image);