|
|
Definition at line 357 of file miff.c.
References AcquireMagickMemory(), AcquireString(), AcquireStringInfo(), AllocateImage(), AllocateImageColormap(), AllocateNextImage(), AppendElementToLinkedList(), assert, _Image::background_color, _PixelPacket::blue, _ChromaticityInfo::blue_primary, _Image::border_color, BZipCompression, BZipMaxExtent, _Image::chromaticity, ClassType, _Image::client_data, CloneString(), CloseBlob(), CMYKAQuantum, CMYKColorspace, CMYKQuantum, _Image::colormap, _Image::colors, _Image::colorspace, ColorspaceType, _Image::columns, _Image::compose, CompositeOperator, _Image::compression, CompressionType, CopyMagickString(), CorruptImageError, _StringInfo::datum, _ImageInfo::debug, _Image::delay, _Image::depth, DestroyImageList(), DestroyLinkedList(), DestroyStringInfo(), DirectClass, _Image::directory, _Image::dispose, DisposeType, _Image::endian, EndianType, EOFBlob(), _Image::filename, _ImageInfo::filename, _Image::gamma, GetBlobSize(), GetFirstImageInList(), GetImageProfile(), GetImageQuantumDepth(), GetIndexes(), GetMagickModule, GetNextElementInLinkedList(), GetPageGeometry(), _PixelPacket::green, _ChromaticityInfo::green_primary, IndexAlphaQuantum, IndexPacket, IndexQuantum, _Image::iterations, _StringInfo::length, LoadImagesTag, LocaleCompare(), LocaleNCompare(), LogMagickEvent(), MagickBooleanOptions, MagickBooleanType, MagickClassOptions, MagickColorspaceOptions, MagickCompositeOptions, MagickCompressionOptions, MagickDisposeOptions, MagickEndianOptions, MagickFalse, MagickIntentOptions, MagickOffsetType, MagickProgressMonitor, MagickResolutionOptions, MagickSignature, MagickStatusType, MagickTrue, _Image::matte, _Image::matte_color, Max, MaxTextExtent, _Image::montage, name, NewLinkedList(), _Image::next, NoCompression, _ImageInfo::number_scenes, OpenBlob(), _Image::page, ParseAbsoluteGeometry(), ParseGeometry(), ParseMagickOption(), _ImageInfo::ping, _Image::progress_monitor, PseudoClass, PushCharPixel, PushImagePixels(), PushLongPixel, PushRunlengthPacket(), PushShortPixel, QuantumType, QueryColorDatabase(), ReadBinaryBlobMode, ReadBlob(), ReadBlobByte(), ReadBlobMSBLong(), _PixelPacket::red, _ChromaticityInfo::red_primary, RelinquishMagickMemory(), _Image::rendering_intent, RenderingIntent, ResetLinkedListIterator(), ResetMagickMemory(), ResizeMagickMemory(), ResolutionType, ResourceLimitError, RGBAQuantum, RGBQuantum, _GeometryInfo::rho, RLECompression, _Image::rows, ScaleCharToQuantum, ScaleLongToQuantum, ScaleShortToQuantum, _ImageInfo::scene, _Image::scene, SeekBlob(), SetImageAttribute(), SetImagePixels(), SetImageProfile(), _GeometryInfo::sigma, SigmaValue, _ExceptionInfo::signature, _ImageInfo::signature, _Image::storage_class, SyncImagePixels(), SyncNextImageInList(), TellBlob(), ThrowFileException, ThrowReaderException, TraceEvent, TransparentOpacity, UndefinedClass, _Image::units, _ImageInfo::verbose, _ChromaticityInfo::white_point, _PrimaryInfo::x, _Image::x_resolution, _PrimaryInfo::y, _Image::y_resolution, ZipCompression, and ZipMaxExtent.
Referenced by RegisterMIFFImage().
00359 {
00360 #define BZipMaxExtent(x) ((x)+((x)/100)+600)
00361 #define ZipMaxExtent(x) ((x)+(((x)+7) >> 3)+(((x)+63) >> 6)+11)
00362
00363 #if defined(HasBZLIB)
00364 bz_stream
00365 bzip_info;
00366 #endif
00367
00368 char
00369 id[ MaxTextExtent],
00370 keyword[ MaxTextExtent],
00371 *options;
00372
00373 double
00374 version;
00375
00376 GeometryInfo
00377 geometry_info;
00378
00379 Image
00380 *image;
00381
00382 IndexPacket
00383 index;
00384
00385 int
00386 c,
00387 code;
00388
00389 LinkedListInfo
00390 *profiles;
00391
00392 long
00393 y;
00394
00395 PixelPacket
00396 pixel;
00397
00398 QuantumType
00399 quantum_type;
00400
00401 MagickBooleanType
00402 status;
00403
00404 MagickStatusType
00405 flags;
00406
00407 register IndexPacket
00408 *indexes;
00409
00410 register long
00411 i,
00412 x;
00413
00414 register PixelPacket
00415 *q;
00416
00417 register unsigned char
00418 *p;
00419
00420 size_t
00421 length,
00422 packet_size;
00423
00424 StringInfo
00425 *profile;
00426
00427 unsigned char
00428 *compress_pixels,
00429 *pixels;
00430
00431 unsigned long
00432 colors,
00433 depth;
00434
00435 #if defined(HasZLIB)
00436 z_stream
00437 zip_info;
00438 #endif
00439
00440
00441
00442
00443 assert(image_info != ( const ImageInfo *) NULL);
00444 assert(image_info-> signature == MagickSignature);
00445 if (image_info-> debug != MagickFalse)
00446 ( void) LogMagickEvent(TraceEvent, GetMagickModule(),image_info-> filename);
00447 assert(exception != ( ExceptionInfo *) NULL);
00448 assert(exception-> signature == MagickSignature);
00449 image= AllocateImage(image_info);
00450 status= OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
00451 if (status == MagickFalse)
00452 {
00453 DestroyImageList(image);
00454 return(( Image *) NULL);
00455 }
00456
00457
00458
00459 c= ReadBlobByte(image);
00460 if (c == EOF)
00461 ThrowReaderException(CorruptImageError, "ImproperImageHeader");
00462 code=0;
00463 * id= '\0';
00464 version=0.0;
00465 do
00466 {
00467
00468
00469
00470 length= MaxTextExtent;
00471 options= AcquireString(( char *) NULL);
00472 profiles=( LinkedListInfo *) NULL;
00473 colors=0;
00474 image-> depth=8UL;
00475 image-> compression= NoCompression;
00476 while ((isgraph(c) != MagickFalse) && (c != ( int) ':'))
00477 {
00478 register char
00479 *p;
00480
00481 if (c == ( int) '{')
00482 {
00483 char
00484 *comment;
00485
00486
00487
00488
00489 length= MaxTextExtent;
00490 comment= AcquireString(( char *) NULL);
00491 for (p=comment; comment != ( char *) NULL; p++)
00492 {
00493 c= ReadBlobByte(image);
00494 if ((c == EOF) || (c == ( int) '}'))
00495 break;
00496 if ((size_t) (p-comment+1) >= length)
00497 {
00498 *p= '\0';
00499 length<<=1;
00500 comment=( char *) ResizeMagickMemory(comment,
00501 (length+MaxTextExtent)* sizeof(*comment));
00502 if (comment == ( char *) NULL)
00503 break;
00504 p=comment+strlen(comment);
00505 }
00506 *p=( char) c;
00507 }
00508 if (comment == ( char *) NULL)
00509 ThrowReaderException(ResourceLimitError, "MemoryAllocationFailed");
00510 *p= '\0';
00511 ( void) SetImageAttribute(image, "Comment",comment);
00512 comment=( char *) RelinquishMagickMemory(comment);
00513 c= ReadBlobByte(image);
00514 }
00515 else
00516 if (isalnum(c) != MagickFalse)
00517 {
00518
00519
00520
00521 p=keyword;
00522 do
00523 {
00524 if (isspace(( int) (( unsigned char) c)) != 0)
00525 break;
00526 if (c == ( int) '=')
00527 break;
00528 if ((size_t) (p-keyword) < ( MaxTextExtent-1))
00529 *p++=( char) c;
00530 c= ReadBlobByte(image);
00531 } while (c != EOF);
00532 *p= '\0';
00533 p=options;
00534 while (isspace(( int) (( unsigned char) c)) != 0)
00535 c= ReadBlobByte(image);
00536 if (c == ( int) '=')
00537 {
00538
00539
00540
00541 c= ReadBlobByte(image);
00542 while ((c != ( int) '}') && (c != EOF))
00543 {
00544 if ((size_t) (p-options+1) >= length)
00545 {
00546 *p= '\0';
00547 length<<=1;
00548 options=( char *) ResizeMagickMemory(options,
00549 (length+MaxTextExtent)* sizeof(*options));
00550 if (options == ( char *) NULL)
00551 break;
00552 p=options+strlen(options);
00553 }
00554 if (options == ( char *) NULL)
00555 ThrowReaderException(ResourceLimitError,
00556 "MemoryAllocationFailed");
00557 *p++=( char) c;
00558 c= ReadBlobByte(image);
00559 if (*options != '{')
00560 if (isspace(( int) (( unsigned char) c)) != 0)
00561 break;
00562 }
00563 }
00564 *p= '\0';
00565 if (*options == '{')
00566 ( void) CopyMagickString(options,options+1,MaxTextExtent);
00567
00568
00569
00570 switch (*keyword)
00571 {
00572 case 'b':
00573 case 'B':
00574 {
00575 if ( LocaleCompare(keyword, "background-color") == 0)
00576 {
00577 ( void) QueryColorDatabase(options,&image-> background_color,
00578 exception);
00579 break;
00580 }
00581 if ( LocaleCompare(keyword, "blue-primary") == 0)
00582 {
00583 flags= ParseGeometry(options,&geometry_info);
00584 image-> chromaticity. blue_primary. x=geometry_info. rho;
00585 image-> chromaticity. blue_primary. y=geometry_info. sigma;
00586 if ((flags & SigmaValue) == 0)
00587 image-> chromaticity. blue_primary. y=
00588 image-> chromaticity. blue_primary. x;
00589 break;
00590 }
00591 if ( LocaleCompare(keyword, "border-color") == 0)
00592 {
00593 ( void) QueryColorDatabase(options,&image-> border_color,
00594 exception);
00595 break;
00596 }
00597 ( void) SetImageAttribute(image,keyword,options);
00598 break;
00599 }
00600 case 'c':
00601 case 'C':
00602 {
00603 if ( LocaleCompare(keyword, "class") == 0)
00604 {
00605 image-> storage_class=( ClassType)
00606 ParseMagickOption(MagickClassOptions,MagickFalse,options);
00607 break;
00608 }
00609 if ( LocaleCompare(keyword, "colors") == 0)
00610 {
00611 colors=( unsigned long) atol(options);
00612 break;
00613 }
00614 if ( LocaleCompare(keyword, "colorspace") == 0)
00615 {
00616 image-> colorspace=( ColorspaceType) ParseMagickOption(
00617 MagickColorspaceOptions,MagickFalse,options);
00618 break;
00619 }
00620 if ( LocaleCompare(keyword, "compose") == 0)
00621 {
00622 image-> compose=( CompositeOperator) ParseMagickOption(
00623 MagickCompositeOptions,MagickFalse,options);
00624 break;
00625 }
00626 if ( LocaleCompare(keyword, "compression") == 0)
00627 {
00628 image-> compression=( CompressionType) ParseMagickOption(
00629 MagickCompressionOptions,MagickFalse,options);
00630 break;
00631 }
00632 if ( LocaleCompare(keyword, "columns") == 0)
00633 {
00634 image-> columns=( unsigned long) atol(options);
00635 break;
00636 }
00637 ( void) SetImageAttribute(image,keyword,options);
00638 break;
00639 }
00640 case 'd':
00641 case 'D':
00642 {
00643 if ( LocaleCompare(keyword, "delay") == 0)
00644 {
00645 image-> delay=( unsigned long) atol(options);
00646 break;
00647 }
00648 if ( LocaleCompare(keyword, "depth") == 0)
00649 {
00650 image-> depth=( unsigned long) atol(options);
00651 break;
00652 }
00653 if ( LocaleCompare(keyword, "dispose") == 0)
00654 {
00655 image-> dispose=( DisposeType) ParseMagickOption(
00656 MagickDisposeOptions,MagickFalse,options);
00657 break;
00658 }
00659 ( void) SetImageAttribute(image,keyword,options);
00660 break;
00661 }
00662 case 'e':
00663 case 'E':
00664 {
00665 if ( LocaleCompare(keyword, "endian") == 0)
00666 {
00667 image-> endian=( EndianType) ParseMagickOption(
00668 MagickEndianOptions,MagickFalse,options);
00669 break;
00670 }
00671 ( void) SetImageAttribute(image,keyword,options);
00672 break;
00673 }
00674 case 'g':
00675 case 'G':
00676 {
00677 if ( LocaleCompare(keyword, "gamma") == 0)
00678 {
00679 image-> gamma=atof(options);
00680 break;
00681 }
00682 if ( LocaleCompare(keyword, "green-primary") == 0)
00683 {
00684 flags= ParseGeometry(options,&geometry_info);
00685 image-> chromaticity. green_primary. x=geometry_info. rho;
00686 image-> chromaticity. green_primary. y=geometry_info. sigma;
00687 if ((flags & SigmaValue) == 0)
00688 image-> chromaticity. green_primary. y=
00689 image-> chromaticity. green_primary. x;
00690 break;
00691 }
00692 ( void) SetImageAttribute(image,keyword,options);
00693 break;
00694 }
00695 case 'i':
00696 case 'I':
00697 {
00698 if ( LocaleCompare(keyword, "id") == 0)
00699 {
00700 ( void) CopyMagickString( id,options,MaxTextExtent);
00701 break;
00702 }
00703 if ( LocaleCompare(keyword, "iterations") == 0)
00704 {
00705 image-> iterations=( unsigned long) atol(options);
00706 break;
00707 }
00708 ( void) SetImageAttribute(image,keyword,options);
00709 break;
00710 }
00711 case 'm':
00712 case 'M':
00713 {
00714 if ( LocaleCompare(keyword, "matte") == 0)
00715 {
00716 image-> matte=( MagickBooleanType) ParseMagickOption(
00717 MagickBooleanOptions,MagickFalse,options);
00718 break;
00719 }
00720 if ( LocaleCompare(keyword, "matte-color") == 0)
00721 {
00722 ( void) QueryColorDatabase(options,&image-> matte_color,
00723 exception);
00724 break;
00725 }
00726 if ( LocaleCompare(keyword, "montage") == 0)
00727 {
00728 ( void) CloneString(&image-> montage,options);
00729 break;
00730 }
00731 ( void) SetImageAttribute(image,keyword,options);
00732 break;
00733 }
00734 case 'o':
00735 case 'O':
00736 {
00737 if ( LocaleCompare(keyword, "opaque") == 0)
00738 {
00739 image-> matte=( MagickBooleanType) ParseMagickOption(
00740 MagickBooleanOptions,MagickFalse,options);
00741 break;
00742 }
00743 ( void) SetImageAttribute(image,keyword,options);
00744 break;
00745 }
00746 case 'p':
00747 case 'P':
00748 {
00749 if ( LocaleCompare(keyword, "page") == 0)
00750 {
00751 char
00752 *geometry;
00753
00754 geometry= GetPageGeometry(options);
00755 ( void) ParseAbsoluteGeometry(geometry,&image-> page);
00756 geometry=( char *) RelinquishMagickMemory(geometry);
00757 break;
00758 }
00759 if ( LocaleNCompare(keyword, "profile-",8) == 0)
00760 {
00761 if (profiles == ( LinkedListInfo *) NULL)
00762 profiles= NewLinkedList(0);
00763 ( void) AppendElementToLinkedList(profiles,
00764 AcquireString(keyword+8));
00765 profile= AcquireStringInfo((size_t) atol(options));
00766 ( void) SetImageProfile(image,keyword+8,profile);
00767 profile= DestroyStringInfo(profile);
00768 break;
00769 }
00770 ( void) SetImageAttribute(image,keyword,options);
00771 break;
00772 }
00773 case 'r':
00774 case 'R':
00775 {
00776 if ( LocaleCompare(keyword, "red-primary") == 0)
00777 {
00778 flags= ParseGeometry(options,&geometry_info);
00779 image-> chromaticity. red_primary. x=geometry_info. rho;
00780 image-> chromaticity. red_primary. y=geometry_info. sigma;
00781 if ((flags & SigmaValue) == 0)
00782 image-> chromaticity. red_primary. y=
00783 image-> chromaticity. red_primary. x;
00784 break;
00785 }
00786 if ( LocaleCompare(keyword, "rendering-intent") == 0)
00787 {
00788 image-> rendering_intent=( RenderingIntent)
00789 ParseMagickOption(MagickIntentOptions,MagickFalse,options);
00790 break;
00791 }
00792 if ( LocaleCompare(keyword, "resolution") == 0)
00793 {
00794 flags= ParseGeometry(options,&geometry_info);
00795 image-> x_resolution=geometry_info. rho;
00796 image-> y_resolution=geometry_info. sigma;
00797 if ((flags & SigmaValue) == 0)
00798 image-> y_resolution=image-> x_resolution;
00799 break;
00800 }
00801 if ( LocaleCompare(keyword, "rows") == 0)
00802 {
00803 image-> rows=( unsigned long) atol(options);
00804 break;
00805 }
00806 ( void) SetImageAttribute(image,keyword,options);
00807 break;
00808 }
00809 case 's':
00810 case 'S':
00811 {
00812 if ( LocaleCompare(keyword, "scene") == 0)
00813 {
00814 image-> scene=( unsigned long) atol(options);
00815 break;
00816 }
00817 ( void) SetImageAttribute(image,keyword,options);
00818 break;
00819 }
00820 case 'u':
00821 case 'U':
00822 {
00823 if ( LocaleCompare(keyword, "units") == 0)
00824 {
00825 image-> units=( ResolutionType) ParseMagickOption(
00826 MagickResolutionOptions,MagickFalse,options);
00827 break;
00828 }
00829 ( void) SetImageAttribute(image,keyword,options);
00830 break;
00831 }
00832 case 'v':
00833 case 'V':
00834 {
00835 if ( LocaleCompare(keyword, "version") == 0)
00836 {
00837 version=atof(options);
00838 break;
00839 }
00840 ( void) SetImageAttribute(image,keyword,options);
00841 break;
00842 }
00843 case 'w':
00844 case 'W':
00845 {
00846 if ( LocaleCompare(keyword, "white-point") == 0)
00847 {
00848 flags= ParseGeometry(options,&geometry_info);
00849 image-> chromaticity. white_point. x=geometry_info. rho;
00850 image-> chromaticity. white_point. y=geometry_info. rho;
00851 if ((flags & SigmaValue) != 0)
00852 image-> chromaticity. white_point. y=
00853 image-> chromaticity. white_point. x;
00854 break;
00855 }
00856 ( void) SetImageAttribute(image,keyword,options);
00857 break;
00858 }
00859 default:
00860 {
00861 ( void) SetImageAttribute(image,keyword,options);
00862 break;
00863 }
00864 }
00865 }
00866 else
00867 c= ReadBlobByte(image);
00868 while (isspace(( int) (( unsigned char) c)) != 0)
00869 c= ReadBlobByte(image);
00870 }
00871 options=( char *) RelinquishMagickMemory(options);
00872 ( void) ReadBlobByte(image);
00873
00874
00875
00876 if (( LocaleCompare( id, "ImageMagick") != 0) ||
00877 (image-> storage_class == UndefinedClass) ||
00878 (image-> columns == 0) || (image-> rows == 0))
00879 ThrowReaderException(CorruptImageError, "ImproperImageHeader");
00880 if (image-> montage != ( char *) NULL)
00881 {
00882 register char
00883 *p;
00884
00885
00886
00887
00888 length= MaxTextExtent;
00889 image-> directory= AcquireString(( char *) NULL);
00890 p=image-> directory;
00891 do
00892 {
00893 *p= '\0';
00894 if ((strlen(image-> directory)+ MaxTextExtent) >= length)
00895 {
00896
00897
00898
00899 length<<=1;
00900 image-> directory=( char *) ResizeMagickMemory(image-> directory,
00901 (length+MaxTextExtent)* sizeof(*image-> directory));
00902 if (image-> directory == ( char *) NULL)
00903 ThrowReaderException(CorruptImageError, "UnableToReadImageData");
00904 p=image-> directory+strlen(image-> directory);
00905 }
00906 c= ReadBlobByte(image);
00907 *p++=( char) c;
00908 } while (c != ( int) '\0');
00909 }
00910 if (profiles != ( LinkedListInfo *) NULL)
00911 {
00912 const char
00913 * name;
00914
00915
00916
00917
00918 ResetLinkedListIterator(profiles);
00919 name=( const char *) GetNextElementInLinkedList(profiles);
00920 while ( name != ( const char *) NULL)
00921 {
00922 profile= GetImageProfile(image,name);
00923 ( void) ReadBlob(image,profile-> length,profile-> datum);
00924 name=( const char *) GetNextElementInLinkedList(profiles);
00925 }
00926 profiles= DestroyLinkedList(profiles,RelinquishMagickMemory);
00927 }
00928 depth= GetImageQuantumDepth(image,MagickFalse);
00929 if (image-> storage_class == PseudoClass)
00930 {
00931
00932
00933
00934 status= AllocateImageColormap(image,colors != 0 ? colors : 256);
00935 if (status == MagickFalse)
00936 ThrowReaderException(ResourceLimitError, "MemoryAllocationFailed");
00937 if (colors != 0)
00938 {
00939 size_t
00940 packet_size;
00941
00942 unsigned char
00943 *colormap;
00944
00945 unsigned long
00946 pixel;
00947
00948
00949
00950
00951 packet_size=(size_t) (3*depth/8);
00952 colormap=( unsigned char *)
00953 AcquireMagickMemory(packet_size*image-> colors);
00954 if (colormap == ( unsigned char *) NULL)
00955 ThrowReaderException(ResourceLimitError, "MemoryAllocationFailed");
00956 ( void) ReadBlob(image,packet_size*image-> colors,colormap);
00957 p=colormap;
00958 switch (depth)
00959 {
00960 default:
00961 ThrowReaderException(CorruptImageError,
00962 "ImageDepthNotSupported");
00963 case 8:
00964 {
00965 for (i=0; i < ( long) image-> colors; i++)
00966 {
00967 PushCharPixel(pixel,p);
00968 image-> colormap[i]. red= ScaleCharToQuantum(pixel);
00969 PushCharPixel(pixel,p);
00970 image-> colormap[i]. green= ScaleCharToQuantum(pixel);
00971 PushCharPixel(pixel,p);
00972 image-> colormap[i]. blue= ScaleCharToQuantum(pixel);
00973 }
00974 break;
00975 }
00976 case 16:
00977 {
00978 for (i=0; i < ( long) image-> colors; i++)
00979 {
00980 PushShortPixel(pixel,p);
00981 image-> colormap[i]. red= ScaleShortToQuantum(pixel);
00982 PushShortPixel(pixel,p);
00983 image-> colormap[i]. green= ScaleShortToQuantum(pixel);
00984 PushShortPixel(pixel,p);
00985 image-> colormap[i]. blue= ScaleShortToQuantum(pixel);
00986 }
00987
|