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