Beispiel #1
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+     I s S c e n e G e o m e t r y                                           %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  IsSceneGeometry() returns MagickTrue if the geometry is a valid scene
%  specification (e.g. [1], [1-9], [1,7,4]).
%
%  The format of the IsSceneGeometry method is:
%
%      MagickBooleanType IsSceneGeometry(const char *geometry,
%        const MagickBooleanType pedantic)
%
%  A description of each parameter follows:
%
%    o geometry: This string is the geometry specification.
%
%    o pedantic: A value other than 0 invokes a more restrictive set of
%      conditions for a valid specification (e.g. [1], [1-4], [4-1]).
%
*/
MagickExport MagickBooleanType IsSceneGeometry(const char *geometry,
        const MagickBooleanType pedantic)
{
    char
    *p;

    double
    value;

    if (geometry == (const char *) NULL)
        return(MagickFalse);
    p=(char *) geometry;
    value=InterpretLocaleValue(geometry,&p);
    (void) value;
    if (p == geometry)
        return(MagickFalse);
    if (strspn(geometry,"0123456789-, ") != strlen(geometry))
        return(MagickFalse);
    if ((pedantic != MagickFalse) && (strchr(geometry,',') != (char *) NULL))
        return(MagickFalse);
    return(MagickTrue);
}
Beispiel #2
0
WandExport MagickBooleanType ImportImageCommand(ImageInfo *image_info,
  int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception)
{
#if defined(MAGICKCORE_X11_DELEGATE)
#define DestroyImport() \
{ \
  XDestroyResourceInfo(&resource_info); \
  if (display != (Display *) NULL) \
    { \
      XCloseDisplay(display); \
      display=(Display *) NULL; \
    } \
  DestroyImageStack(); \
  if (target_window != (char *) NULL) \
    target_window=DestroyString(target_window); \
  for (i=0; i < (ssize_t) argc; i++) \
    argv[i]=DestroyString(argv[i]); \
  argv=(char **) RelinquishMagickMemory(argv); \
}
#define ThrowImportException(asperity,tag,option) \
{ \
  (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
     option); \
  DestroyImport(); \
  return(MagickFalse); \
}
#define ThrowImportInvalidArgumentException(option,argument) \
{ \
  (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
    "InvalidArgument","`%s': %s",option,argument); \
  DestroyImport(); \
  return(MagickFalse); \
}

  char
    *filename,
    *option,
    *resource_value,
    *server_name,
    *target_window;

  Display
    *display;

  Image
    *image;

  ImageStack
    image_stack[MaxImageStackDepth+1];

  MagickBooleanType
    fire,
    pend,
    respect_parenthesis;

  MagickStatusType
    status;

  QuantizeInfo
    *quantize_info;

  register ssize_t
    i;

  ssize_t
    j,
    k,
    snapshots;

  XImportInfo
    ximage_info;

  XResourceInfo
    resource_info;

  XrmDatabase
    resource_database;

  /*
    Set defaults.
  */
  assert(image_info != (ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  assert(exception != (ExceptionInfo *) NULL);
  if (argc == 2)
    {
      option=argv[1];
      if ((LocaleCompare("version",option+1) == 0) ||
          (LocaleCompare("-version",option+1) == 0))
        {
          (void) FormatLocaleFile(stdout,"Version: %s\n",
            GetMagickVersion((size_t *) NULL));
          (void) FormatLocaleFile(stdout,"Copyright: %s\n",
            GetMagickCopyright());
          (void) FormatLocaleFile(stdout,"Features: %s\n\n",
            GetMagickFeatures());
          return(MagickFalse);
        }
    }
  display=(Display *) NULL;
  j=1;
  k=0;
  NewImageStack();
  option=(char *) NULL;
  pend=MagickFalse;
  resource_database=(XrmDatabase) NULL;
  respect_parenthesis=MagickFalse;
  (void) ResetMagickMemory(&resource_info,0,sizeof(resource_info));
  server_name=(char *) NULL;
  status=MagickTrue;
  SetNotifyHandlers;
  target_window=(char *) NULL;
  /*
    Check for server name specified on the command line.
  */
  ReadCommandlLine(argc,&argv);
  status=ExpandFilenames(&argc,&argv);
  if (status == MagickFalse)
    ThrowImportException(ResourceLimitError,"MemoryAllocationFailed",
      GetExceptionMessage(errno));
  for (i=1; i < (ssize_t) argc; i++)
  {
    /*
      Check command line for server name.
    */
    option=argv[i];
    if (LocaleCompare("display",option+1) == 0)
      {
        /*
          User specified server name.
        */
        i++;
        if (i == (ssize_t) argc)
          ThrowImportException(OptionError,"MissingArgument",option);
        server_name=argv[i];
      }
    if ((LocaleCompare("help",option+1) == 0) ||
        (LocaleCompare("-help",option+1) == 0))
      return(ImportUsage());
  }
  /*
    Get user defaults from X resource database.
  */
  display=XOpenDisplay(server_name);
  if (display == (Display *) NULL)
    ThrowImportException(XServerError,"UnableToOpenXServer",
      XDisplayName(server_name));
  (void) XSetErrorHandler(XError);
  resource_database=XGetResourceDatabase(display,GetClientName());
  XGetImportInfo(&ximage_info);
  XGetResourceInfo(image_info,resource_database,GetClientName(),
    &resource_info);
  quantize_info=resource_info.quantize_info;
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "border","False");
  ximage_info.borders=IsMagickTrue(resource_value);
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "delay","0");
  resource_info.delay=(unsigned int) StringToUnsignedLong(resource_value);
  image_info->density=XGetResourceInstance(resource_database,GetClientName(),
    "density",(char *) NULL);
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "descend","True");
  ximage_info.descend=IsMagickTrue(resource_value);
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "frame","False");
  ximage_info.frame=IsMagickTrue(resource_value);
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "interlace","none");
  image_info->interlace=UndefinedInterlace;
  if (LocaleCompare("None",resource_value) == 0)
    image_info->interlace=NoInterlace;
  if (LocaleCompare("Line",resource_value) == 0)
    image_info->interlace=LineInterlace;
  if (LocaleCompare("Plane",resource_value) == 0)
    image_info->interlace=PlaneInterlace;
  if (LocaleCompare("Partition",resource_value) == 0)
    image_info->interlace=PartitionInterlace;
  if (image_info->interlace == UndefinedInterlace)
    ThrowImportException(OptionError,"Unrecognized interlace type",
      resource_value);
  image_info->page=XGetResourceInstance(resource_database,GetClientName(),
    "pageGeometry",(char *) NULL);
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "pause","0");
  resource_info.pause=(unsigned int) StringToUnsignedLong(resource_value);
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "quality","85");
  image_info->quality=StringToUnsignedLong(resource_value);
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "screen","False");
  ximage_info.screen=IsMagickTrue(resource_value);
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "silent","False");
  ximage_info.silent=IsMagickTrue(resource_value);
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "verbose","False");
  image_info->verbose=IsMagickTrue(resource_value);
  resource_value=XGetResourceInstance(resource_database,GetClientName(),
    "dither","True");
  quantize_info->dither=IsMagickTrue(resource_value);
  snapshots=1;
  status=MagickTrue;
  filename=(char *) NULL;
  /*
    Check command syntax.
  */
  for (i=1; i < (ssize_t) argc; i++)
  {
    option=argv[i];
    if (LocaleCompare(option,"(") == 0)
      {
        FireImageStack(MagickFalse,MagickTrue,pend);
        if (k == MaxImageStackDepth)
          ThrowImportException(OptionError,"ParenthesisNestedTooDeeply",
            option);
        PushImageStack();
        continue;
      }
    if (LocaleCompare(option,")") == 0)
      {
        FireImageStack(MagickFalse,MagickTrue,MagickTrue);
        if (k == 0)
          ThrowImportException(OptionError,"UnableToParseExpression",option);
        PopImageStack();
        continue;
      }
    if (IsCommandOption(option) == MagickFalse)
      {
        Image
          *images;

        size_t
          scene;

        /*
          Read image from X server.
        */
        FireImageStack(MagickFalse,MagickFalse,pend);
        filename=argv[i];
        if (target_window != (char *) NULL)
          (void) CopyMagickString(image_info->filename,target_window,
            MaxTextExtent);
        for (scene=0; scene < (size_t) MagickMax(snapshots,1); scene++)
        {
          (void) sleep(resource_info.pause);
          images=XImportImage(image_info,&ximage_info);
          status&=(images != (Image *) NULL) &&
            (exception->severity < ErrorException);
          if (images == (Image *) NULL)
            continue;
          (void) CopyMagickString(images->filename,filename,MaxTextExtent);
          (void) CopyMagickString(images->magick,"PS",MaxTextExtent);
          images->scene=scene;
          AppendImageStack(images);
        }
        continue;
      }
    pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
    switch(*(option+1))
    {
      case 'a':
      {
        if (LocaleCompare("adjoin",option+1) == 0)
          break;
        if (LocaleCompare("annotate",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            i++;
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'b':
      {
        if (LocaleCompare("border",option+1) == 0)
          {
            (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent);
            ximage_info.borders=(*option == '-') ? MagickTrue : MagickFalse;
            break;
          }
        if (LocaleCompare("bordercolor",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'c':
      {
        if (LocaleCompare("cache",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("channel",option+1) == 0)
          {
            ssize_t
              channel;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            channel=ParseChannelOption(argv[i]);
            if (channel < 0)
              ThrowImportException(OptionError,"UnrecognizedChannelType",
                argv[i]);
            break;
          }
        if (LocaleCompare("colors",option+1) == 0)
          {
            quantize_info->number_colors=0;
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            quantize_info->number_colors=StringToUnsignedLong(argv[i]);
            break;
          }
        if (LocaleCompare("colorspace",option+1) == 0)
          {
            ssize_t
              colorspace;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            colorspace=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
              argv[i]);
            if (colorspace < 0)
              ThrowImportException(OptionError,"UnrecognizedColorspace",
                argv[i]);
            break;
          }
        if (LocaleCompare("comment",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            status=SetImageOption(image_info,"comment",argv[i]);
            if (status == MagickFalse)
              ThrowImportException(OptionError,"UnrecognizedOption",argv[i]);
            break;
          }
        if (LocaleCompare("compress",option+1) == 0)
          {
            ssize_t
              compress;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
              argv[i]);
            if (compress < 0)
              ThrowImportException(OptionError,"UnrecognizedImageCompression",
                argv[i]);
            break;
          }
        if (LocaleCompare("concurrent",option+1) == 0)
          break;
        if (LocaleCompare("crop",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'd':
      {
        if (LocaleCompare("debug",option+1) == 0)
          {
            ssize_t
              event;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
            if (event < 0)
              ThrowImportException(OptionError,"UnrecognizedEventType",argv[i]);
            (void) SetLogEventMask(argv[i]);
            break;
          }
        if (LocaleCompare("define",option+1) == 0)
          {
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (*option == '+')
              {
                const char
                  *define;

                define=GetImageOption(image_info,argv[i]);
                if (define == (char *) NULL)
                  ThrowImportException(OptionError,"NoSuchOption",argv[i]);
                break;
              }
            break;
          }
        if (LocaleCompare("delay",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            status=SetImageOption(image_info,"delay",argv[i]);
            if (status == MagickFalse)
              ThrowImportException(OptionError,"UnrecognizedOption",argv[i]);
            break;
          }
        if (LocaleCompare("density",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("depth",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("descend",option+1) == 0)
          {
            ximage_info.descend=(*option == '-') ? MagickTrue : MagickFalse;
            break;
          }
        if (LocaleCompare("display",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("dispose",option+1) == 0)
          {
            ssize_t
              dispose;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,argv[i]);
            if (dispose < 0)
              ThrowImportException(OptionError,"UnrecognizedDisposeMethod",
                argv[i]);
            break;
          }
        if (LocaleCompare("dither",option+1) == 0)
          {
            ssize_t
              method;

            quantize_info->dither=MagickFalse;
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            method=ParseCommandOption(MagickDitherOptions,MagickFalse,argv[i]);
            if (method < 0)
              ThrowImportException(OptionError,"UnrecognizedDitherMethod",
                argv[i]);
            quantize_info->dither=MagickTrue;
            quantize_info->dither_method=(DitherMethod) method;
            break;
          }
        if (LocaleCompare("duration",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'e':
      {
        if (LocaleCompare("encipher",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("encoding",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("endian",option+1) == 0)
          {
            ssize_t
              endian;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
              argv[i]);
            if (endian < 0)
              ThrowImportException(OptionError,"UnrecognizedEndianType",
                argv[i]);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'f':
      {
        if (LocaleCompare("filter",option+1) == 0)
          {
            ssize_t
              filter;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            filter=ParseCommandOption(MagickFilterOptions,MagickFalse,argv[i]);
            if (filter < 0)
              ThrowImportException(OptionError,"UnrecognizedImageFilter",
                argv[i]);
            break;
          }
        if (LocaleCompare("frame",option+1) == 0)
          {
            (void) CopyMagickString(argv[i]+1,"sans0",MaxTextExtent);
            ximage_info.frame=(*option == '-') ? MagickTrue : MagickFalse;
            break;
          }
        if (LocaleCompare("format",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'g':
      {
        if (LocaleCompare("geometry",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("gravity",option+1) == 0)
          {
            ssize_t
              gravity;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,argv[i]);
            if (gravity < 0)
              ThrowImportException(OptionError,"UnrecognizedGravityType",
                argv[i]);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'h':
      {
        if (LocaleCompare("help",option+1) == 0)
          break;
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'i':
      {
        if (LocaleCompare("identify",option+1) == 0)
          break;
        if (LocaleCompare("interlace",option+1) == 0)
          {
            ssize_t
              interlace;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
              argv[i]);
            if (interlace < 0)
              ThrowImportException(OptionError,"UnrecognizedInterlaceType",
                argv[i]);
            break;
          }
        if (LocaleCompare("interpolate",option+1) == 0)
          {
            ssize_t
              interpolate;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
              argv[i]);
            if (interpolate < 0)
              ThrowImportException(OptionError,"UnrecognizedInterpolateMethod",
                argv[i]);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'l':
      {
        if (LocaleCompare("label",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            status=SetImageOption(image_info,"label",argv[i]);
            if (status == MagickFalse)
              ThrowImportException(OptionError,"UnrecognizedOption",argv[i]);
            break;
          }
        if (LocaleCompare("limit",option+1) == 0)
          {
            char
              *p;

            double
              value;

            ssize_t
              resource;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
              argv[i]);
            if (resource < 0)
              ThrowImportException(OptionError,"UnrecognizedResourceType",
                argv[i]);
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            value=InterpretLocaleValue(argv[i],&p);
            (void) value;
            if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("list",option+1) == 0)
          {
            ssize_t
              list;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
            if (list < 0)
              ThrowImportException(OptionError,"UnrecognizedListType",argv[i]);
            status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
              argv+j,exception);
            DestroyImport();
            return(status != 0 ? MagickFalse : MagickTrue);
          }
        if (LocaleCompare("log",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
              ThrowImportException(OptionError,"MissingArgument",option);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'm':
      {
        if (LocaleCompare("monitor",option+1) == 0)
          break;
        if (LocaleCompare("monochrome",option+1) == 0)
          {
            if (*option == '+')
              break;
            quantize_info->number_colors=2;
            quantize_info->colorspace=GRAYColorspace;
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'n':
      {
        if (LocaleCompare("negate",option+1) == 0)
          break;
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'p':
      {
        if (LocaleCompare("page",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            status=SetImageOption(image_info,"page",argv[i]);
            if (status == MagickFalse)
              ThrowImportException(OptionError,"UnrecognizedOption",argv[i]);
            break;
          }
        if (LocaleCompare("pause",option+1) == 0)
          {
            resource_info.pause=0;
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            resource_info.pause=(unsigned int) StringToUnsignedLong(argv[i]);
            break;
          }
        if (LocaleCompare("ping",option+1) == 0)
          break;  /* deprecated option */
        if (LocaleCompare("pointsize",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'q':
      {
        if (LocaleCompare("quality",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("quantize",option+1) == 0)
          {
            ssize_t
              colorspace;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            colorspace=ParseCommandOption(MagickColorspaceOptions,
              MagickFalse,argv[i]);
            if (colorspace < 0)
              ThrowImportException(OptionError,"UnrecognizedColorspace",
                argv[i]);
            break;
          }
        if (LocaleCompare("quiet",option+1) == 0)
          break;
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'r':
      {
        if (LocaleCompare("regard-warnings",option+1) == 0)
          break;
        if (LocaleCompare("repage",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("resize",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
          {
            respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
            break;
          }
        if (LocaleCompare("rotate",option+1) == 0)
          {
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 's':
      {
        if (LocaleCompare("sampling-factor",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("scene",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("set",option+1) == 0)
          {
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("screen",option+1) == 0)
          {
            ximage_info.screen=(*option == '-') ? MagickTrue : MagickFalse;
            break;
          }
        if (LocaleCompare("seed",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("silent",option+1) == 0)
          {
            ximage_info.silent=(*option == '-') ? MagickTrue : MagickFalse;
            break;
          }
        if (LocaleCompare("snaps",option+1) == 0)
          {
            (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent);
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            snapshots=(ssize_t) StringToLong(argv[i]);
            break;
          }
        if (LocaleCompare("strip",option+1) == 0)
          break;
        if (LocaleCompare("support",option+1) == 0)
          {
            i++;  /* deprecated */
            break;
          }
        if (LocaleCompare("synchronize",option+1) == 0)
          break;
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 't':
      {
        if (LocaleCompare("taint",option+1) == 0)
          break;
        if (LocaleCompare("thumbnail",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            break;
          }
        if (LocaleCompare("transparent",option+1) == 0)
          {
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("transparent-color",option+1) == 0)
          {
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) (argc-1))
              ThrowImportException(OptionError,"MissingArgument",option);
            break;
          }
        if (LocaleCompare("treedepth",option+1) == 0)
          {
            quantize_info->tree_depth=0;
            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            if (IsGeometry(argv[i]) == MagickFalse)
              ThrowImportInvalidArgumentException(option,argv[i]);
            quantize_info->tree_depth=StringToUnsignedLong(argv[i]);
            break;
          }
        if (LocaleCompare("trim",option+1) == 0)
          break;
        if (LocaleCompare("type",option+1) == 0)
          {
            ssize_t
              type;

            if (*option == '+')
              break;
            i++;
            if (i == (ssize_t) argc)
              ThrowImportException(OptionError,"MissingArgument",option);
            type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
            if (type < 0)
              ThrowImportException(OptionError,"UnrecognizedImageType",argv[i]);
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case 'w':
      {
        i++;
        if (i == (ssize_t) argc)
          ThrowImportException(OptionError,"MissingArgument",option);
        (void) CloneString(&target_window,argv[i]);
        break;
      }
      case 'v':
      {
        if (LocaleCompare("verbose",option+1) == 0)
          break;
        if ((LocaleCompare("version",option+1) == 0) ||
            (LocaleCompare("-version",option+1) == 0))
          {
            (void) FormatLocaleFile(stdout,"Version: %s\n",
              GetMagickVersion((size_t *) NULL));
            (void) FormatLocaleFile(stdout,"Copyright: %s\n",
              GetMagickCopyright());
            (void) FormatLocaleFile(stdout,"Features: %s\n\n",
              GetMagickFeatures());
            break;
          }
        ThrowImportException(OptionError,"UnrecognizedOption",option);
      }
      case '?':
        break;
      default:
        ThrowImportException(OptionError,"UnrecognizedOption",option);
    }
    fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
      FireOptionFlag) == 0 ?  MagickFalse : MagickTrue;
    if (fire != MagickFalse)
      FireImageStack(MagickFalse,MagickTrue,MagickTrue);
  }
  if (k != 0)
    ThrowImportException(OptionError,"UnbalancedParenthesis",argv[i]);
  if (i-- != (ssize_t) argc)
    ThrowImportException(OptionError,"MissingAnImageFilename",argv[i]);
  if (image == (Image *) NULL)
    ThrowImportException(OptionError,"MissingAnImageFilename",argv[argc-1]);
  FinalizeImageSettings(image_info,image,MagickTrue);
  status&=WriteImages(image_info,image,filename,exception);
  DestroyImport();
  return(status != 0 ? MagickTrue : MagickFalse);
#else
  (void) argc;
  (void) argv;
  (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
    "DelegateLibrarySupportNotBuiltIn","`%s' (X11)",image_info->filename);
  return(ImportUsage());
#endif
}
Beispiel #3
0
static Image *ReadFITSImage(const ImageInfo *image_info,
                            ExceptionInfo *exception)
{
    typedef struct _FITSInfo
    {
        MagickBooleanType
        extend,
        simple;

        int
        bits_per_pixel,
        columns,
        rows,
        number_axes,
        number_planes;

        double
        min_data,
        max_data,
        zero,
        scale;

        EndianType
        endian;
    } FITSInfo;

    char
    *comment,
    keyword[9],
    property[MaxTextExtent],
    value[73];

    double
    pixel,
    scale;

    FITSInfo
    fits_info;

    Image
    *image;

    int
    c;

    MagickBooleanType
    status;

    MagickSizeType
    number_pixels;

    register ssize_t
    i,
    x;

    register PixelPacket
    *q;

    ssize_t
    count,
    scene,
    y;

    /*
      Open image file.
    */
    assert(image_info != (const ImageInfo *) NULL);
    assert(image_info->signature == MagickSignature);
    if (image_info->debug != MagickFalse)
        (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
                              image_info->filename);
    assert(exception != (ExceptionInfo *) NULL);
    assert(exception->signature == MagickSignature);
    image=AcquireImage(image_info);
    status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    if (status == MagickFalse)
    {
        image=DestroyImageList(image);
        return((Image *) NULL);
    }
    /*
      Initialize image header.
    */
    (void) ResetMagickMemory(&fits_info,0,sizeof(fits_info));
    fits_info.extend=MagickFalse;
    fits_info.simple=MagickFalse;
    fits_info.bits_per_pixel=8;
    fits_info.columns=1;
    fits_info.rows=1;
    fits_info.rows=1;
    fits_info.number_planes=1;
    fits_info.min_data=0.0;
    fits_info.max_data=0.0;
    fits_info.zero=0.0;
    fits_info.scale=1.0;
    fits_info.endian=MSBEndian;
    /*
      Decode image header.
    */
    for (comment=(char *) NULL; EOFBlob(image) == MagickFalse; )
    {
        for ( ; EOFBlob(image) == MagickFalse; )
        {
            register char
            *p;

            count=ReadBlob(image,8,(unsigned char *) keyword);
            if (count != 8)
                break;
            for (i=0; i < 8; i++)
            {
                if (isspace((int) ((unsigned char) keyword[i])) != 0)
                    break;
                keyword[i]=tolower((int) ((unsigned char) keyword[i]));
            }
            keyword[i]='\0';
            count=ReadBlob(image,72,(unsigned char *) value);
            if (count != 72)
                break;
            value[72]='\0';
            p=value;
            if (*p == '=')
            {
                p+=2;
                while (isspace((int) ((unsigned char) *p)) != 0)
                    p++;
            }
            if (LocaleCompare(keyword,"end") == 0)
                break;
            if (LocaleCompare(keyword,"extend") == 0)
                fits_info.extend=(*p == 'T') || (*p == 't') ? MagickTrue : MagickFalse;
            if (LocaleCompare(keyword,"simple") == 0)
                fits_info.simple=(*p == 'T') || (*p == 't') ? MagickTrue : MagickFalse;
            if (LocaleCompare(keyword,"bitpix") == 0)
                fits_info.bits_per_pixel=StringToLong(p);
            if (LocaleCompare(keyword,"naxis") == 0)
                fits_info.number_axes=StringToLong(p);
            if (LocaleCompare(keyword,"naxis1") == 0)
                fits_info.columns=StringToLong(p);
            if (LocaleCompare(keyword,"naxis2") == 0)
                fits_info.rows=StringToLong(p);
            if (LocaleCompare(keyword,"naxis3") == 0)
                fits_info.number_planes=StringToLong(p);
            if (LocaleCompare(keyword,"datamax") == 0)
                fits_info.max_data=InterpretLocaleValue(p,(char **) NULL);
            if (LocaleCompare(keyword,"datamin") == 0)
                fits_info.min_data=InterpretLocaleValue(p,(char **) NULL);
            if (LocaleCompare(keyword,"bzero") == 0)
                fits_info.zero=InterpretLocaleValue(p,(char **) NULL);
            if (LocaleCompare(keyword,"bscale") == 0)
                fits_info.scale=InterpretLocaleValue(p,(char **) NULL);
            if (LocaleCompare(keyword,"comment") == 0)
            {
                if (comment == (char *) NULL)
                    comment=ConstantString(p);
                else
                    (void) ConcatenateString(&comment,p);
            }
            if (LocaleCompare(keyword,"xendian") == 0)
            {
                if (LocaleNCompare(p,"big",3) == 0)
                    fits_info.endian=MSBEndian;
                else
                    fits_info.endian=LSBEndian;
            }
            (void) FormatLocaleString(property,MaxTextExtent,"fits:%s",keyword);
            (void) SetImageProperty(image,property,p);
        }
        c=0;
        while (((TellBlob(image) % FITSBlocksize) != 0) && (c != EOF))
            c=ReadBlobByte(image);
        if (fits_info.extend == MagickFalse)
            break;
        number_pixels=(MagickSizeType) fits_info.columns*fits_info.rows;
        if ((fits_info.simple != MagickFalse) && (fits_info.number_axes >= 1) &&
                (fits_info.number_axes <= 4) && (number_pixels != 0))
            break;
    }
    /*
      Verify that required image information is defined.
    */
    if (comment != (char *) NULL)
    {
        (void) SetImageProperty(image,"comment",comment);
        comment=DestroyString(comment);
    }
    if (EOFBlob(image) != MagickFalse)
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
                           image->filename);
    number_pixels=(MagickSizeType) fits_info.columns*fits_info.rows;
    if ((fits_info.simple == MagickFalse) || (fits_info.number_axes < 1) ||
            (fits_info.number_axes > 4) || (number_pixels == 0))
        ThrowReaderException(CorruptImageError,"ImageTypeNotSupported");
    for (scene=0; scene < (ssize_t) fits_info.number_planes; scene++)
    {
        image->columns=(size_t) fits_info.columns;
        image->rows=(size_t) fits_info.rows;
        image->depth=(size_t) (fits_info.bits_per_pixel < 0 ? -1 : 1)*
                     fits_info.bits_per_pixel;
        image->endian=fits_info.endian;
        image->scene=(size_t) scene;
        if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
            if (image->scene >= (image_info->scene+image_info->number_scenes-1))
                break;
        /*
          Initialize image structure.
        */
        if ((fits_info.min_data != 0.0) || (fits_info.max_data != 0.0))
        {
            if ((fits_info.bits_per_pixel != 0) && (fits_info.max_data == 0.0))
                fits_info.max_data=GetFITSPixelRange((size_t)
                                                     fits_info.bits_per_pixel);
        }
        else
            GetFITSPixelExtrema(image,fits_info.bits_per_pixel,&fits_info.min_data,
                                &fits_info.max_data);
        /*
          Convert FITS pixels to pixel packets.
        */
        scale=(double) QuantumRange/(fits_info.scale*(fits_info.max_data-
                                     fits_info.min_data)+fits_info.zero);
        for (y=(ssize_t) image->rows-1; y >= 0; y--)
        {
            q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
            if (q == (PixelPacket *) NULL)
                break;
            for (x=0; x < (ssize_t) image->columns; x++)
            {
                pixel=GetFITSPixel(image,fits_info.bits_per_pixel);
                SetPixelRed(q,ClampToQuantum(scale*(fits_info.scale*(pixel-
                                                    fits_info.min_data)+fits_info.zero)));
                SetPixelGreen(q,GetPixelRed(q));
                SetPixelBlue(q,GetPixelRed(q));
                q++;
            }
            if (SyncAuthenticPixels(image,exception) == MagickFalse)
                break;
            if (image->previous == (Image *) NULL)
            {
                status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                                        image->rows);
                if (status == MagickFalse)
                    break;
            }
        }
        if (EOFBlob(image) != MagickFalse)
        {
            ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
                               image->filename);
            break;
        }
        /*
          Proceed to next image.
        */
        if (image_info->number_scenes != 0)
            if (image->scene >= (image_info->scene+image_info->number_scenes-1))
                break;
        if (scene < (ssize_t) (fits_info.number_planes-1))
        {
            /*
              Allocate next image structure.
            */
            AcquireNextImage(image_info,image);
            if (GetNextImageInList(image) == (Image *) NULL)
            {
                image=DestroyImageList(image);
                return((Image *) NULL);
            }
            image=SyncNextImageInList(image);
            status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
                                    GetBlobSize(image));
            if (status == MagickFalse)
                break;
        }
    }
    (void) CloseBlob(image);
    return(GetFirstImageInList(image));
}
Beispiel #4
0
static MagickBooleanType WriteJBIGImage(const ImageInfo *image_info,
  Image *image)
{
  double
    version;

  MagickBooleanType
    status;

  MagickOffsetType
    scene;

  register const IndexPacket
    *indexes;

  register const PixelPacket
    *p;

  register ssize_t
    x;

  register unsigned char
    *q;

  size_t
    number_packets;

  ssize_t
    y;

  struct jbg_enc_state
    jbig_info;

  unsigned char
    bit,
    byte,
    *pixels;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
  if (status == MagickFalse)
    return(status);
  version=InterpretLocaleValue(JBG_VERSION,(char **) NULL);
  scene=0;
  do
  {
    /*
      Allocate pixel data.
    */
    if (IsRGBColorspace(image->colorspace) == MagickFalse)
      (void) TransformImageColorspace(image,RGBColorspace);
    number_packets=(image->columns+7)/8;
    pixels=(unsigned char *) AcquireQuantumMemory(number_packets,
      image->rows*sizeof(*pixels));
    if (pixels == (unsigned char *) NULL)
      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    /*
      Convert pixels to a bitmap.
    */
    (void) SetImageType(image,BilevelType);
    q=pixels;
    for (y=0; y < (ssize_t) image->rows; y++)
    {
      p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
      if (p == (const PixelPacket *) NULL)
        break;
      indexes=GetVirtualIndexQueue(image);
      bit=0;
      byte=0;
      for (x=0; x < (ssize_t) image->columns; x++)
      {
        byte<<=1;
        if (PixelIntensity(p) < (QuantumRange/2.0))
          byte|=0x01;
        bit++;
        if (bit == 8)
          {
            *q++=byte;
            bit=0;
            byte=0;
          }
        p++;
      }
      if (bit != 0)
        *q++=byte << (8-bit);
      if (image->previous == (Image *) NULL)
        {
          status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
            image->rows);
          if (status == MagickFalse)
            break;
        }
    }
    /*
      Initialize JBIG info structure.
    */
    jbg_enc_init(&jbig_info,(unsigned long) image->columns,(unsigned long)
      image->rows,1,&pixels,(void (*)(unsigned char *,size_t,void *))
      JBIGEncode,image);
    if (image_info->scene != 0)
      jbg_enc_layers(&jbig_info,(int) image_info->scene);
    else
      {
        size_t
          x_resolution,
          y_resolution;

        ssize_t
          sans_offset;

        x_resolution=640;
        y_resolution=480;
        sans_offset=0;
        if (image_info->density != (char *) NULL)
          {
            GeometryInfo
              geometry_info;

            MagickStatusType
              flags;

            flags=ParseGeometry(image_info->density,&geometry_info);
            x_resolution=geometry_info.rho;
            y_resolution=geometry_info.sigma;
            if ((flags & SigmaValue) == 0)
              y_resolution=x_resolution;
          }
        if (image->units == PixelsPerCentimeterResolution)
          {
            x_resolution=(size_t) (100.0*2.54*x_resolution+0.5)/100.0;
            y_resolution=(size_t) (100.0*2.54*y_resolution+0.5)/100.0;
          }
        (void) jbg_enc_lrlmax(&jbig_info,(unsigned long) x_resolution,
          (unsigned long) y_resolution);
      }
    (void) jbg_enc_lrange(&jbig_info,-1,-1);
    jbg_enc_options(&jbig_info,JBG_ILEAVE | JBG_SMID,JBG_TPDON | JBG_TPBON |
      JBG_DPON,version < 1.6 ? -1 : 0,-1,-1);
    /*
      Write JBIG image.
    */
    jbg_enc_out(&jbig_info);
    jbg_enc_free(&jbig_info);
    pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    if (GetNextImageInList(image) == (Image *) NULL)
      break;
    image=SyncNextImageInList(image);
    status=SetImageProgress(image,SaveImagesTag,scene++,
      GetImageListLength(image));
    if (status == MagickFalse)
      break;
  } while (image_info->adjoin != MagickFalse);
  (void) CloseBlob(image);
  return(MagickTrue);
}
Beispiel #5
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d C A C H E I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadMPCImage() reads an Magick Persistent Cache image file and returns
%  it.  It allocates the memory necessary for the new Image structure and
%  returns a pointer to the new image.
%
%  The format of the ReadMPCImage method is:
%
%      Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  Decompression code contributed by Kyle Shorter.
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    cache_filename[MaxTextExtent],
    id[MaxTextExtent],
    keyword[MaxTextExtent],
    *options;

  const unsigned char
    *p;

  GeometryInfo
    geometry_info;

  Image
    *image;

  int
    c;

  LinkedListInfo
    *profiles;

  MagickBooleanType
    status;

  MagickOffsetType
    offset;

  MagickStatusType
    flags;

  register ssize_t
    i;

  size_t
    depth,
    length,
    quantum_depth;

  ssize_t
    count;

  StringInfo
    *profile;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  (void) CopyMagickString(cache_filename,image->filename,MaxTextExtent);
  AppendImageFormat("cache",cache_filename);
  c=ReadBlobByte(image);
  if (c == EOF)
    {
      image=DestroyImage(image);
      return((Image *) NULL);
    }
  *id='\0';
  (void) ResetMagickMemory(keyword,0,sizeof(keyword));
  offset=0;
  do
  {
    /*
      Decode image header;  header terminates one character beyond a ':'.
    */
    profiles=(LinkedListInfo *) NULL;
    length=MaxTextExtent;
    options=AcquireString((char *) NULL);
    quantum_depth=MAGICKCORE_QUANTUM_DEPTH;
    image->depth=8;
    image->compression=NoCompression;
    while ((isgraph(c) != MagickFalse) && (c != (int) ':'))
    {
      register char
        *p;

      if (c == (int) '{')
        {
          char
            *comment;

          /*
            Read comment-- any text between { }.
          */
          length=MaxTextExtent;
          comment=AcquireString((char *) NULL);
          for (p=comment; comment != (char *) NULL; p++)
          {
            c=ReadBlobByte(image);
            if ((c == EOF) || (c == (int) '}'))
              break;
            if ((size_t) (p-comment+1) >= length)
              {
                *p='\0';
                length<<=1;
                comment=(char *) ResizeQuantumMemory(comment,length+
                  MaxTextExtent,sizeof(*comment));
                if (comment == (char *) NULL)
                  break;
                p=comment+strlen(comment);
              }
            *p=(char) c;
          }
          if (comment == (char *) NULL)
            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
          *p='\0';
          (void) SetImageProperty(image,"comment",comment);
          comment=DestroyString(comment);
          c=ReadBlobByte(image);
        }
      else
        if (isalnum(c) != MagickFalse)
          {
            /*
              Get the keyword.
            */
            p=keyword;
            do
            {
              if (c == (int) '=')
                break;
              if ((size_t) (p-keyword) < (MaxTextExtent-1))
                *p++=(char) c;
              c=ReadBlobByte(image);
            } while (c != EOF);
            *p='\0';
            p=options;
            while (isspace((int) ((unsigned char) c)) != 0)
              c=ReadBlobByte(image);
            if (c == (int) '=')
              {
                /*
                  Get the keyword value.
                */
                c=ReadBlobByte(image);
                while ((c != (int) '}') && (c != EOF))
                {
                  if ((size_t) (p-options+1) >= length)
                    {
                      *p='\0';
                      length<<=1;
                      options=(char *) ResizeQuantumMemory(options,length+
                        MaxTextExtent,sizeof(*options));
                      if (options == (char *) NULL)
                        break;
                      p=options+strlen(options);
                    }
                  if (options == (char *) NULL)
                    ThrowReaderException(ResourceLimitError,
                      "MemoryAllocationFailed");
                  *p++=(char) c;
                  c=ReadBlobByte(image);
                  if (*options != '{')
                    if (isspace((int) ((unsigned char) c)) != 0)
                      break;
                }
              }
            *p='\0';
            if (*options == '{')
              (void) CopyMagickString(options,options+1,MaxTextExtent);
            /*
              Assign a value to the specified keyword.
            */
            switch (*keyword)
            {
              case 'b':
              case 'B':
              {
                if (LocaleCompare(keyword,"background-color") == 0)
                  {
                    (void) QueryColorDatabase(options,&image->background_color,
                      exception);
                    break;
                  }
                if (LocaleCompare(keyword,"blue-primary") == 0)
                  {
                    flags=ParseGeometry(options,&geometry_info);
                    image->chromaticity.blue_primary.x=geometry_info.rho;
                    image->chromaticity.blue_primary.y=geometry_info.sigma;
                    if ((flags & SigmaValue) == 0)
                      image->chromaticity.blue_primary.y=
                        image->chromaticity.blue_primary.x;
                    break;
                  }
                if (LocaleCompare(keyword,"border-color") == 0)
                  {
                    (void) QueryColorDatabase(options,&image->border_color,
                      exception);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'c':
              case 'C':
              {
                if (LocaleCompare(keyword,"class") == 0)
                  {
                    ssize_t
                      storage_class;

                    storage_class=ParseCommandOption(MagickClassOptions,
                      MagickFalse,options);
                    if (storage_class < 0)
                      break;
                    image->storage_class=(ClassType) storage_class;
                    break;
                  }
                if (LocaleCompare(keyword,"colors") == 0)
                  {
                    image->colors=StringToUnsignedLong(options);
                    break;
                  }
                if (LocaleCompare(keyword,"colorspace") == 0)
                  {
                    ssize_t
                      colorspace;

                    colorspace=ParseCommandOption(MagickColorspaceOptions,
                      MagickFalse,options);
                    if (colorspace < 0)
                      break;
                    image->colorspace=(ColorspaceType) colorspace;
                    break;
                  }
                if (LocaleCompare(keyword,"compression") == 0)
                  {
                    ssize_t
                      compression;

                    compression=ParseCommandOption(MagickCompressOptions,
                      MagickFalse,options);
                    if (compression < 0)
                      break;
                    image->compression=(CompressionType) compression;
                    break;
                  }
                if (LocaleCompare(keyword,"columns") == 0)
                  {
                    image->columns=StringToUnsignedLong(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'd':
              case 'D':
              {
                if (LocaleCompare(keyword,"delay") == 0)
                  {
                    image->delay=StringToUnsignedLong(options);
                    break;
                  }
                if (LocaleCompare(keyword,"depth") == 0)
                  {
                    image->depth=StringToUnsignedLong(options);
                    break;
                  }
                if (LocaleCompare(keyword,"dispose") == 0)
                  {
                    ssize_t
                      dispose;

                    dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,
                      options);
                    if (dispose < 0)
                      break;
                    image->dispose=(DisposeType) dispose;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'e':
              case 'E':
              {
                if (LocaleCompare(keyword,"endian") == 0)
                  {
                    ssize_t
                      endian;

                    endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
                      options);
                    if (endian < 0)
                      break;
                    image->endian=(EndianType) endian;
                    break;
                  }
                if (LocaleCompare(keyword,"error") == 0)
                  {
                    image->error.mean_error_per_pixel=InterpretLocaleValue(
                      options,(char **) NULL);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'g':
              case 'G':
              {
                if (LocaleCompare(keyword,"gamma") == 0)
                  {
                    image->gamma=InterpretLocaleValue(options,(char **) NULL);
                    break;
                  }
                if (LocaleCompare(keyword,"green-primary") == 0)
                  {
                    flags=ParseGeometry(options,&geometry_info);
                    image->chromaticity.green_primary.x=geometry_info.rho;
                    image->chromaticity.green_primary.y=geometry_info.sigma;
                    if ((flags & SigmaValue) == 0)
                      image->chromaticity.green_primary.y=
                        image->chromaticity.green_primary.x;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'i':
              case 'I':
              {
                if (LocaleCompare(keyword,"id") == 0)
                  {
                    (void) CopyMagickString(id,options,MaxTextExtent);
                    break;
                  }
                if (LocaleCompare(keyword,"iterations") == 0)
                  {
                    image->iterations=StringToUnsignedLong(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'm':
              case 'M':
              {
                if (LocaleCompare(keyword,"matte") == 0)
                  {
                    ssize_t
                      matte;

                    matte=ParseCommandOption(MagickBooleanOptions,MagickFalse,
                      options);
                    if (matte < 0)
                      break;
                    image->matte=(MagickBooleanType) matte;
                    break;
                  }
                if (LocaleCompare(keyword,"matte-color") == 0)
                  {
                    (void) QueryColorDatabase(options,&image->matte_color,
                      exception);
                    break;
                  }
                if (LocaleCompare(keyword,"maximum-error") == 0)
                  {
                    image->error.normalized_maximum_error=
                      InterpretLocaleValue(options,(char **) NULL);
                    break;
                  }
                if (LocaleCompare(keyword,"mean-error") == 0)
                  {
                    image->error.normalized_mean_error=InterpretLocaleValue(
                      options,(char **) NULL);
                    break;
                  }
                if (LocaleCompare(keyword,"montage") == 0)
                  {
                    (void) CloneString(&image->montage,options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'o':
              case 'O':
              {
                if (LocaleCompare(keyword,"opaque") == 0)
                  {
                    ssize_t
                      matte;

                    matte=ParseCommandOption(MagickBooleanOptions,MagickFalse,
                      options);
                    if (matte < 0)
                      break;
                    image->matte=(MagickBooleanType) matte;
                    break;
                  }
                if (LocaleCompare(keyword,"orientation") == 0)
                  {
                    ssize_t
                      orientation;

                    orientation=ParseCommandOption(MagickOrientationOptions,
                      MagickFalse,options);
                    if (orientation < 0)
                      break;
                    image->orientation=(OrientationType) orientation;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'p':
              case 'P':
              {
                if (LocaleCompare(keyword,"page") == 0)
                  {
                    char
                      *geometry;

                    geometry=GetPageGeometry(options);
                    (void) ParseAbsoluteGeometry(geometry,&image->page);
                    geometry=DestroyString(geometry);
                    break;
                  }
                if ((LocaleNCompare(keyword,"profile:",8) == 0) ||
                    (LocaleNCompare(keyword,"profile-",8) == 0))
                  {
                    if (profiles == (LinkedListInfo *) NULL)
                      profiles=NewLinkedList(0);
                    (void) AppendValueToLinkedList(profiles,
                      AcquireString(keyword+8));
                    profile=AcquireStringInfo((size_t) StringToLong(options));
                    (void) SetImageProfile(image,keyword+8,profile);
                    profile=DestroyStringInfo(profile);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'q':
              case 'Q':
              {
                if (LocaleCompare(keyword,"quality") == 0)
                  {
                    image->quality=StringToUnsignedLong(options);
                    break;
                  }
                if (LocaleCompare(keyword,"quantum-depth") == 0)
                  {
                    quantum_depth=StringToUnsignedLong(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'r':
              case 'R':
              {
                if (LocaleCompare(keyword,"red-primary") == 0)
                  {
                    flags=ParseGeometry(options,&geometry_info);
                    image->chromaticity.red_primary.x=geometry_info.rho;
                    if ((flags & SigmaValue) != 0)
                      image->chromaticity.red_primary.y=geometry_info.sigma;
                    break;
                  }
                if (LocaleCompare(keyword,"rendering-intent") == 0)
                  {
                    ssize_t
                      rendering_intent;

                    rendering_intent=ParseCommandOption(MagickIntentOptions,
                      MagickFalse,options);
                    if (rendering_intent < 0)
                      break;
                    image->rendering_intent=(RenderingIntent) rendering_intent;
                    break;
                  }
                if (LocaleCompare(keyword,"resolution") == 0)
                  {
                    flags=ParseGeometry(options,&geometry_info);
                    image->x_resolution=geometry_info.rho;
                    image->y_resolution=geometry_info.sigma;
                    if ((flags & SigmaValue) == 0)
                      image->y_resolution=image->x_resolution;
                    break;
                  }
                if (LocaleCompare(keyword,"rows") == 0)
                  {
                    image->rows=StringToUnsignedLong(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 's':
              case 'S':
              {
                if (LocaleCompare(keyword,"scene") == 0)
                  {
                    image->scene=StringToUnsignedLong(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 't':
              case 'T':
              {
                if (LocaleCompare(keyword,"ticks-per-second") == 0)
                  {
                    image->ticks_per_second=(ssize_t) StringToLong(options);
                    break;
                  }
                if (LocaleCompare(keyword,"tile-offset") == 0)
                  {
                    char
                      *geometry;

                    geometry=GetPageGeometry(options);
                    (void) ParseAbsoluteGeometry(geometry,&image->tile_offset);
                    geometry=DestroyString(geometry);
                  }
                if (LocaleCompare(keyword,"type") == 0)
                  {
                    ssize_t
                      type;

                    type=ParseCommandOption(MagickTypeOptions,MagickFalse,
                      options);
                    if (type < 0)
                      break;
                    image->type=(ImageType) type;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'u':
              case 'U':
              {
                if (LocaleCompare(keyword,"units") == 0)
                  {
                    ssize_t
                      units;

                    units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
                      options);
                    if (units < 0)
                      break;
                    image->units=(ResolutionType) units;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'w':
              case 'W':
              {
                if (LocaleCompare(keyword,"white-point") == 0)
                  {
                    flags=ParseGeometry(options,&geometry_info);
                    image->chromaticity.white_point.x=geometry_info.rho;
                    image->chromaticity.white_point.y=geometry_info.sigma;
                    if ((flags & SigmaValue) == 0)
                      image->chromaticity.white_point.y=
                        image->chromaticity.white_point.x;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              default:
              {
                (void) SetImageProperty(image,keyword,options);
                break;
              }
            }
          }
        else
          c=ReadBlobByte(image);
      while (isspace((int) ((unsigned char) c)) != 0)
        c=ReadBlobByte(image);
    }
    options=DestroyString(options);
    (void) ReadBlobByte(image);
    /*
      Verify that required image information is defined.
    */
    if ((LocaleCompare(id,"MagickCache") != 0) ||
        (image->storage_class == UndefinedClass) ||
        (image->compression == UndefinedCompression) || (image->columns == 0) ||
        (image->rows == 0))
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    if (quantum_depth != MAGICKCORE_QUANTUM_DEPTH)
      ThrowReaderException(CacheError,"InconsistentPersistentCacheDepth");
    if (image->montage != (char *) NULL)
      {
        register char
          *p;

        /*
          Image directory.
        */
        length=MaxTextExtent;
        image->directory=AcquireString((char *) NULL);
        p=image->directory;
        do
        {
          *p='\0';
          if ((strlen(image->directory)+MaxTextExtent) >= length)
            {
              /*
                Allocate more memory for the image directory.
              */
              length<<=1;
              image->directory=(char *) ResizeQuantumMemory(image->directory,
                length+MaxTextExtent,sizeof(*image->directory));
              if (image->directory == (char *) NULL)
                ThrowReaderException(CorruptImageError,"UnableToReadImageData");
              p=image->directory+strlen(image->directory);
            }
          c=ReadBlobByte(image);
          *p++=(char) c;
        } while (c != (int) '\0');
      }
    if (profiles != (LinkedListInfo *) NULL)
      {
        const char
          *name;

        const StringInfo
          *profile;

        register unsigned char
          *p;

        /*
          Read image profiles.
        */
        ResetLinkedListIterator(profiles);
        name=(const char *) GetNextValueInLinkedList(profiles);
        while (name != (const char *) NULL)
        {
          profile=GetImageProfile(image,name);
          if (profile != (StringInfo *) NULL)
            {
              p=GetStringInfoDatum(profile);
              count=ReadBlob(image,GetStringInfoLength(profile),p);
            }
          name=(const char *) GetNextValueInLinkedList(profiles);
        }
        profiles=DestroyLinkedList(profiles,RelinquishMagickMemory);
      }
    depth=GetImageQuantumDepth(image,MagickFalse);
    if (image->storage_class == PseudoClass)
      {
        /*
          Create image colormap.
        */
        if (AcquireImageColormap(image,image->colors) == MagickFalse)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        if (image->colors != 0)
          {
            size_t
              packet_size;

            unsigned char
              *colormap;

            /*
              Read image colormap from file.
            */
            packet_size=(size_t) (3UL*depth/8UL);
            colormap=(unsigned char *) AcquireQuantumMemory(image->colors,
              packet_size*sizeof(*colormap));
            if (colormap == (unsigned char *) NULL)
              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
            count=ReadBlob(image,packet_size*image->colors,colormap);
            if (count != (ssize_t) (packet_size*image->colors))
              ThrowReaderException(CorruptImageError,
                "InsufficientImageDataInFile");
            p=colormap;
            switch (depth)
            {
              default:
                ThrowReaderException(CorruptImageError,
                  "ImageDepthNotSupported");
              case 8:
              {
                unsigned char
                  pixel;

                for (i=0; i < (ssize_t) image->colors; i++)
                {
                  p=PushCharPixel(p,&pixel);
                  image->colormap[i].red=ScaleCharToQuantum(pixel);
                  p=PushCharPixel(p,&pixel);
                  image->colormap[i].green=ScaleCharToQuantum(pixel);
                  p=PushCharPixel(p,&pixel);
                  image->colormap[i].blue=ScaleCharToQuantum(pixel);
                }
                break;
              }
              case 16:
              {
                unsigned short
                  pixel;

                for (i=0; i < (ssize_t) image->colors; i++)
                {
                  p=PushShortPixel(MSBEndian,p,&pixel);
                  image->colormap[i].red=ScaleShortToQuantum(pixel);
                  p=PushShortPixel(MSBEndian,p,&pixel);
                  image->colormap[i].green=ScaleShortToQuantum(pixel);
                  p=PushShortPixel(MSBEndian,p,&pixel);
                  image->colormap[i].blue=ScaleShortToQuantum(pixel);
                }
                break;
              }
              case 32:
              {
                unsigned int
                  pixel;

                for (i=0; i < (ssize_t) image->colors; i++)
                {
                  p=PushLongPixel(MSBEndian,p,&pixel);
                  image->colormap[i].red=ScaleLongToQuantum(pixel);
                  p=PushLongPixel(MSBEndian,p,&pixel);
                  image->colormap[i].green=ScaleLongToQuantum(pixel);
                  p=PushLongPixel(MSBEndian,p,&pixel);
                  image->colormap[i].blue=ScaleLongToQuantum(pixel);
                }
                break;
              }
            }
            colormap=(unsigned char *) RelinquishMagickMemory(colormap);
          }
      }
    if (EOFBlob(image) != MagickFalse)
      {
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
          image->filename);
        break;
      }
    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    /*
      Attach persistent pixel cache.
    */
    status=PersistPixelCache(image,cache_filename,MagickTrue,&offset,exception);
    if (status == MagickFalse)
      ThrowReaderException(CacheError,"UnableToPersistPixelCache");
    /*
      Proceed to next image.
    */
    do
    {
      c=ReadBlobByte(image);
    } while ((isgraph(c) == MagickFalse) && (c != EOF));
    if (c != EOF)
      {
        /*
          Allocate next image structure.
        */
        AcquireNextImage(image_info,image);
        if (GetNextImageInList(image) == (Image *) NULL)
          {
            image=DestroyImageList(image);
            return((Image *) NULL);
          }
        image=SyncNextImageInList(image);
        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
          GetBlobSize(image));
        if (status == MagickFalse)
          break;
      }
  } while (c != EOF);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
Beispiel #6
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   G e t G e o m e t r y                                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GetGeometry() parses a geometry specification and returns the width,
%  height, x, and y values.  It also returns flags that indicates which
%  of the four values (width, height, x, y) were located in the string, and
%  whether the x or y values are negative.  In addition, there are flags to
%  report any meta characters (%, !, <, or >).
%
%  The format of the GetGeometry method is:
%
%      MagickStatusType GetGeometry(const char *geometry,ssize_t *x,ssize_t *y,
%        size_t *width,size_t *height)
%
%  A description of each parameter follows:
%
%    o geometry:  The geometry.
%
%    o x,y:  The x and y offset as determined by the geometry specification.
%
%    o width,height:  The width and height as determined by the geometry
%      specification.
%
*/
MagickExport MagickStatusType GetGeometry(const char *geometry,ssize_t *x,
        ssize_t *y,size_t *width,size_t *height)
{
    char
    *p,
    pedantic_geometry[MaxTextExtent],
    *q;

    double
    value;

    MagickStatusType
    flags;

    /*
      Remove whitespace and meta characters from geometry specification.
    */
    flags=NoValue;
    if ((geometry == (char *) NULL) || (*geometry == '\0'))
        return(flags);
    if (strlen(geometry) >= MaxTextExtent)
        return(flags);
    (void) CopyMagickString(pedantic_geometry,geometry,MaxTextExtent);
    for (p=pedantic_geometry; *p != '\0'; )
    {
        if (isspace((int) ((unsigned char) *p)) != 0)
        {
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            continue;
        }
        switch ((int) *p)
        {
        case '%':
        {
            flags|=PercentValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '!':
        {
            flags|=AspectValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '<':
        {
            flags|=LessValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '>':
        {
            flags|=GreaterValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '^':
        {
            flags|=MinimumValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '@':
        {
            flags|=AreaValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '(':
        case ')':
        {
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '-':
        case '.':
        case ',':
        case '+':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case -41:
        case 'x':
        case 'X':
        {
            p++;
            break;
        }
        default:
            return(flags);
        }
    }
    /*
      Parse width, height, x, and y.
    */
    p=pedantic_geometry;
    if (*p == '\0')
        return(flags);
    q=p;
    value=InterpretLocaleValue(p,&q);
    (void) value;
    if (LocaleNCompare(p,"0x",2) == 0)
        value=(double) strtol(p,&q,10);
    if ((((int) *q) == -41) || (*q == 'x') || (*q == 'X') || (*q == '\0'))
    {
        /*
          Parse width.
        */
        q=p;
        if (LocaleNCompare(p,"0x",2) == 0)
            *width=(size_t) strtol(p,&p,10);
        else
            *width=(size_t) floor(InterpretLocaleValue(p,&p)+0.5);
        if (p != q)
            flags|=WidthValue;
    }
    if ((((int) *p) == -41) || (*p == 'x') || (*p == 'X'))
    {
        p++;
        if ((*p != '+') && (*p != '-'))
        {
            /*
              Parse height.
            */
            q=p;
            *height=(size_t) floor(InterpretLocaleValue(p,&p)+0.5);
            if (p != q)
                flags|=HeightValue;
        }
    }
    if ((*p == '+') || (*p == '-'))
    {
        /*
          Parse x value.
        */
        if (*p == '-')
            flags|=XNegative;
        q=p;
        *x=(ssize_t) ceil(InterpretLocaleValue(p,&p)-0.5);
        if (p != q)
            flags|=XValue;
        if ((*p == '+') || (*p == '-'))
        {
            /*
              Parse y value.
            */
            if (*p == '-')
                flags|=YNegative;
            q=p;
            *y=(ssize_t) ceil(InterpretLocaleValue(p,&p)-0.5);
            if (p != q)
                flags|=YValue;
        }
    }
    return(flags);
}
Beispiel #7
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   P a r s e G e o m e t r y                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ParseGeometry() parses a geometry specification and returns the sigma,
%  rho, xi, and psi values.  It also returns flags that indicates which
%  of the four values (sigma, rho, xi, psi) were located in the string, and
%  whether the xi or pi values are negative.
%
%  In addition, it reports if there are any of meta characters (%, !, <, >, @,
%  and ^) flags present. It does not report the location of the percentage
%  relative to the values.
%
%  The format of the ParseGeometry method is:
%
%      MagickStatusType ParseGeometry(const char *geometry,
%        GeometryInfo *geometry_info)
%
%  A description of each parameter follows:
%
%    o geometry:  The geometry string (e.g. "100x100+10+10").
%
%    o geometry_info:  returns the parsed width/height/x/y in this structure.
%
*/
MagickExport MagickStatusType ParseGeometry(const char *geometry,
        GeometryInfo *geometry_info)
{
    char
    *p,
    pedantic_geometry[MaxTextExtent],
    *q;

    double
    value;

    MagickStatusType
    flags;

    /*
      Remove whitespaces meta characters from geometry specification.
    */
    assert(geometry_info != (GeometryInfo *) NULL);
    flags=NoValue;
    if ((geometry == (char *) NULL) || (*geometry == '\0'))
        return(flags);
    if (strlen(geometry) >= MaxTextExtent)
        return(flags);
    (void) CopyMagickString(pedantic_geometry,geometry,MaxTextExtent);
    for (p=pedantic_geometry; *p != '\0'; )
    {
        if (isspace((int) ((unsigned char) *p)) != 0)
        {
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            continue;
        }
        switch ((int) *p)
        {
        case '%':
        {
            flags|=PercentValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '!':
        {
            flags|=AspectValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '<':
        {
            flags|=LessValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '>':
        {
            flags|=GreaterValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '^':
        {
            flags|=MinimumValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '@':
        {
            flags|=AreaValue;
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '(':
        case ')':
        {
            (void) CopyMagickString(p,p+1,MaxTextExtent);
            break;
        }
        case '-':
        case '+':
        case ',':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case -41:
        case 'x':
        case 'X':
        case '/':
        case ':':
        {
            p++;
            break;
        }
        case '.':
        {
            p++;
            flags|=DecimalValue;
            break;
        }
        default:
            return(flags);
        }
    }
    /*
      Parse rho, sigma, xi, psi, and optionally chi.
    */
    p=pedantic_geometry;
    if (*p == '\0')
        return(flags);
    q=p;
    value=InterpretLocaleValue(p,&q);
    if (LocaleNCompare(p,"0x",2) == 0)
        value=(double) strtol(p,&q,10);
    if ((((int) *q) == -41) || (*q == 'x') || (*q == 'X') || (*q == ',') ||
            (*q == '/') || (*q == ':') || (*q =='\0'))
    {
        /*
          Parse rho.
        */
        q=p;
        if (LocaleNCompare(p,"0x",2) == 0)
            value=(double) strtol(p,&p,10);
        else
            value=InterpretLocaleValue(p,&p);
        if (p != q)
        {
            flags|=RhoValue;
            geometry_info->rho=value;
        }
    }
    q=p;
    if ((((int) *p) == -41) || (*p == 'x') || (*p == 'X') || (*p == ',') ||
            (*p == '/') || (*p == ':'))
    {
        /*
          Parse sigma.
        */
        p++;
        while (isspace((int) ((unsigned char) *p)) != 0)
            p++;
        if (((((int) *q) != -41) && (*q != 'x') && (*q != 'X')) ||
                ((*p != '+') && (*p != '-')))
        {
            q=p;
            value=InterpretLocaleValue(p,&p);
            if (p != q)
            {
                flags|=SigmaValue;
                geometry_info->sigma=value;
            }
        }
    }
    while (isspace((int) ((unsigned char) *p)) != 0)
        p++;
    if ((*p == '+') || (*p == '-') || (*p == ',') || (*p == '/') || (*p == ':'))
    {
        /*
          Parse xi value.
        */
        if ((*p == ',') || (*p == '/') || (*p == ':'))
            p++;
        q=p;
        value=InterpretLocaleValue(p,&p);
        if (p != q)
        {
            flags|=XiValue;
            if (*q == '-')
                flags|=XiNegative;
            geometry_info->xi=value;
        }
        while (isspace((int) ((unsigned char) *p)) != 0)
            p++;
        if ((*p == '+') || (*p == '-') || (*p == ',') || (*p == '/') ||
                (*p == ':'))
        {
            /*
              Parse psi value.
            */
            if ((*p == ',') || (*p == '/') || (*p == ':'))
                p++;
            q=p;
            value=InterpretLocaleValue(p,&p);
            if (p != q)
            {
                flags|=PsiValue;
                if (*q == '-')
                    flags|=PsiNegative;
                geometry_info->psi=value;
            }
        }
        while (isspace((int) ((unsigned char) *p)) != 0)
            p++;
        if ((*p == '+') || (*p == '-') || (*p == ',') || (*p == '/') ||
                (*p == ':'))
        {
            /*
              Parse chi value.
            */
            if ((*p == ',') || (*p == '/') || (*p == ':'))
                p++;
            q=p;
            value=InterpretLocaleValue(p,&p);
            if (p != q)
            {
                flags|=ChiValue;
                if (*q == '-')
                    flags|=ChiNegative;
                geometry_info->chi=value;
            }
        }
    }
    if (strchr(pedantic_geometry,':') != (char *) NULL)
    {
        /*
          Normalize sampling factor (e.g. 4:2:2 => 2x1).
        */
        geometry_info->rho/=geometry_info->sigma;
        geometry_info->sigma=1.0;
        if (geometry_info->xi == 0.0)
            geometry_info->sigma=2.0;
    }
    if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0) &&
            ((flags & PsiValue) == 0))
    {
        /*
          Support negative height values (e.g. 30x-20).
        */
        geometry_info->sigma=geometry_info->xi;
        geometry_info->xi=0.0;
        flags|=SigmaValue;
        flags&=(~XiValue);
    }
    return(flags);
}
Beispiel #8
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   P a r s e A f f i n e G e o m e t r y                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ParseAffineGeometry() returns an affine matrix as defined by a string of 4
%  to 6 comma/space separated floating point values.
%
%  The affine matrix determinant is checked for validity of the values.
%
%  The format of the ParseAffineGeometry method is:
%
%      MagickStatusType ParseAffineGeometry(const char *geometry,
%        AffineMatrix *affine_matrix,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o geometry:  The geometry string (e.g. "1.0,0.0,0.0,1.0,3.2,1.2").
%
%    o affine_matrix: the affine matrix as defined by the geometry string.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickStatusType ParseAffineGeometry(const char *geometry,
        AffineMatrix *affine_matrix,ExceptionInfo *exception)
{
    char
    token[MaxTextExtent];

    const char
    *p;

    double
    determinant;

    MagickStatusType
    flags;

    register ssize_t
    i;

    GetAffineMatrix(affine_matrix);
    flags=NoValue;
    p=(char *) geometry;
    for (i=0; (*p != '\0') && (i < 6); i++)
    {
        GetMagickToken(p,&p,token);
        if (*token == ',')
            GetMagickToken(p,&p,token);
        switch (i)
        {
        case 0:
        {
            affine_matrix->sx=InterpretLocaleValue(token,(char **) NULL);
            break;
        }
        case 1:
        {
            affine_matrix->rx=InterpretLocaleValue(token,(char **) NULL);
            break;
        }
        case 2:
        {
            affine_matrix->ry=InterpretLocaleValue(token,(char **) NULL);
            break;
        }
        case 3:
        {
            affine_matrix->sy=InterpretLocaleValue(token,(char **) NULL);
            break;
        }
        case 4:
        {
            affine_matrix->tx=InterpretLocaleValue(token,(char **) NULL);
            flags|=XValue;
            break;
        }
        case 5:
        {
            affine_matrix->ty=InterpretLocaleValue(token,(char **) NULL);
            flags|=YValue;
            break;
        }
        }
    }
    determinant=(affine_matrix->sx*affine_matrix->sy-affine_matrix->rx*
                 affine_matrix->ry);
    if (fabs(determinant) < MagickEpsilon)
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
                                    "InvalidGeometry","`%s'",geometry);
    return(flags);
}
Beispiel #9
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d S C T I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadSCTImage() reads a Scitex image file and returns it.  It allocates
%  the memory necessary for the new Image structure and returns a pointer to
%  the new image.
%
%  The format of the ReadSCTImage method is:
%
%      Image *ReadSCTImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadSCTImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    magick[2];

  Image
    *image;

  MagickBooleanType
    status;

  MagickRealType
    height,
    width;

  Quantum
    pixel;

  register IndexPacket
    *indexes;

  register ssize_t
    i,
    x;

  register PixelPacket
    *q;

  ssize_t
    count,
    y;

  unsigned char
    buffer[768];

  size_t
    separations,
    separations_mask,
    units;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
    Read control block.
  */
  count=ReadBlob(image,80,buffer);
  (void) count;
  count=ReadBlob(image,2,(unsigned char *) magick);
  if ((LocaleNCompare((char *) magick,"CT",2) != 0) &&
      (LocaleNCompare((char *) magick,"LW",2) != 0) &&
      (LocaleNCompare((char *) magick,"BM",2) != 0) &&
      (LocaleNCompare((char *) magick,"PG",2) != 0) &&
      (LocaleNCompare((char *) magick,"TX",2) != 0))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  if ((LocaleNCompare((char *) magick,"LW",2) == 0) ||
      (LocaleNCompare((char *) magick,"BM",2) == 0) ||
      (LocaleNCompare((char *) magick,"PG",2) == 0) ||
      (LocaleNCompare((char *) magick,"TX",2) == 0))
    ThrowReaderException(CoderError,"OnlyContinuousTonePictureSupported");
  count=ReadBlob(image,174,buffer);
  count=ReadBlob(image,768,buffer);
  /*
    Read paramter block.
  */
  units=1UL*ReadBlobByte(image);
  if (units == 0)
    image->units=PixelsPerCentimeterResolution;
  separations=1UL*ReadBlobByte(image);
  separations_mask=ReadBlobMSBShort(image);
  count=ReadBlob(image,14,buffer);
  buffer[14]='\0';
  height=InterpretLocaleValue((char *) buffer,(char **) NULL);
  count=ReadBlob(image,14,buffer);
  width=InterpretLocaleValue((char *) buffer,(char **) NULL);
  count=ReadBlob(image,12,buffer);
  buffer[12]='\0';
  image->rows=StringToUnsignedLong((char *) buffer);
  count=ReadBlob(image,12,buffer);
  image->columns=StringToUnsignedLong((char *) buffer);
  count=ReadBlob(image,200,buffer);
  count=ReadBlob(image,768,buffer);
  if (separations_mask == 0x0f)
    image->colorspace=CMYKColorspace;
  image->x_resolution=1.0*image->columns/width;
  image->y_resolution=1.0*image->rows/height;
  if (image_info->ping != MagickFalse)
    {
      (void) CloseBlob(image);
      return(GetFirstImageInList(image));
    }
  /*
    Convert SCT raster image to pixel packets.
  */
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    for (i=0; i < (ssize_t) separations; i++)
    {
      q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
      if (q == (PixelPacket *) NULL)
        break;
      indexes=GetAuthenticIndexQueue(image);
      for (x=0; x < (ssize_t) image->columns; x++)
      {
        pixel=(Quantum) ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
        if (image->colorspace == CMYKColorspace)
          pixel=(Quantum) (QuantumRange-pixel);
        switch (i)
        {
          case 0:
          {
            SetPixelRed(q,pixel);
            SetPixelGreen(q,pixel);
            SetPixelBlue(q,pixel);
            break;
          }
          case 1:
          {
            SetPixelGreen(q,pixel);
            break;
          }
          case 2:
          {
            SetPixelBlue(q,pixel);
            break;
          }
          case 3: 
          {
            if (image->colorspace == CMYKColorspace)
              SetPixelBlack(indexes+x,pixel);
            break;
          }
        }
        q++;
      }
      if (SyncAuthenticPixels(image,exception) == MagickFalse)
        break;
      if ((image->columns % 2) != 0)
        (void) ReadBlobByte(image);  /* pad */
    }
    status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
      image->rows);
    if (status == MagickFalse)
      break;
  }
  if (EOFBlob(image) != MagickFalse)
    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
      image->filename);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}