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