2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Raw BGR Image Format %
20 % Copyright 1999-2018 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 % https://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 if (canvas_image == (Image *) NULL)
163 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
164 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
166 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
167 if (quantum_info == (QuantumInfo *) NULL)
168 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
169 quantum_type=BGRQuantum;
170 if (LocaleCompare(image_info->magick,"BGRA") == 0)
172 quantum_type=BGRAQuantum;
173 image->alpha_trait=BlendPixelTrait;
174 canvas_image->alpha_trait=BlendPixelTrait;
176 if (LocaleCompare(image_info->magick,"BGRO") == 0)
178 quantum_type=BGROQuantum;
179 image->alpha_trait=BlendPixelTrait;
180 canvas_image->alpha_trait=BlendPixelTrait;
182 pixels=(const unsigned char *) NULL;
183 if (image_info->number_scenes != 0)
184 while (image->scene < image_info->scene)
190 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
191 for (y=0; y < (ssize_t) image->rows; y++)
193 pixels=(const unsigned char *) ReadBlobStream(image,length,
194 GetQuantumPixels(quantum_info),&count);
195 if (count != (ssize_t) length)
205 Read pixels to virtual canvas image then push to image.
207 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
208 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
210 status=SetImageExtent(image,image->columns,image->rows,exception);
211 if (status == MagickFalse)
212 return(DestroyImageList(image));
213 switch (image_info->interlace)
219 No interlacing: BGRBGRBGRBGRBGRBGR...
223 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
224 pixels=(const unsigned char *) ReadBlobStream(image,length,
225 GetQuantumPixels(quantum_info),&count);
226 if (count != (ssize_t) length)
229 for (y=0; y < (ssize_t) image->extract_info.height; y++)
231 register const Quantum
240 if (count != (ssize_t) length)
242 ThrowFileException(exception,CorruptImageError,
243 "UnexpectedEndOfFile",image->filename);
246 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
248 if (q == (Quantum *) NULL)
250 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
251 quantum_info,quantum_type,pixels,exception);
252 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
254 if (((y-image->extract_info.y) >= 0) &&
255 ((y-image->extract_info.y) < (ssize_t) image->rows))
257 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
258 canvas_image->columns,1,exception);
259 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
260 image->columns,1,exception);
261 if ((p == (const Quantum *) NULL) ||
262 (q == (Quantum *) NULL))
264 for (x=0; x < (ssize_t) image->columns; x++)
266 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
267 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
268 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
269 SetPixelAlpha(image,OpaqueAlpha,q);
270 if (image->alpha_trait != UndefinedPixelTrait)
271 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
272 p+=GetPixelChannels(canvas_image);
273 q+=GetPixelChannels(image);
275 if (SyncAuthenticPixels(image,exception) == MagickFalse)
278 if (image->previous == (Image *) NULL)
280 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
282 if (status == MagickFalse)
285 pixels=(const unsigned char *) ReadBlobStream(image,length,
286 GetQuantumPixels(quantum_info),&count);
287 if (count != (ssize_t) length)
304 Line interlacing: BBB...GGG...RRR...RRR...GGG...BBB...
308 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
309 pixels=(const unsigned char *) ReadBlobStream(image,length,
310 GetQuantumPixels(quantum_info),&count);
311 if (count != (ssize_t) length)
314 for (y=0; y < (ssize_t) image->extract_info.height; y++)
316 register const Quantum
325 if (count != (ssize_t) length)
327 ThrowFileException(exception,CorruptImageError,
328 "UnexpectedEndOfFile",image->filename);
331 for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 4 : 3); i++)
333 quantum_type=quantum_types[i];
334 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
336 if (q == (Quantum *) NULL)
338 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
339 quantum_info,quantum_type,pixels,exception);
340 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
342 if (((y-image->extract_info.y) >= 0) &&
343 ((y-image->extract_info.y) < (ssize_t) image->rows))
345 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
346 canvas_image->columns,1,exception);
347 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
348 image->columns,1,exception);
349 if ((p == (const Quantum *) NULL) ||
350 (q == (Quantum *) NULL))
352 for (x=0; x < (ssize_t) image->columns; x++)
354 switch (quantum_type)
358 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
363 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
368 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
373 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
378 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
384 p+=GetPixelChannels(canvas_image);
385 q+=GetPixelChannels(image);
387 if (SyncAuthenticPixels(image,exception) == MagickFalse)
390 pixels=(const unsigned char *) ReadBlobStream(image,length,
391 GetQuantumPixels(quantum_info),&count);
392 if (count != (ssize_t) length)
395 if (image->previous == (Image *) NULL)
397 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
399 if (status == MagickFalse)
408 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
412 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
413 pixels=(const unsigned char *) ReadBlobStream(image,length,
414 GetQuantumPixels(quantum_info),&count);
415 if (count != (ssize_t) length)
418 for (y=0; y < (ssize_t) image->extract_info.height; y++)
420 register const Quantum
429 if (count != (ssize_t) length)
431 ThrowFileException(exception,CorruptImageError,
432 "UnexpectedEndOfFile",image->filename);
435 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
437 if (q == (Quantum *) NULL)
439 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
440 quantum_info,RedQuantum,pixels,exception);
441 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
443 if (((y-image->extract_info.y) >= 0) &&
444 ((y-image->extract_info.y) < (ssize_t) image->rows))
446 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
447 canvas_image->columns,1,exception);
448 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
449 image->columns,1,exception);
450 if ((p == (const Quantum *) NULL) ||
451 (q == (Quantum *) NULL))
453 for (x=0; x < (ssize_t) image->columns; x++)
455 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
456 p+=GetPixelChannels(canvas_image);
457 q+=GetPixelChannels(image);
459 if (SyncAuthenticPixels(image,exception) == MagickFalse)
462 pixels=(const unsigned char *) ReadBlobStream(image,length,
463 GetQuantumPixels(quantum_info),&count);
464 if (count != (ssize_t) length)
467 if (image->previous == (Image *) NULL)
469 status=SetImageProgress(image,LoadImageTag,1,6);
470 if (status == MagickFalse)
473 for (y=0; y < (ssize_t) image->extract_info.height; y++)
475 register const Quantum
484 if (count != (ssize_t) length)
486 ThrowFileException(exception,CorruptImageError,
487 "UnexpectedEndOfFile",image->filename);
490 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
492 if (q == (Quantum *) NULL)
494 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
495 quantum_info,GreenQuantum,pixels,exception);
496 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
498 if (((y-image->extract_info.y) >= 0) &&
499 ((y-image->extract_info.y) < (ssize_t) image->rows))
501 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
502 canvas_image->columns,1,exception);
503 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
504 image->columns,1,exception);
505 if ((p == (const Quantum *) NULL) ||
506 (q == (Quantum *) NULL))
508 for (x=0; x < (ssize_t) image->columns; x++)
510 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
511 p+=GetPixelChannels(canvas_image);
512 q+=GetPixelChannels(image);
514 if (SyncAuthenticPixels(image,exception) == MagickFalse)
517 pixels=(const unsigned char *) ReadBlobStream(image,length,
518 GetQuantumPixels(quantum_info),&count);
519 if (count != (ssize_t) length)
522 if (image->previous == (Image *) NULL)
524 status=SetImageProgress(image,LoadImageTag,2,6);
525 if (status == MagickFalse)
528 for (y=0; y < (ssize_t) image->extract_info.height; y++)
530 register const Quantum
539 if (count != (ssize_t) length)
541 ThrowFileException(exception,CorruptImageError,
542 "UnexpectedEndOfFile",image->filename);
545 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
547 if (q == (Quantum *) NULL)
549 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
550 quantum_info,BlueQuantum,pixels,exception);
551 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
553 if (((y-image->extract_info.y) >= 0) &&
554 ((y-image->extract_info.y) < (ssize_t) image->rows))
556 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
557 canvas_image->columns,1,exception);
558 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
559 image->columns,1,exception);
560 if ((p == (const Quantum *) NULL) ||
561 (q == (Quantum *) NULL))
563 for (x=0; x < (ssize_t) image->columns; x++)
565 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
566 p+=GetPixelChannels(canvas_image);
567 q+=GetPixelChannels(image);
569 if (SyncAuthenticPixels(image,exception) == MagickFalse)
572 pixels=(const unsigned char *) ReadBlobStream(image,length,
573 GetQuantumPixels(quantum_info),&count);
574 if (count != (ssize_t) length)
577 if (image->previous == (Image *) NULL)
579 status=SetImageProgress(image,LoadImageTag,3,6);
580 if (status == MagickFalse)
583 if (image->previous == (Image *) NULL)
585 status=SetImageProgress(image,LoadImageTag,4,6);
586 if (status == MagickFalse)
589 if (image->alpha_trait != UndefinedPixelTrait)
591 for (y=0; y < (ssize_t) image->extract_info.height; y++)
593 register const Quantum
602 if (count != (ssize_t) length)
604 ThrowFileException(exception,CorruptImageError,
605 "UnexpectedEndOfFile",image->filename);
608 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
610 if (q == (Quantum *) NULL)
612 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
613 quantum_info,AlphaQuantum,pixels,exception);
614 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
616 if (((y-image->extract_info.y) >= 0) &&
617 ((y-image->extract_info.y) < (ssize_t) image->rows))
619 p=GetVirtualPixels(canvas_image,
620 canvas_image->extract_info.x,0,canvas_image->columns,1,
622 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
623 image->columns,1,exception);
624 if ((p == (const Quantum *) NULL) ||
625 (q == (Quantum *) NULL))
627 for (x=0; x < (ssize_t) image->columns; x++)
629 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
630 p+=GetPixelChannels(canvas_image);
631 q+=GetPixelChannels(image);
633 if (SyncAuthenticPixels(image,exception) == MagickFalse)
636 pixels=(const unsigned char *) ReadBlobStream(image,length,
637 GetQuantumPixels(quantum_info),&count);
638 if (count != (ssize_t) length)
641 if (image->previous == (Image *) NULL)
643 status=SetImageProgress(image,LoadImageTag,5,6);
644 if (status == MagickFalse)
648 if (image->previous == (Image *) NULL)
650 status=SetImageProgress(image,LoadImageTag,6,6);
651 if (status == MagickFalse)
656 case PartitionInterlace:
659 Partition interlacing: BBBBBB..., GGGGGG..., RRRRRR...
661 AppendImageFormat("B",image->filename);
662 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
663 if (status == MagickFalse)
665 canvas_image=DestroyImageList(canvas_image);
666 image=DestroyImageList(image);
667 return((Image *) NULL);
669 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
670 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
672 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
673 for (i=0; i < (ssize_t) scene; i++)
674 for (y=0; y < (ssize_t) image->extract_info.height; y++)
676 pixels=(const unsigned char *) ReadBlobStream(image,length,
677 GetQuantumPixels(quantum_info),&count);
678 if (count != (ssize_t) length)
680 ThrowFileException(exception,CorruptImageError,
681 "UnexpectedEndOfFile",image->filename);
685 pixels=(const unsigned char *) ReadBlobStream(image,length,
686 GetQuantumPixels(quantum_info),&count);
687 if (count != (ssize_t) length)
689 for (y=0; y < (ssize_t) image->extract_info.height; y++)
691 register const Quantum
700 if (count != (ssize_t) length)
702 ThrowFileException(exception,CorruptImageError,
703 "UnexpectedEndOfFile",image->filename);
706 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
708 if (q == (Quantum *) NULL)
710 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
711 quantum_info,BlueQuantum,pixels,exception);
712 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
714 if (((y-image->extract_info.y) >= 0) &&
715 ((y-image->extract_info.y) < (ssize_t) image->rows))
717 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
718 canvas_image->columns,1,exception);
719 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
720 image->columns,1,exception);
721 if ((p == (const Quantum *) NULL) ||
722 (q == (Quantum *) NULL))
724 for (x=0; x < (ssize_t) image->columns; x++)
726 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
727 p+=GetPixelChannels(canvas_image);
728 q+=GetPixelChannels(image);
730 if (SyncAuthenticPixels(image,exception) == MagickFalse)
733 pixels=(const unsigned char *) ReadBlobStream(image,length,
734 GetQuantumPixels(quantum_info),&count);
735 if (count != (ssize_t) length)
738 if (image->previous == (Image *) NULL)
740 status=SetImageProgress(image,LoadImageTag,1,5);
741 if (status == MagickFalse)
744 (void) CloseBlob(image);
745 AppendImageFormat("G",image->filename);
746 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
747 if (status == MagickFalse)
749 canvas_image=DestroyImageList(canvas_image);
750 image=DestroyImageList(image);
751 return((Image *) NULL);
753 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
754 for (i=0; i < (ssize_t) scene; i++)
755 for (y=0; y < (ssize_t) image->extract_info.height; y++)
757 pixels=(const unsigned char *) ReadBlobStream(image,length,
758 GetQuantumPixels(quantum_info),&count);
759 if (count != (ssize_t) length)
761 ThrowFileException(exception,CorruptImageError,
762 "UnexpectedEndOfFile",image->filename);
766 pixels=(const unsigned char *) ReadBlobStream(image,length,
767 GetQuantumPixels(quantum_info),&count);
768 if (count != (ssize_t) length)
770 for (y=0; y < (ssize_t) image->extract_info.height; y++)
772 register const Quantum
781 if (count != (ssize_t) length)
783 ThrowFileException(exception,CorruptImageError,
784 "UnexpectedEndOfFile",image->filename);
787 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
789 if (q == (Quantum *) NULL)
791 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
792 quantum_info,GreenQuantum,pixels,exception);
793 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
795 if (((y-image->extract_info.y) >= 0) &&
796 ((y-image->extract_info.y) < (ssize_t) image->rows))
798 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
799 canvas_image->columns,1,exception);
800 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
801 image->columns,1,exception);
802 if ((p == (const Quantum *) NULL) ||
803 (q == (Quantum *) NULL))
805 for (x=0; x < (ssize_t) image->columns; x++)
807 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
808 p+=GetPixelChannels(canvas_image);
809 q+=GetPixelChannels(image);
811 if (SyncAuthenticPixels(image,exception) == MagickFalse)
814 pixels=(const unsigned char *) ReadBlobStream(image,length,
815 GetQuantumPixels(quantum_info),&count);
816 if (count != (ssize_t) length)
819 if (image->previous == (Image *) NULL)
821 status=SetImageProgress(image,LoadImageTag,2,5);
822 if (status == MagickFalse)
825 (void) CloseBlob(image);
826 AppendImageFormat("R",image->filename);
827 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
828 if (status == MagickFalse)
830 canvas_image=DestroyImageList(canvas_image);
831 image=DestroyImageList(image);
832 return((Image *) NULL);
834 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
835 for (i=0; i < (ssize_t) scene; i++)
836 for (y=0; y < (ssize_t) image->extract_info.height; y++)
838 pixels=(const unsigned char *) ReadBlobStream(image,length,
839 GetQuantumPixels(quantum_info),&count);
840 if (count != (ssize_t) length)
842 ThrowFileException(exception,CorruptImageError,
843 "UnexpectedEndOfFile",image->filename);
847 pixels=(const unsigned char *) ReadBlobStream(image,length,
848 GetQuantumPixels(quantum_info),&count);
849 if (count != (ssize_t) length)
851 for (y=0; y < (ssize_t) image->extract_info.height; y++)
853 register const Quantum
862 if (count != (ssize_t) length)
864 ThrowFileException(exception,CorruptImageError,
865 "UnexpectedEndOfFile",image->filename);
868 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
870 if (q == (Quantum *) NULL)
872 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
873 quantum_info,RedQuantum,pixels,exception);
874 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
876 if (((y-image->extract_info.y) >= 0) &&
877 ((y-image->extract_info.y) < (ssize_t) image->rows))
879 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
880 canvas_image->columns,1,exception);
881 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
882 image->columns,1,exception);
883 if ((p == (const Quantum *) NULL) ||
884 (q == (Quantum *) NULL))
886 for (x=0; x < (ssize_t) image->columns; x++)
888 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
889 p+=GetPixelChannels(canvas_image);
890 q+=GetPixelChannels(image);
892 if (SyncAuthenticPixels(image,exception) == MagickFalse)
895 pixels=(const unsigned char *) ReadBlobStream(image,length,
896 GetQuantumPixels(quantum_info),&count);
897 if (count != (ssize_t) length)
900 if (image->previous == (Image *) NULL)
902 status=SetImageProgress(image,LoadImageTag,3,5);
903 if (status == MagickFalse)
906 if (image->alpha_trait != UndefinedPixelTrait)
908 (void) CloseBlob(image);
909 AppendImageFormat("A",image->filename);
910 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
911 if (status == MagickFalse)
913 canvas_image=DestroyImageList(canvas_image);
914 image=DestroyImageList(image);
915 return((Image *) NULL);
917 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
918 for (i=0; i < (ssize_t) scene; i++)
919 for (y=0; y < (ssize_t) image->extract_info.height; y++)
921 pixels=(const unsigned char *) ReadBlobStream(image,length,
922 GetQuantumPixels(quantum_info),&count);
923 if (count != (ssize_t) length)
925 ThrowFileException(exception,CorruptImageError,
926 "UnexpectedEndOfFile",image->filename);
930 pixels=(const unsigned char *) ReadBlobStream(image,length,
931 GetQuantumPixels(quantum_info),&count);
932 if (count != (ssize_t) length)
934 for (y=0; y < (ssize_t) image->extract_info.height; y++)
936 register const Quantum
945 if (count != (ssize_t) length)
947 ThrowFileException(exception,CorruptImageError,
948 "UnexpectedEndOfFile",image->filename);
951 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
953 if (q == (Quantum *) NULL)
955 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
956 quantum_info,BlueQuantum,pixels,exception);
957 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
959 if (((y-image->extract_info.y) >= 0) &&
960 ((y-image->extract_info.y) < (ssize_t) image->rows))
962 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
963 0,canvas_image->columns,1,exception);
964 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
965 image->columns,1,exception);
966 if ((p == (const Quantum *) NULL) ||
967 (q == (Quantum *) NULL))
969 for (x=0; x < (ssize_t) image->columns; x++)
971 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
972 p+=GetPixelChannels(canvas_image);
973 q+=GetPixelChannels(image);
975 if (SyncAuthenticPixels(image,exception) == MagickFalse)
978 pixels=(const unsigned char *) ReadBlobStream(image,length,
979 GetQuantumPixels(quantum_info),&count);
980 if (count != (ssize_t) length)
983 if (image->previous == (Image *) NULL)
985 status=SetImageProgress(image,LoadImageTag,4,5);
986 if (status == MagickFalse)
990 (void) CloseBlob(image);
991 if (image->previous == (Image *) NULL)
993 status=SetImageProgress(image,LoadImageTag,5,5);
994 if (status == MagickFalse)
1000 SetQuantumImageType(image,quantum_type);
1002 Proceed to next image.
1004 if (image_info->number_scenes != 0)
1005 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1007 if (count == (ssize_t) length)
1010 Allocate next image structure.
1012 AcquireNextImage(image_info,image,exception);
1013 if (GetNextImageInList(image) == (Image *) NULL)
1015 image=DestroyImageList(image);
1016 return((Image *) NULL);
1018 image=SyncNextImageInList(image);
1019 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1020 GetBlobSize(image));
1021 if (status == MagickFalse)
1025 } while (count == (ssize_t) length);
1026 quantum_info=DestroyQuantumInfo(quantum_info);
1027 canvas_image=DestroyImage(canvas_image);
1028 (void) CloseBlob(image);
1029 return(GetFirstImageInList(image));
1033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1037 % R e g i s t e r B G R I m a g e %
1041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1043 % RegisterBGRImage() adds attributes for the BGR image format to
1044 % the list of supported formats. The attributes include the image format
1045 % tag, a method to read and/or write the format, whether the format
1046 % supports the saving of more than one frame to the same file or blob,
1047 % whether the format supports native in-memory I/O, and a brief
1048 % description of the format.
1050 % The format of the RegisterBGRImage method is:
1052 % size_t RegisterBGRImage(void)
1055 ModuleExport size_t RegisterBGRImage(void)
1060 entry=AcquireMagickInfo("BGR","BGR","Raw blue, green, and red samples");
1061 entry->decoder=(DecodeImageHandler *) ReadBGRImage;
1062 entry->encoder=(EncodeImageHandler *) WriteBGRImage;
1063 entry->flags|=CoderRawSupportFlag;
1064 entry->flags|=CoderEndianSupportFlag;
1065 (void) RegisterMagickInfo(entry);
1066 entry=AcquireMagickInfo("BGR","BGRA",
1067 "Raw blue, green, red, and alpha samples");
1068 entry->decoder=(DecodeImageHandler *) ReadBGRImage;
1069 entry->encoder=(EncodeImageHandler *) WriteBGRImage;
1070 entry->flags|=CoderRawSupportFlag;
1071 entry->flags|=CoderEndianSupportFlag;
1072 (void) RegisterMagickInfo(entry);
1073 entry=AcquireMagickInfo("BGR","BGRO",
1074 "Raw blue, green, red, and opacity samples");
1075 entry->decoder=(DecodeImageHandler *) ReadBGRImage;
1076 entry->encoder=(EncodeImageHandler *) WriteBGRImage;
1077 entry->flags|=CoderRawSupportFlag;
1078 entry->flags|=CoderEndianSupportFlag;
1079 (void) RegisterMagickInfo(entry);
1080 return(MagickImageCoderSignature);
1084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1088 % U n r e g i s t e r B G R I m a g e %
1092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1094 % UnregisterBGRImage() removes format registrations made by the BGR module
1095 % from the list of supported formats.
1097 % The format of the UnregisterBGRImage method is:
1099 % UnregisterBGRImage(void)
1102 ModuleExport void UnregisterBGRImage(void)
1104 (void) UnregisterMagickInfo("BGRA");
1105 (void) UnregisterMagickInfo("BGR");
1109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1113 % W r i t e B G R I m a g e %
1117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1119 % WriteBGRImage() writes an image to a file in the BGR or BGRA
1120 % rasterfile format.
1122 % The format of the WriteBGRImage method is:
1124 % MagickBooleanType WriteBGRImage(const ImageInfo *image_info,
1125 % Image *image,ExceptionInfo *exception)
1127 % A description of each parameter follows.
1129 % o image_info: the image info.
1131 % o image: The image.
1133 % o exception: return any errors or warnings in this structure.
1136 static MagickBooleanType WriteBGRImage(const ImageInfo *image_info,Image *image,
1137 ExceptionInfo *exception)
1162 Allocate memory for pixels.
1164 assert(image_info != (const ImageInfo *) NULL);
1165 assert(image_info->signature == MagickCoreSignature);
1166 assert(image != (Image *) NULL);
1167 assert(image->signature == MagickCoreSignature);
1168 if (image->debug != MagickFalse)
1169 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1170 if (image_info->interlace != PartitionInterlace)
1173 Open output image file.
1175 assert(exception != (ExceptionInfo *) NULL);
1176 assert(exception->signature == MagickCoreSignature);
1177 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1178 if (status == MagickFalse)
1181 quantum_type=BGRQuantum;
1182 if (LocaleCompare(image_info->magick,"BGRA") == 0)
1184 quantum_type=BGRAQuantum;
1185 image->alpha_trait=BlendPixelTrait;
1191 Convert MIFF to BGR raster pixels.
1193 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1194 if ((LocaleCompare(image_info->magick,"BGRA") == 0) &&
1195 (image->alpha_trait == UndefinedPixelTrait))
1196 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1197 quantum_info=AcquireQuantumInfo(image_info,image);
1198 if (quantum_info == (QuantumInfo *) NULL)
1199 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1200 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
1201 switch (image_info->interlace)
1207 No interlacing: BGRBGRBGRBGRBGRBGR...
1209 for (y=0; y < (ssize_t) image->rows; y++)
1211 register const Quantum
1214 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1215 if (p == (const Quantum *) NULL)
1217 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1218 quantum_type,pixels,exception);
1219 count=WriteBlob(image,length,pixels);
1220 if (count != (ssize_t) length)
1222 if (image->previous == (Image *) NULL)
1224 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1226 if (status == MagickFalse)
1235 Line interlacing: BBB...GGG...RRR...RRR...GGG...BBB...
1237 for (y=0; y < (ssize_t) image->rows; y++)
1239 register const Quantum
1242 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1243 if (p == (const Quantum *) NULL)
1245 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1246 BlueQuantum,pixels,exception);
1247 count=WriteBlob(image,length,pixels);
1248 if (count != (ssize_t) length)
1250 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1251 GreenQuantum,pixels,exception);
1252 count=WriteBlob(image,length,pixels);
1253 if (count != (ssize_t) length)
1255 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1256 RedQuantum,pixels,exception);
1257 count=WriteBlob(image,length,pixels);
1258 if (count != (ssize_t) length)
1260 if (quantum_type == BGRAQuantum)
1262 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1263 AlphaQuantum,pixels,exception);
1264 count=WriteBlob(image,length,pixels);
1265 if (count != (ssize_t) length)
1268 if (image->previous == (Image *) NULL)
1270 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1272 if (status == MagickFalse)
1278 case PlaneInterlace:
1281 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1283 for (y=0; y < (ssize_t) image->rows; y++)
1285 register const Quantum
1288 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1289 if (p == (const Quantum *) NULL)
1291 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1292 RedQuantum,pixels,exception);
1293 count=WriteBlob(image,length,pixels);
1294 if (count != (ssize_t) length)
1297 if (image->previous == (Image *) NULL)
1299 status=SetImageProgress(image,SaveImageTag,1,6);
1300 if (status == MagickFalse)
1303 for (y=0; y < (ssize_t) image->rows; y++)
1305 register const Quantum
1308 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1309 if (p == (const Quantum *) NULL)
1311 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1312 GreenQuantum,pixels,exception);
1313 count=WriteBlob(image,length,pixels);
1314 if (count != (ssize_t) length)
1317 if (image->previous == (Image *) NULL)
1319 status=SetImageProgress(image,SaveImageTag,2,6);
1320 if (status == MagickFalse)
1323 for (y=0; y < (ssize_t) image->rows; y++)
1325 register const Quantum
1328 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1329 if (p == (const Quantum *) NULL)
1331 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1332 BlueQuantum,pixels,exception);
1333 count=WriteBlob(image,length,pixels);
1334 if (count != (ssize_t) length)
1337 if (image->previous == (Image *) NULL)
1339 status=SetImageProgress(image,SaveImageTag,3,6);
1340 if (status == MagickFalse)
1343 if (quantum_type == BGRAQuantum)
1345 for (y=0; y < (ssize_t) image->rows; y++)
1347 register const Quantum
1350 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1351 if (p == (const Quantum *) NULL)
1353 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1354 AlphaQuantum,pixels,exception);
1355 count=WriteBlob(image,length,pixels);
1356 if (count != (ssize_t) length)
1359 if (image->previous == (Image *) NULL)
1361 status=SetImageProgress(image,SaveImageTag,5,6);
1362 if (status == MagickFalse)
1366 if (image_info->interlace == PartitionInterlace)
1367 (void) CopyMagickString(image->filename,image_info->filename,
1369 if (image->previous == (Image *) NULL)
1371 status=SetImageProgress(image,SaveImageTag,6,6);
1372 if (status == MagickFalse)
1377 case PartitionInterlace:
1380 Partition interlacing: BBBBBB..., GGGGGG..., RRRRRR...
1382 AppendImageFormat("B",image->filename);
1383 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1384 AppendBinaryBlobMode,exception);
1385 if (status == MagickFalse)
1387 for (y=0; y < (ssize_t) image->rows; y++)
1389 register const Quantum
1392 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1393 if (p == (const Quantum *) NULL)
1395 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1396 BlueQuantum,pixels,exception);
1397 count=WriteBlob(image,length,pixels);
1398 if (count != (ssize_t) length)
1401 if (image->previous == (Image *) NULL)
1403 status=SetImageProgress(image,SaveImageTag,1,6);
1404 if (status == MagickFalse)
1407 (void) CloseBlob(image);
1408 AppendImageFormat("G",image->filename);
1409 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1410 AppendBinaryBlobMode,exception);
1411 if (status == MagickFalse)
1413 for (y=0; y < (ssize_t) image->rows; y++)
1415 register const Quantum
1418 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1419 if (p == (const Quantum *) NULL)
1421 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1422 GreenQuantum,pixels,exception);
1423 count=WriteBlob(image,length,pixels);
1424 if (count != (ssize_t) length)
1427 if (image->previous == (Image *) NULL)
1429 status=SetImageProgress(image,SaveImageTag,2,6);
1430 if (status == MagickFalse)
1433 (void) CloseBlob(image);
1434 AppendImageFormat("R",image->filename);
1435 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1436 AppendBinaryBlobMode,exception);
1437 if (status == MagickFalse)
1439 for (y=0; y < (ssize_t) image->rows; y++)
1441 register const Quantum
1444 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1445 if (p == (const Quantum *) NULL)
1447 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1448 RedQuantum,pixels,exception);
1449 count=WriteBlob(image,length,pixels);
1450 if (count != (ssize_t) length)
1453 if (image->previous == (Image *) NULL)
1455 status=SetImageProgress(image,SaveImageTag,3,6);
1456 if (status == MagickFalse)
1459 (void) CloseBlob(image);
1460 if (quantum_type == BGRAQuantum)
1462 (void) CloseBlob(image);
1463 AppendImageFormat("A",image->filename);
1464 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1465 AppendBinaryBlobMode,exception);
1466 if (status == MagickFalse)
1468 for (y=0; y < (ssize_t) image->rows; y++)
1470 register const Quantum
1473 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1474 if (p == (const Quantum *) NULL)
1476 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1477 AlphaQuantum,pixels,exception);
1478 count=WriteBlob(image,length,pixels);
1479 if (count != (ssize_t) length)
1482 if (image->previous == (Image *) NULL)
1484 status=SetImageProgress(image,SaveImageTag,5,6);
1485 if (status == MagickFalse)
1489 (void) CloseBlob(image);
1490 (void) CopyMagickString(image->filename,image_info->filename,
1492 if (image->previous == (Image *) NULL)
1494 status=SetImageProgress(image,SaveImageTag,6,6);
1495 if (status == MagickFalse)
1501 quantum_info=DestroyQuantumInfo(quantum_info);
1502 if (GetNextImageInList(image) == (Image *) NULL)
1504 image=SyncNextImageInList(image);
1505 status=SetImageProgress(image,SaveImagesTag,scene++,
1506 GetImageListLength(image));
1507 if (status == MagickFalse)
1509 } while (image_info->adjoin != MagickFalse);
1510 (void) CloseBlob(image);