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