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