示例#1
0
文件: rmilist.c 项目: r-project/BS
/*
    Method:     ImageList#append(stack)
    Purpose:    Append all the images by calling ImageAppend
    Returns:    an Frame object for the result
*/
VALUE
ImageList_append(VALUE self, VALUE stack_arg)
{
    Image *images, *new_image;
    unsigned int stack;
    ExceptionInfo exception;

    // Convert the image array to an image sequence.
    images = images_from_imagelist(self);

    // If stack == true, stack rectangular images top-to-bottom,
    // otherwise left-to-right.
    stack = RTEST(stack_arg);

    GetExceptionInfo(&exception);
    new_image = AppendImages(images, stack, &exception);
    rm_split(images);
    rm_check_exception(&exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(&exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   M a g i c k Q u e r y C o n f i g u r e O p t i o n                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  MagickQueryConfigureOption() returns the value associated with the specified
%  configure option.
%
%  The format of the MagickQueryConfigureOption function is:
%
%      char *MagickQueryConfigureOption(const char *option)
%
%  A description of each parameter follows:
%
%    o option: The option name.
%
*/
WandExport char *MagickQueryConfigureOption(const char *option)
{
  char
    *value;

  const ConfigureInfo
    **configure_info;

  ExceptionInfo
    exception;

  unsigned long
    number_options;

  GetExceptionInfo(&exception);
  configure_info=GetConfigureInfoList(option,&number_options,&exception);
  DestroyExceptionInfo(&exception);
  if (configure_info == (const ConfigureInfo **) NULL)
    return((char *) NULL);
  value=AcquireString(configure_info[0]->value);
  configure_info=(const ConfigureInfo **)
    RelinquishMagickMemory((void *) configure_info);
  return(value);
}
ngx_int_t
convert_image(ngx_http_request_t *r, convert_options_t *option_info,
    Image **image)
{
    ngx_uint_t                          i;

    ngx_http_gm_convert_option_t      *options;
    ngx_http_gm_convert_option_t      *option;

    RectangleInfo                      geometry;
    RectangleInfo                      geometry_info;
    ExceptionInfo                      exception;

    Image                             *resize_image = NULL;
    u_char                            *resize_geometry = NULL;
    u_char                            *need_crop_resize = NULL;

    Image                             *rotate_image = NULL;
    u_char                            *rotate_degrees = NULL;
    ngx_int_t                          degrees;
    ngx_int_t                          degrees_suffix_len = 0;

    dd("entering");

    options = option_info->options->elts;

    for (i = 0; i < option_info->options->nelts; ++i) {
        option = &options[i];

        if (option->type == NGX_HTTP_GM_RESIZE_OPTION) {
            dd("starting resize");

            resize_geometry = ngx_http_gm_get_str_value(r,
                    option->resize_geometry_cv, &option->resize_geometry);

            need_crop_resize = (u_char *)ngx_strchr(resize_geometry, 'c');
            if (need_crop_resize != NULL) {
                *need_crop_resize = '^';
            }

            if (resize_geometry == NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                        "gm filter: resize image, get resize geometry failed");
                return  NGX_ERROR;
            }

            if (ngx_strncmp(resize_geometry, "no", 2) == 0) {
                continue;
            }


            (void) GetImageGeometry(*image, (char *)resize_geometry, 1,
                                    &geometry);

            if ((geometry.width == (*image)->columns) &&
                (geometry.height == (*image)->rows))
                continue;

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "resize image geometry: \"%s\"", resize_geometry);

            GetExceptionInfo(&exception);
            resize_image = ResizeImage(*image, geometry.width, geometry.height,
                (*image)->filter,(*image)->blur, &exception);

            if (resize_image == (Image *) NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                              "gm filter: resize image failed, "
                              "arg: \"%s\" severity: \"%O\" "
                              "reason: \"%s\", description: \"%s\"",
                              resize_geometry, exception.severity,
                              exception.reason, exception.description);

                DestroyExceptionInfo(&exception);

                return NGX_ERROR;
            }

            DestroyImage(*image);
            *image = resize_image;
            DestroyExceptionInfo(&exception);

            if (need_crop_resize != NULL) {
                GetGeometry((char *)resize_geometry,
                            &geometry_info.x, &geometry_info.y,
                            (unsigned long *)(&geometry_info.width),
                            (unsigned long *)(&geometry_info.height));

                if (geometry_info.width > (*image)->columns ||
                        geometry_info.height > (*image)->rows) {
                    continue;
                }

                geometry_info.x = ((*image)->columns - geometry_info.width) / 2;
                geometry_info.y = ((*image)->rows - geometry_info.height) / 2;

                GetExceptionInfo(&exception);
                resize_image = CropImage(*image, &geometry_info, &exception);


                if (resize_image == (Image *) NULL) {
                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                                "gm filter: resize croping image failed, "
                                "arg: \"%s\" severity: \"%O\" "
                                "reason: \"%s\", description: \"%s\"",
                                resize_geometry, exception.severity,
                                exception.reason, exception.description);

                    DestroyExceptionInfo(&exception);

                    return NGX_ERROR;
                }

                DestroyImage(*image);
                *image = resize_image;
                DestroyExceptionInfo(&exception);
            }

        } else if (option->type == NGX_HTTP_GM_ROTATE_OPTION) {
            dd("starting rotate");

            rotate_degrees = ngx_http_gm_get_str_value(r,
                    option->rotate_degrees_cv, &option->rotate_degrees);

            if (rotate_degrees == NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                        "gm filter: rotate image, get rotate degrees failed");
                return  NGX_ERROR;
            }

            if (ngx_strchr(rotate_degrees,'>') != (char *) NULL) {
                if ((*image)->columns <= (*image)->rows)
                    continue;
                degrees_suffix_len = 1;
            }

            if (ngx_strchr(rotate_degrees,'<') != (char *) NULL) {
                if ((*image)->columns >= (*image)->rows)
                    continue;
                degrees_suffix_len = 1;
            }

            degrees = 0;
            degrees = ngx_atoi(rotate_degrees,
                               ngx_strlen(rotate_degrees) - degrees_suffix_len);

            if (degrees == 0) {
                continue;
            }

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "rotate image degrees: \"%O\"", degrees);

            GetExceptionInfo(&exception);


            rotate_image=RotateImage(*image, degrees, &exception);
            if (rotate_image == (Image *) NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                              "gm filter: rotate image failed, "
                              "degrees: \"%s\" severity: \"%O\" "
                              "reason: \"%s\", description: \"%s\"",
                              option->rotate_degrees, exception.severity,
                              exception.reason, exception.description);

                DestroyExceptionInfo(&exception);

                return NGX_ERROR;
            }

            DestroyImage(*image);
            *image = rotate_image;

            DestroyExceptionInfo(&exception);

        } else {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                              "gm filter: convert command, unkonwn option");
            return NGX_ERROR;
        }
    }

    return NGX_OK;
}
示例#4
0
CAMLprim value
magick_loader(value input)
{
    CAMLparam1(input);
    CAMLlocal2(pixel_matrix, res);
    Image *image_bloc;
    int image_type_code;
    int components;
    GLenum format;
    ExceptionInfo exception;
    GetExceptionInfo(&exception);
    {
        if (IsMagickInstantiated() == MagickFalse) {
            InitializeMagick(getenv("PWD"));
        }

        {
            ImageInfo *image_info;
            image_info = CloneImageInfo((ImageInfo *) NULL);
            switch (Tag_val(input))
            {
                /* given a filename of an image */
                case 0:
                    (void) strcpy(image_info->filename, String_val(Field(input,0)));
                    image_bloc = ReadImage(image_info, &exception);
                    break;

                /* given the image data in a buffer */
                case 1:
                    image_bloc = BlobToImage(
                        image_info,
                        (void *)String_val(Field(input,0)),
                        caml_string_length(Field(input,0)),
                        &exception);
                    break;
            }
            DestroyImageInfo(image_info);
        }

        if (exception.severity != UndefinedException) {
            if (image_bloc != (Image *) NULL) {
                DestroyImage(image_bloc);
            }
            DestroyExceptionInfo(&exception);
            caml_failwith( exception.reason );
            /* @TODO  exception.description */
        }

        if (image_bloc == (Image *) NULL) {
            DestroyExceptionInfo(&exception);
            caml_failwith("read image failed");
        }
    }
    {
        ImageType image_type;
        image_type = GetImageType( image_bloc, &exception );

        if (exception.severity != UndefinedException)
            caml_failwith( exception.reason );

        image_type_code = Val_ImageType(image_type, &components);

        if ( image_type_code == 11 )
            caml_failwith("getting image type failed");
    }
    {
        unsigned long x, y;
        unsigned long columns, rows;

        PixelPacket pixel;

        columns = image_bloc->columns;
        rows    = image_bloc->rows;

        const PixelPacket * pixel_packet_array;

        pixel_packet_array =
                AcquireImagePixels(
                         image_bloc,
                         0, 0, columns, rows,
                         &exception );

        if (exception.severity != UndefinedException) {
            caml_failwith(exception.reason);
        }

        {
            unsigned char *image;
            long ndx;
            long dims[3];
            dims[0] = columns;
            dims[1] = rows;
            dims[2] = components;
            pixel_matrix = alloc_bigarray(BIGARRAY_UINT8 | BIGARRAY_C_LAYOUT, 3, NULL, dims);
            image = Data_bigarray_val(pixel_matrix);
            for (x=0; x < columns; ++x) {
                for (y=0; y < rows; ++y) {
                    pixel = pixel_packet_array[(columns * y) + x];

                    ndx = (columns * y * components) + (x * components);
                    switch (components) {
                        case 1:
                            image[ndx + 0] = pixel.red   / SCALE;
                            break;
                        case 2:
                            image[ndx + 0] = pixel.red   / SCALE;
                            image[ndx + 1] = ( MaxMap - pixel.opacity ) / SCALE;
                            break;
                        case 3:
                            image[ndx + 0] = pixel.red   / SCALE;
                            image[ndx + 1] = pixel.green / SCALE;
                            image[ndx + 2] = pixel.blue  / SCALE;
                            break;
                        case 4:
                            image[ndx + 0] = pixel.red   / SCALE;
                            image[ndx + 1] = pixel.green / SCALE;
                            image[ndx + 2] = pixel.blue  / SCALE;
                            image[ndx + 3] = ( MaxMap - pixel.opacity ) / SCALE;
                            break;
                    }
                }
            }
        }

        switch (components) {
            case 1: format = GL_LUMINANCE; break;
            case 2: format = GL_LUMINANCE_ALPHA; break;
            case 3: format = GL_RGB; break;
            case 4: format = GL_RGBA; break;
        }

        res = alloc_tuple(5);
        Store_field(res, 0, pixel_matrix );
        Store_field(res, 1, Val_long(columns) );
        Store_field(res, 2, Val_long(rows) );
        Store_field(res, 3, Val_internal_format(components) );
        Store_field(res, 4, Val_pixel_data_format(format) );
    }
    DestroyExceptionInfo(&exception);
    DestroyImage(image_bloc);
    CAMLreturn(res);
}
示例#5
0
int main(int argc, char **argv)
{
  char
    *xml;

  const char
    *acronym,
    *data_type,
    *description,
    *endian,
    *mask,
    *mime_type,
    *offset,
    *pattern,
    *priority,
    *match_type,
    *value;

  ExceptionInfo
    *exception;

  size_t
    length;
 
  static char
    *doc_type =
    {
      "<!DOCTYPE mimemap [\n"
      "  <!ELEMENT mimemap (mime+)>\n"
      "  <!ELEMENT mime (#PCDATA)>\n"
      "  <!ATTLIST mime type CDATA #REQUIRED>\n"
      "  <!ATTLIST mime acronym CDATA #IMPLIED>\n"
      "  <!ATTLIST mime description CDATA #IMPLIED>\n"
      "  <!ATTLIST mime pattern CDATA #IMPLIED>\n"
      "  <!ATTLIST mime offset CDATA #IMPLIED>\n"
      "  <!ATTLIST mime data-type (string|byte|short|ssize_t) #IMPLIED>\n"
      "  <!ATTLIST mime endian (lsb|msb) #IMPLIED>\n"
      "  <!ATTLIST mime magic CDATA #IMPLIED>\n"
      "  <!ATTLIST mime mask CDATA #IMPLIED>\n"
      "  <!ATTLIST mime priority CDATA #IMPLIED>\n"
      "]>"
    };

  XMLTreeInfo
    *comment,
    *expanded_acronym,
    *glob,
    *magic,
    *match,
    *type,
    *xml_info;

  if (argc != 2)
    return(fprintf(stderr,"usage: %s xml-file\n", argv[0]));
  exception=AcquireExceptionInfo();
  xml=(char *) FileToBlob(argv[1],~0UL,&length,exception);
  if (xml == (char *) NULL)
    return(fprintf(stderr,"%s: unable to read file\n",argv[1]));
  xml_info=NewXMLTree(xml,exception);
  xml=(char *) RelinquishWizardMemory(xml);
  if (xml_info == (XMLTreeInfo *) NULL)
    return(fprintf(stderr,"%s: unable to parse xml-file\n",argv[1]));
  (void) printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
  (void) printf("%s\n",doc_type);
  (void) printf("<mimemap>\n");
  type=GetXMLTreeChild(xml_info,"mime-type");
	while (type != (XMLTreeInfo *) NULL)
  {
    mime_type=GetXMLTreeAttribute(type,"type");
    acronym=(const char *) NULL;
    expanded_acronym=GetXMLTreeChild(type,"acronym");
    if (expanded_acronym != (XMLTreeInfo *) NULL)
      acronym=GetXMLTreeContent(expanded_acronym);
    expanded_acronym=GetXMLTreeChild(type,"expanded-acronym");
    description=(const char *) NULL;
    comment=GetXMLTreeChild(type,"comment");
    if (comment != (XMLTreeInfo *) NULL)
      description=GetXMLTreeContent(comment);
    if (expanded_acronym != (XMLTreeInfo *) NULL)
      description=GetXMLTreeContent(expanded_acronym);
    magic=GetXMLTreeChild(type,"magic");
    priority=(char *) NULL;
    match=(XMLTreeInfo *) NULL;
    if (magic != (XMLTreeInfo *) NULL)
      {
        priority=GetXMLTreeAttribute(magic,"priority");
        match=GetXMLTreeChild(magic,"match");
      }
  	while (match != (XMLTreeInfo *) NULL)
    {
      value=(char *) NULL;
      match_type=(char *) NULL;
      mask=(char *) NULL;
      offset=(char *) NULL;
      if (match != (XMLTreeInfo *) NULL)
        {
          value=GetXMLTreeAttribute(match,"value");
          match_type=GetXMLTreeAttribute(match,"type");
          offset=GetXMLTreeAttribute(match,"offset");
          mask=GetXMLTreeAttribute(match,"mask");
        }
      (void) printf("  <mime");
      if (mime_type != (const char *) NULL)
        (void) printf(" type=\"%s\"",mime_type);
      if (description != (const char *) NULL)
        (void) printf(" description=\"%s\"",description);
      if (match_type != (const char *) NULL)
        {
          data_type="string";
          endian="undefined";
          if (strncmp(match_type,"little",6) == 0)
            endian="LSB";
          if (strncmp(match_type,"big",3) == 0)
            endian="MSB";
          if (strcmp(match_type,"byte") == 0)
            data_type="byte";
          if (strcmp(match_type+strlen(match_type)-2,"16") == 0)
            data_type="short";
          if (strcmp(match_type+strlen(match_type)-2,"32") == 0)
            data_type="ssize_t";
          (void) printf(" data-type=\"%s\"",data_type);
          if (strcmp(endian,"undefined") != 0)
            (void) printf(" endian=\"%s\"",endian);
        }
      if (offset != (const char *) NULL)
        (void) printf(" offset=\"%s\"",offset);
      if (mask != (const char *) NULL)
        (void) printf(" mask=\"%s\"",mask);
      if (value != (const char *) NULL)
        {
          char
            *magic;

          magic=AcquireString(value);
          SubstituteString(&magic,"<","&lt;");
          SubstituteString(&magic,">","&gt;");
          SubstituteString(&magic,"\"","&quot;");
          (void) printf(" magic=\"%s\"",magic);
          magic=(char *) RelinquishWizardMemory(magic);
        }
      if (priority != (const char *) NULL)
        (void) printf(" priority=\"%s\"",priority);
      (void) printf(" />\n");
		  match=GetNextXMLTreeTag(match);
    }
    glob=GetXMLTreeChild(type,"glob");
    while (glob != (XMLTreeInfo *) NULL)
    {
      pattern=GetXMLTreeAttribute(glob,"pattern");
      value=(char *) NULL;
      if (match)
        value=GetXMLTreeAttribute(match,"value");
      (void) printf("  <mime");
      if (mime_type != (const char *) NULL)
        (void) printf(" type=\"%s\"",mime_type);
      if (acronym != (const char *) NULL)
        (void) printf(" acronym=\"%s\"",acronym);
      if (description != (const char *) NULL)
        (void) printf(" description=\"%s\"",description);
      (void) printf(" priority=\"100\"");
      if (pattern != (const char *) NULL)
        (void) printf(" pattern=\"%s\"",pattern);
      (void) printf(" />\n");
      glob=GetNextXMLTreeTag(glob);
    }
    type=GetNextXMLTreeTag(type);
  }
  (void) printf("</mimemap>\n");
  xml=XMLTreeInfoToXML(xml_info);
  (void) fprintf(stderr,"%s\n",xml);
  xml=(char *) RelinquishWizardMemory(xml);
  DestroyXMLTree(xml_info);
  exception=DestroyExceptionInfo(exception);
  return(0);
}
示例#6
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e I m a g e                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteImage() writes an image or an image sequence to a file or file handle.
%  If writing to a file is on disk, the name is defined by the filename member
%  of the image structure.  WriteImage() returns MagickFalse is there is a
%  memory shortage or if the image cannot be written.  Check the exception
%  member of image to determine the cause for any failure.
%
%  The format of the WriteImage method is:
%
%      MagickBooleanType WriteImage(const ImageInfo *image_info,Image *image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType WriteImage(const ImageInfo *image_info,
  Image *image,ExceptionInfo *exception)
{
  char
    filename[MaxTextExtent];

  const char
    *option;

  const DelegateInfo
    *delegate_info;

  const MagickInfo
    *magick_info;

  ExceptionInfo
    *sans_exception;

  ImageInfo
    *write_info;

  MagickBooleanType
    status,
    temporary;

  MagickStatusType
    thread_support;

  PolicyDomain
    domain;

  PolicyRights
    rights;

  /*
    Determine image type from filename prefix or suffix (e.g. image.jpg).
  */
  assert(image_info != (ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  assert(exception != (ExceptionInfo *) NULL);
  sans_exception=AcquireExceptionInfo();
  write_info=CloneImageInfo(image_info);
  (void) CopyMagickString(write_info->filename,image->filename,MaxTextExtent);
  if (*write_info->magick == '\0')
    (void) CopyMagickString(write_info->magick,image->magick,MaxTextExtent);
  (void) SetImageInfo(write_info,1,sans_exception);
  if (LocaleCompare(write_info->magick,"clipmask") == 0)
    {
      if (image->clip_mask == (Image *) NULL)
        {
          (void) ThrowMagickException(exception,GetMagickModule(),
            OptionError,"NoClipPathDefined","`%s'",image->filename);
          return(MagickFalse);
        }
      image=image->clip_mask;
      (void) SetImageInfo(write_info,1,sans_exception);
    }
  (void) CopyMagickString(filename,image->filename,MaxTextExtent);
  (void) CopyMagickString(image->filename,write_info->filename,MaxTextExtent);
  domain=CoderPolicyDomain;
  rights=WritePolicyRights;
  if (IsRightsAuthorized(domain,rights,write_info->magick) == MagickFalse)
    {
      sans_exception=DestroyExceptionInfo(sans_exception);
      errno=EPERM;
      ThrowBinaryException(PolicyError,"NotAuthorized",filename);
    }
  magick_info=GetMagickInfo(write_info->magick,sans_exception);
  sans_exception=DestroyExceptionInfo(sans_exception);
  if (magick_info != (const MagickInfo *) NULL)
    {
      if (GetMagickEndianSupport(magick_info) == MagickFalse)
        image->endian=UndefinedEndian;
      else
        if ((image_info->endian == UndefinedEndian) &&
            (GetMagickRawSupport(magick_info) != MagickFalse))
          {
            size_t
              lsb_first;

            lsb_first=1;
            image->endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
         }
    }
  (void) SyncImageProfiles(image);
  option=GetImageOption(image_info,"delegate:bimodal");
  if ((option != (const char *) NULL) &&
      (IsMagickTrue(option) != MagickFalse) &&
      (write_info->page == (char *) NULL) &&
      (GetPreviousImageInList(image) == (Image *) NULL) &&
      (GetNextImageInList(image) == (Image *) NULL) &&
      (IsTaintImage(image) == MagickFalse))
    {
      delegate_info=GetDelegateInfo(image->magick,write_info->magick,exception);
      if ((delegate_info != (const DelegateInfo *) NULL) &&
          (GetDelegateMode(delegate_info) == 0) &&
          (IsPathAccessible(image->magick_filename) != MagickFalse))
        {
          /*
            Process image with bi-modal delegate.
          */
          (void) CopyMagickString(image->filename,image->magick_filename,
            MaxTextExtent);
          status=InvokeDelegate(write_info,image,image->magick,
            write_info->magick,exception);
          write_info=DestroyImageInfo(write_info);
          (void) CopyMagickString(image->filename,filename,MaxTextExtent);
          return(status);
        }
    }
  status=MagickFalse;
  temporary=MagickFalse;
  if ((magick_info != (const MagickInfo *) NULL) &&
      (GetMagickSeekableStream(magick_info) != MagickFalse))
    {
      char
        filename[MaxTextExtent];

      (void) CopyMagickString(filename,image->filename,MaxTextExtent);
      status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
      (void) CopyMagickString(image->filename,filename,MaxTextExtent);
      if (status != MagickFalse)
        {
          if (IsBlobSeekable(image) == MagickFalse)
            {
              /*
                A seekable stream is required by the encoder.
              */
              write_info->adjoin=MagickTrue;
              (void) CopyMagickString(write_info->filename,image->filename,
                MaxTextExtent);
              (void) AcquireUniqueFilename(image->filename);
              temporary=MagickTrue;
            }
          (void) CloseBlob(image);
        }
    }
  if (constitute_semaphore == (SemaphoreInfo *) NULL)
    AcquireSemaphoreInfo(&constitute_semaphore);
  if ((magick_info != (const MagickInfo *) NULL) &&
      (GetImageEncoder(magick_info) != (EncodeImageHandler *) NULL))
    {
      /*
        Call appropriate image writer based on image type.
      */
      thread_support=GetMagickThreadSupport(magick_info);
      if ((thread_support & EncoderThreadSupport) == 0)
        LockSemaphoreInfo(constitute_semaphore);
      status=GetImageEncoder(magick_info)(write_info,image,exception);
      if ((thread_support & EncoderThreadSupport) == 0)
        UnlockSemaphoreInfo(constitute_semaphore);
    }
  else
    {
      delegate_info=GetDelegateInfo((char *) NULL,write_info->magick,exception);
      if (delegate_info != (DelegateInfo *) NULL)
        {
          /*
            Process the image with delegate.
          */
          *write_info->filename='\0';
          if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
            LockSemaphoreInfo(constitute_semaphore);
          status=InvokeDelegate(write_info,image,(char *) NULL,
            write_info->magick,exception);
          if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
            UnlockSemaphoreInfo(constitute_semaphore);
          (void) CopyMagickString(image->filename,filename,MaxTextExtent);
        }
      else
        {
          sans_exception=AcquireExceptionInfo();
          magick_info=GetMagickInfo(write_info->magick,sans_exception);
          sans_exception=DestroyExceptionInfo(sans_exception);
          if ((write_info->affirm == MagickFalse) &&
              (magick_info == (const MagickInfo *) NULL))
            {
              (void) CopyMagickString(write_info->magick,image->magick,
                MaxTextExtent);
              magick_info=GetMagickInfo(write_info->magick,exception);
            }
          if ((magick_info == (const MagickInfo *) NULL) ||
              (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL))
            {
              char
                extension[MaxTextExtent];

              GetPathComponent(image->filename,ExtensionPath,extension);
              if (*extension != '\0')
                magick_info=GetMagickInfo(extension,exception);
              else
                magick_info=GetMagickInfo(image->magick,exception);
              (void) CopyMagickString(image->filename,filename,MaxTextExtent);
            }
          if ((magick_info == (const MagickInfo *) NULL) ||
              (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL))
            (void) ThrowMagickException(exception,GetMagickModule(),
              MissingDelegateError,"NoEncodeDelegateForThisImageFormat","`%s'",
              image->filename);
          else
            {
              /*
                Call appropriate image writer based on image type.
              */
              thread_support=GetMagickThreadSupport(magick_info);
              if ((thread_support & EncoderThreadSupport) == 0)
                LockSemaphoreInfo(constitute_semaphore);
              status=GetImageEncoder(magick_info)(write_info,image,exception);
              if ((thread_support & EncoderThreadSupport) == 0)
                UnlockSemaphoreInfo(constitute_semaphore);
            }
        }
    }
  if (GetBlobError(image) != MagickFalse)
    ThrowFileException(exception,FileOpenError,
      "AnErrorHasOccurredWritingToFile",image->filename);
  if (temporary == MagickTrue)
    {
      /*
        Copy temporary image file to permanent.
      */
      status=OpenBlob(write_info,image,ReadBinaryBlobMode,exception);
      if (status != MagickFalse)
        status=ImageToFile(image,write_info->filename,exception);
      (void) CloseBlob(image);
      (void) RelinquishUniqueFileResource(image->filename);
      (void) CopyMagickString(image->filename,write_info->filename,
        MaxTextExtent);
    }
  if ((LocaleCompare(write_info->magick,"info") != 0) &&
      (write_info->verbose != MagickFalse))
    (void) IdentifyImage(image,stdout,MagickFalse,exception);
  write_info=DestroyImageInfo(write_info);
  return(status);
}
示例#7
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d I m a g e                                                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadImage() reads an image or image sequence from a file or file handle.
%  The method returns a NULL if there is a memory shortage or if the image
%  cannot be read.  On failure, a NULL image is returned and exception
%  describes the reason for the failure.
%
%  The format of the ReadImage method is:
%
%      Image *ReadImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: Read the image defined by the file or filename members of
%      this structure.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport Image *ReadImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  char
    filename[MaxTextExtent],
    magick[MaxTextExtent],
    magick_filename[MaxTextExtent];

  const char
    *value;

  const DelegateInfo
    *delegate_info;

  const MagickInfo
    *magick_info;

  ExceptionInfo
    *sans_exception;

  GeometryInfo
    geometry_info;

  Image
    *image,
    *next;

  ImageInfo
    *read_info;

  MagickStatusType
    flags,
    thread_support;

  PolicyDomain
    domain;

  PolicyRights
    rights;

  /*
    Determine image type from filename prefix or suffix (e.g. image.jpg).
  */
  assert(image_info != (ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image_info->filename != (char *) NULL);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  read_info=CloneImageInfo(image_info);
  (void) CopyMagickString(magick_filename,read_info->filename,MaxTextExtent);
  (void) SetImageInfo(read_info,0,exception);
  (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
  (void) CopyMagickString(magick,read_info->magick,MaxTextExtent);
  domain=CoderPolicyDomain;
  rights=ReadPolicyRights;
  if (IsRightsAuthorized(domain,rights,read_info->magick) == MagickFalse)
    {
      errno=EPERM;
      (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
        "NotAuthorized","`%s'",read_info->filename);
      return((Image *) NULL);
    }
  /*
    Call appropriate image reader based on image type.
  */
  sans_exception=AcquireExceptionInfo();
  magick_info=GetMagickInfo(read_info->magick,sans_exception);
  sans_exception=DestroyExceptionInfo(sans_exception);
  if (magick_info != (const MagickInfo *) NULL)
    {
      if (GetMagickEndianSupport(magick_info) == MagickFalse)
        read_info->endian=UndefinedEndian;
      else
        if ((image_info->endian == UndefinedEndian) &&
            (GetMagickRawSupport(magick_info) != MagickFalse))
          {
            size_t
              lsb_first;

            lsb_first=1;
            read_info->endian=(*(char *) &lsb_first) == 1 ? LSBEndian :
              MSBEndian;
         }
    }
  if ((magick_info != (const MagickInfo *) NULL) &&
      (GetMagickSeekableStream(magick_info) != MagickFalse))
    {
      MagickBooleanType
        status;

      image=AcquireImage(read_info,exception);
      (void) CopyMagickString(image->filename,read_info->filename,
        MaxTextExtent);
      status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
      if (status == MagickFalse)
        {
          read_info=DestroyImageInfo(read_info);
          image=DestroyImage(image);
          return((Image *) NULL);
        }
      if (IsBlobSeekable(image) == MagickFalse)
        {
          /*
            Coder requires a seekable stream.
          */
          *read_info->filename='\0';
          status=ImageToFile(image,read_info->filename,exception);
          if (status == MagickFalse)
            {
              (void) CloseBlob(image);
              read_info=DestroyImageInfo(read_info);
              image=DestroyImage(image);
              return((Image *) NULL);
            }
          read_info->temporary=MagickTrue;
        }
      (void) CloseBlob(image);
      image=DestroyImage(image);
    }
  image=NewImageList();
  if (constitute_semaphore == (SemaphoreInfo *) NULL)
    AcquireSemaphoreInfo(&constitute_semaphore);
  if ((magick_info != (const MagickInfo *) NULL) &&
      (GetImageDecoder(magick_info) != (DecodeImageHandler *) NULL))
    {
      thread_support=GetMagickThreadSupport(magick_info);
      if ((thread_support & DecoderThreadSupport) == 0)
        LockSemaphoreInfo(constitute_semaphore);
      image=GetImageDecoder(magick_info)(read_info,exception);
      if ((thread_support & DecoderThreadSupport) == 0)
        UnlockSemaphoreInfo(constitute_semaphore);
    }
  else
    {
      delegate_info=GetDelegateInfo(read_info->magick,(char *) NULL,exception);
      if (delegate_info == (const DelegateInfo *) NULL)
        {
          (void) ThrowMagickException(exception,GetMagickModule(),
            MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
            read_info->filename);
          if (read_info->temporary != MagickFalse)
            (void) RelinquishUniqueFileResource(read_info->filename);
          read_info=DestroyImageInfo(read_info);
          return((Image *) NULL);
        }
      /*
        Let our decoding delegate process the image.
      */
      image=AcquireImage(read_info,exception);
      if (image == (Image *) NULL)
        {
          read_info=DestroyImageInfo(read_info);
          return((Image *) NULL);
        }
      (void) CopyMagickString(image->filename,read_info->filename,
        MaxTextExtent);
      *read_info->filename='\0';
      if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
        LockSemaphoreInfo(constitute_semaphore);
      (void) InvokeDelegate(read_info,image,read_info->magick,(char *) NULL,
        exception);
      if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
        UnlockSemaphoreInfo(constitute_semaphore);
      image=DestroyImageList(image);
      read_info->temporary=MagickTrue;
      (void) SetImageInfo(read_info,0,exception);
      magick_info=GetMagickInfo(read_info->magick,exception);
      if ((magick_info == (const MagickInfo *) NULL) ||
          (GetImageDecoder(magick_info) == (DecodeImageHandler *) NULL))
        {
          if (IsPathAccessible(read_info->filename) != MagickFalse)
            (void) ThrowMagickException(exception,GetMagickModule(),
              MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
              read_info->filename);
          else
            ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
              read_info->filename);
          read_info=DestroyImageInfo(read_info);
          return((Image *) NULL);
        }
      thread_support=GetMagickThreadSupport(magick_info);
      if ((thread_support & DecoderThreadSupport) == 0)
        LockSemaphoreInfo(constitute_semaphore);
      image=(Image *) (GetImageDecoder(magick_info))(read_info,exception);
      if ((thread_support & DecoderThreadSupport) == 0)
        UnlockSemaphoreInfo(constitute_semaphore);
    }
  if (read_info->temporary != MagickFalse)
    {
      (void) RelinquishUniqueFileResource(read_info->filename);
      read_info->temporary=MagickFalse;
      if (image != (Image *) NULL)
        (void) CopyMagickString(image->filename,filename,MaxTextExtent);
    }
  if (image == (Image *) NULL)
    {
      read_info=DestroyImageInfo(read_info);
      return(image);
    }
  if (exception->severity >= ErrorException)
    (void) LogMagickEvent(ExceptionEvent,GetMagickModule(),
      "Coder (%s) generated an image despite an error (%d), "
      "notify the developers",image->magick,exception->severity);
  if (IsBlobTemporary(image) != MagickFalse)
    (void) RelinquishUniqueFileResource(read_info->filename);
  if ((GetNextImageInList(image) != (Image *) NULL) &&
      (IsSceneGeometry(read_info->scenes,MagickFalse) != MagickFalse))
    {
      Image
        *clones;

      clones=CloneImages(image,read_info->scenes,exception);
      if (clones == (Image *) NULL)
        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
          "SubimageSpecificationReturnsNoImages","`%s'",read_info->filename);
      else
        {
          image=DestroyImageList(image);
          image=GetFirstImageInList(clones);
        }
    }
  if (GetBlobError(image) != MagickFalse)
    {
      ThrowFileException(exception,FileOpenError,
        "AnErrorHasOccurredReadingFromFile",read_info->filename);
      image=DestroyImageList(image);
      read_info=DestroyImageInfo(read_info);
      return((Image *) NULL);
    }
  for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
  {
    char
      magick_path[MaxTextExtent],
      *property,
      timestamp[MaxTextExtent];

    const char
      *option;

    const StringInfo
      *profile;

    next->taint=MagickFalse;
    GetPathComponent(magick_filename,MagickPath,magick_path);
    if (*magick_path == '\0')
      (void) CopyMagickString(next->magick,magick,MaxTextExtent);
    (void) CopyMagickString(next->magick_filename,magick_filename,
      MaxTextExtent);
    if (IsBlobTemporary(image) != MagickFalse)
      (void) CopyMagickString(next->filename,filename,MaxTextExtent);
    if (next->magick_columns == 0)
      next->magick_columns=next->columns;
    if (next->magick_rows == 0)
      next->magick_rows=next->rows;
    value=GetImageProperty(next,"tiff:Orientation",exception);
    if (value == (char *) NULL)
      value=GetImageProperty(next,"exif:Orientation",exception);
    if (value != (char *) NULL)
      {
        next->orientation=(OrientationType) StringToLong(value);
        (void) DeleteImageProperty(next,"tiff:Orientation");
        (void) DeleteImageProperty(next,"exif:Orientation");
      }
    value=GetImageProperty(next,"exif:XResolution",exception);
    if (value != (char *) NULL)
      {
        geometry_info.rho=next->resolution.x;
        geometry_info.sigma=1.0;
        flags=ParseGeometry(value,&geometry_info);
        if (geometry_info.sigma != 0)
          next->resolution.x=geometry_info.rho/geometry_info.sigma;
        (void) DeleteImageProperty(next,"exif:XResolution");
      }
    value=GetImageProperty(next,"exif:YResolution",exception);
    if (value != (char *) NULL)
      {
        geometry_info.rho=next->resolution.y;
        geometry_info.sigma=1.0;
        flags=ParseGeometry(value,&geometry_info);
        if (geometry_info.sigma != 0)
          next->resolution.y=geometry_info.rho/geometry_info.sigma;
        (void) DeleteImageProperty(next,"exif:YResolution");
      }
    value=GetImageProperty(next,"tiff:ResolutionUnit",exception);
    if (value == (char *) NULL)
      value=GetImageProperty(next,"exif:ResolutionUnit",exception);
    if (value != (char *) NULL)
      {
        next->units=(ResolutionType) (StringToLong(value)-1);
        (void) DeleteImageProperty(next,"exif:ResolutionUnit");
        (void) DeleteImageProperty(next,"tiff:ResolutionUnit");
      }
    if (next->page.width == 0)
      next->page.width=next->columns;
    if (next->page.height == 0)
      next->page.height=next->rows;
    option=GetImageOption(read_info,"caption");
    if (option != (const char *) NULL)
      {
        property=InterpretImageProperties(read_info,next,option,exception);
        (void) SetImageProperty(next,"caption",property,exception);
        property=DestroyString(property);
      }
    option=GetImageOption(read_info,"comment");
    if (option != (const char *) NULL)
      {
        property=InterpretImageProperties(read_info,next,option,exception);
        (void) SetImageProperty(next,"comment",property,exception);
        property=DestroyString(property);
      }
    option=GetImageOption(read_info,"label");
    if (option != (const char *) NULL)
      {
        property=InterpretImageProperties(read_info,next,option,exception);
        (void) SetImageProperty(next,"label",property,exception);
        property=DestroyString(property);
      }
    if (LocaleCompare(next->magick,"TEXT") == 0)
      (void) ParseAbsoluteGeometry("0x0+0+0",&next->page);
    if ((read_info->extract != (char *) NULL) &&
        (read_info->stream == (StreamHandler) NULL))
      {
        RectangleInfo
          geometry;

        flags=ParseAbsoluteGeometry(read_info->extract,&geometry);
        if ((next->columns != geometry.width) ||
            (next->rows != geometry.height))
          {
            if (((flags & XValue) != 0) || ((flags & YValue) != 0))
              {
                Image
                  *crop_image;

                crop_image=CropImage(next,&geometry,exception);
                if (crop_image != (Image *) NULL)
                  ReplaceImageInList(&next,crop_image);
              }
            else
              if (((flags & WidthValue) != 0) || ((flags & HeightValue) != 0))
                {
                  Image
                    *size_image;

                  flags=ParseRegionGeometry(next,read_info->extract,&geometry,
                    exception);
                  size_image=ResizeImage(next,geometry.width,geometry.height,
                    next->filter,next->blur,exception);
                  if (size_image != (Image *) NULL)
                    ReplaceImageInList(&next,size_image);
                }
          }
      }
    profile=GetImageProfile(next,"icc");
    if (profile == (const StringInfo *) NULL)
      profile=GetImageProfile(next,"icm");
    profile=GetImageProfile(next,"iptc");
    if (profile == (const StringInfo *) NULL)
      profile=GetImageProfile(next,"8bim");
    (void) FormatMagickTime(GetBlobProperties(next)->st_mtime,MaxTextExtent,
      timestamp);
    (void) SetImageProperty(next,"date:modify",timestamp,exception);
    (void) FormatMagickTime(GetBlobProperties(next)->st_ctime,MaxTextExtent,
      timestamp);
    (void) SetImageProperty(next,"date:create",timestamp,exception);
    option=GetImageOption(image_info,"delay");
    if (option != (const char *) NULL)
      {
        GeometryInfo
          geometry_info;

        flags=ParseGeometry(option,&geometry_info);
        if ((flags & GreaterValue) != 0)
          {
            if (next->delay > (size_t) floor(geometry_info.rho+0.5))
              next->delay=(size_t) floor(geometry_info.rho+0.5);
          }
        else
          if ((flags & LessValue) != 0)
            {
              if (next->delay < (size_t) floor(geometry_info.rho+0.5))
                next->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5);
            }
          else
            next->delay=(size_t) floor(geometry_info.rho+0.5);
        if ((flags & SigmaValue) != 0)
          next->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5);
      }
    option=GetImageOption(image_info,"dispose");
    if (option != (const char *) NULL)
      next->dispose=(DisposeType) ParseCommandOption(MagickDisposeOptions,
        MagickFalse,option);
    if (read_info->verbose != MagickFalse)
      (void) IdentifyImage(next,stderr,MagickFalse,exception);
    image=next;
  }
  read_info=DestroyImageInfo(read_info);
  return(GetFirstImageInList(image));
}
示例#8
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   G l o b E x p r e s s i o n                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GlobExpression() returns MagickTrue if the expression matches the pattern.
%
%  The format of the GlobExpression function is:
%
%      MagickBooleanType GlobExpression(const char *expression,
%        const char *pattern,const MagickBooleanType case_insensitive)
%
%  A description of each parameter follows:
%
%    o expression: Specifies a pointer to a text string containing a file name.
%
%    o pattern: Specifies a pointer to a text string containing a pattern.
%
%    o case_insensitive: set to MagickTrue to ignore the case when matching
%      an expression.
%
*/
MagickExport MagickBooleanType GlobExpression(const char *expression,
  const char *pattern,const MagickBooleanType case_insensitive)
{
  MagickBooleanType
    done,
    match;

  register const char
    *p;

  /*
    Return on empty pattern or '*'.
  */
  if (pattern == (char *) NULL)
    return(MagickTrue);
  if (GetUTFCode(pattern) == 0)
    return(MagickTrue);
  if (LocaleCompare(pattern,"*") == 0)
    return(MagickTrue);
  p=pattern+strlen(pattern)-1;
  if ((GetUTFCode(p) == ']') && (strchr(pattern,'[') != (char *) NULL))
    {
      ExceptionInfo
        *exception;

      ImageInfo
        *image_info;

      /*
        Determine if pattern is a scene, i.e. img0001.pcd[2].
      */
      image_info=AcquireImageInfo();
      (void) CopyMagickString(image_info->filename,pattern,MaxTextExtent);
      exception=AcquireExceptionInfo();
      (void) SetImageInfo(image_info,MagickTrue,exception);
      exception=DestroyExceptionInfo(exception);
      if (LocaleCompare(image_info->filename,pattern) != 0)
        {
          image_info=DestroyImageInfo(image_info);
          return(MagickFalse);
        }
      image_info=DestroyImageInfo(image_info);
    }
  /*
    Evaluate glob expression.
  */
  done=MagickFalse;
  while ((GetUTFCode(pattern) != 0) && (done == MagickFalse))
  {
    if (GetUTFCode(expression) == 0)
      if ((GetUTFCode(pattern) != '{') && (GetUTFCode(pattern) != '*'))
        break;
    switch (GetUTFCode(pattern))
    {
      case '\\':
      {
        pattern+=GetUTFOctets(pattern);
        if (GetUTFCode(pattern) != 0)
          pattern+=GetUTFOctets(pattern);
        break;
      }
      case '*':
      {
        MagickBooleanType
          status;

        status=MagickFalse;
        pattern+=GetUTFOctets(pattern);
        while ((GetUTFCode(expression) != 0) && (status == MagickFalse))
        {
          status=GlobExpression(expression,pattern,case_insensitive);
          expression+=GetUTFOctets(expression);
        }
        if (status != MagickFalse)
          {
            while (GetUTFCode(expression) != 0)
              expression+=GetUTFOctets(expression);
            while (GetUTFCode(pattern) != 0)
              pattern+=GetUTFOctets(pattern);
          }
        break;
      }
      case '[':
      {
        long
          c;

        pattern+=GetUTFOctets(pattern);
        for ( ; ; )
        {
          if ((GetUTFCode(pattern) == 0) || (GetUTFCode(pattern) == ']'))
            {
              done=MagickTrue;
              break;
            }
          if (GetUTFCode(pattern) == '\\')
            {
              pattern+=GetUTFOctets(pattern);
              if (GetUTFCode(pattern) == 0)
                {
                  done=MagickTrue;
                  break;
                }
             }
          if (GetUTFCode(pattern+GetUTFOctets(pattern)) == '-')
            {
              c=GetUTFCode(pattern);
              pattern+=GetUTFOctets(pattern);
              pattern+=GetUTFOctets(pattern);
              if (GetUTFCode(pattern) == ']')
                {
                  done=MagickTrue;
                  break;
                }
              if (GetUTFCode(pattern) == '\\')
                {
                  pattern+=GetUTFOctets(pattern);
                  if (GetUTFCode(pattern) == 0)
                    {
                      done=MagickTrue;
                      break;
                    }
                }
              if ((GetUTFCode(expression) < c) ||
                  (GetUTFCode(expression) > GetUTFCode(pattern)))
                {
                  pattern+=GetUTFOctets(pattern);
                  continue;
                }
            }
          else
            if (GetUTFCode(pattern) != GetUTFCode(expression))
              {
                pattern+=GetUTFOctets(pattern);
                continue;
              }
          pattern+=GetUTFOctets(pattern);
          while ((GetUTFCode(pattern) != ']') && (GetUTFCode(pattern) != 0))
          {
            if ((GetUTFCode(pattern) == '\\') &&
                (GetUTFCode(pattern+GetUTFOctets(pattern)) > 0))
              pattern+=GetUTFOctets(pattern);
            pattern+=GetUTFOctets(pattern);
          }
          if (GetUTFCode(pattern) != 0)
            {
              pattern+=GetUTFOctets(pattern);
              expression+=GetUTFOctets(expression);
            }
          break;
        }
        break;
      }
      case '?':
      {
        pattern+=GetUTFOctets(pattern);
        expression+=GetUTFOctets(expression);
        break;
      }
      case '{':
      {
        register const char
          *p;

        pattern+=GetUTFOctets(pattern);
        while ((GetUTFCode(pattern) != '}') && (GetUTFCode(pattern) != 0))
        {
          p=expression;
          match=MagickTrue;
          while ((GetUTFCode(p) != 0) && (GetUTFCode(pattern) != 0) &&
                 (GetUTFCode(pattern) != ',') && (GetUTFCode(pattern) != '}') &&
                 (match != MagickFalse))
          {
            if (GetUTFCode(pattern) == '\\')
              pattern+=GetUTFOctets(pattern);
            match=(GetUTFCode(pattern) == GetUTFCode(p)) ? MagickTrue :
              MagickFalse;
            p+=GetUTFOctets(p);
            pattern+=GetUTFOctets(pattern);
          }
          if (GetUTFCode(pattern) == 0)
            {
              match=MagickFalse;
              done=MagickTrue;
              break;
            }
          else
            if (match != MagickFalse)
              {
                expression=p;
                while ((GetUTFCode(pattern) != '}') &&
                       (GetUTFCode(pattern) != 0))
                {
                  pattern+=GetUTFOctets(pattern);
                  if (GetUTFCode(pattern) == '\\')
                    {
                      pattern+=GetUTFOctets(pattern);
                      if (GetUTFCode(pattern) == '}')
                        pattern+=GetUTFOctets(pattern);
                    }
                }
              }
            else
              {
                while ((GetUTFCode(pattern) != '}') &&
                       (GetUTFCode(pattern) != ',') &&
                       (GetUTFCode(pattern) != 0))
                {
                  pattern+=GetUTFOctets(pattern);
                  if (GetUTFCode(pattern) == '\\')
                    {
                      pattern+=GetUTFOctets(pattern);
                      if ((GetUTFCode(pattern) == '}') ||
                          (GetUTFCode(pattern) == ','))
                        pattern+=GetUTFOctets(pattern);
                    }
                }
              }
            if (GetUTFCode(pattern) != 0)
              pattern+=GetUTFOctets(pattern);
          }
        break;
      }
      default:
      {
        if (case_insensitive != MagickFalse)
          {
            if (tolower((int) GetUTFCode(expression)) !=
                tolower((int) GetUTFCode(pattern)))
              {
                done=MagickTrue;
                break;
              }
          }
        else
          if (GetUTFCode(expression) != GetUTFCode(pattern))
            {
              done=MagickTrue;
              break;
            }
        expression+=GetUTFOctets(expression);
        pattern+=GetUTFOctets(pattern);
      }
    }
  }
  while (GetUTFCode(pattern) == '*')
    pattern+=GetUTFOctets(pattern);
  match=(GetUTFCode(expression) == 0) && (GetUTFCode(pattern) == 0) ?
    MagickTrue : MagickFalse;
  return(match);
}
示例#9
0
/**
 * Call QuantizeImages.
 *
 * Ruby usage:
 *   - @verbatim ImageList#quantize @endverbatim
 *   - @verbatim ImageList#quantize(number_colors) @endverbatim
 *   - @verbatim ImageList#quantize(number_colors, colorspace) @endverbatim
 *   - @verbatim ImageList#quantize(number_colors, colorspace, dither) @endverbatim
 *   - @verbatim ImageList#quantize(number_colors, colorspace, dither, tree_depth) @endverbatim
 *   - @verbatim ImageList#quantize(number_colors, colorspace, dither, tree_depth, measure_error) @endverbatim
 *
 * Notes:
 *   - Default number_colors is 256
 *   - Default coorspace is Magick::RGBColorsapce
 *   - Default dither is true
 *   - Default tree_depth is 0
 *   - Default measure_error is false
 *   - Sets \@scene to the same value as self.scene
 *
 * @param argc number of input arguments
 * @param argv array of input arguments
 * @param self this object
 * @return a new ImageList with quantized images
 */
VALUE
ImageList_quantize(int argc, VALUE *argv, VALUE self)
{
    Image *images, *new_images;
    Image *new_image;
    QuantizeInfo quantize_info;
    ExceptionInfo *exception;
    VALUE new_imagelist, scene;

    GetQuantizeInfo(&quantize_info);

    switch (argc)
    {
        case 5:
            quantize_info.measure_error = (MagickBooleanType) RTEST(argv[4]);
        case 4:
            quantize_info.tree_depth = (unsigned long)NUM2INT(argv[3]);
        case 3:
#if defined(HAVE_TYPE_DITHERMETHOD) && defined(HAVE_ENUM_NODITHERMETHOD)
            if (rb_obj_is_kind_of(argv[2], Class_DitherMethod))
            {
                VALUE_TO_ENUM(argv[2], quantize_info.dither_method, DitherMethod);
                quantize_info.dither = quantize_info.dither_method != NoDitherMethod;
            }
#else
            quantize_info.dither = (MagickBooleanType) RTEST(argv[2]);
#endif
        case 2:
            VALUE_TO_ENUM(argv[1], quantize_info.colorspace, ColorspaceType);
        case 1:
            quantize_info.number_colors = NUM2ULONG(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 5)", argc);
            break;
    }


    // Convert image array to image sequence, clone image sequence.
    exception = AcquireExceptionInfo();
    images = images_from_imagelist(self);
    new_images = CloneImageList(images, exception);
    rm_split(images);
    rm_check_exception(exception, new_images, DestroyOnError);

    rm_ensure_result(new_images);


    (void) QuantizeImages(&quantize_info, new_images);
    rm_check_exception(exception, new_images, DestroyOnError);
    (void) DestroyExceptionInfo(exception);

    // Create new ImageList object, convert mapped image sequence to images,
    // append to images array.
    new_imagelist = ImageList_new();
    while ((new_image = RemoveFirstImageFromList(&new_images)))
    {
        imagelist_push(new_imagelist, rm_image_new(new_image));
    }

    // Set @scene in new ImageList object to same value as in self.
    scene = rb_iv_get(self, "@scene");
    (void) rb_iv_set(new_imagelist, "@scene", scene);

    RB_GC_GUARD(new_imagelist);
    RB_GC_GUARD(scene);

    return new_imagelist;
}
示例#10
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%  M a i n                                                                    %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
*/
int main(int argc,char **argv)
{
  char
    *option;

  double
    elapsed_time,
    user_time;

  ExceptionInfo
    *exception;

  ImageInfo
    *image_info;

  MagickBooleanType
    regard_warnings,
    status;

  register long
    i;

  TimerInfo
    timer;

  unsigned long
    iterations;

  MagickCoreGenesis(*argv,MagickTrue);
  exception=AcquireExceptionInfo();
  iterations=1;
  status=MagickFalse;
  regard_warnings=MagickFalse;
  for (i=1; i < (long) (argc-1); i++)
  {
    option=argv[i];
    if ((strlen(option) == 1) || ((*option != '-') && (*option != '+')))
      continue;
    if (LocaleCompare("bench",option+1) == 0)
      iterations=(unsigned long) atol(argv[++i]);
    if (LocaleCompare("debug",option+1) == 0)
      (void) SetLogEventMask(argv[++i]);
    if (LocaleCompare("regard-warnings",option+1) == 0)
      regard_warnings=MagickTrue;
  }
  GetTimerInfo(&timer);
  for (i=0; i < (long) iterations; i++)
  {
    image_info=AcquireImageInfo();
    status=ConvertImageCommand(image_info,argc,argv,(char **) NULL,exception);
    if (exception->severity != UndefinedException)
      {
        if ((exception->severity > ErrorException) ||
            (regard_warnings != MagickFalse))
          status=MagickTrue;
        CatchException(exception);
      }
    image_info=DestroyImageInfo(image_info);
  }
  if (iterations > 1)
    {
      elapsed_time=GetElapsedTime(&timer);
      user_time=GetUserTime(&timer);
      (void) fprintf(stderr,"Performance: %lui %gips %0.3fu %ld:%02ld\n",
        iterations,1.0*iterations/elapsed_time,user_time,(long)
        (elapsed_time/60.0+0.5),(long) ceil(fmod(elapsed_time,60.0)));
    }
  exception=DestroyExceptionInfo(exception);
  MagickCoreTerminus();
  return(status == MagickFalse ? 0 : 1);
}
示例#11
0
// GP: mode = -1 will be automatically guessed from the file
SEXP
lib_readImages (SEXP files, SEXP mode) {
    SEXP res;
    int _mode, i, nappends;
    Image * image, * images;
    ImageInfo * image_info;
    ExceptionInfo exception;
    const char * file;
    ImageType it;

    if ( LENGTH(files) < 1 )
        error ( "please supply at least one file name or URL" );
    _mode = INTEGER (mode)[0];
    if ( _mode < -1 || _mode > MODE_MAX)
        error ( "requested mode is not supported" );

    // Special call for reading Cellomics image
    if (LENGTH(files)==1) {
      file = CHAR(STRING_ELT(files, 0));
      i = strlen(file);
      if (i>4 && (strncmp(&file[i-4], ".c01", 4)==0 || strncmp(&file[i-4], ".C01", 4)==0)) {
	return (readCellomics(file));
      }
    }

    image_info = (ImageInfo *) NULL;
    /* images loaded into image and moved into this list */
    images = NewImageList ();
    GetExceptionInfo (&exception);
    image_info = CloneImageInfo ( (ImageInfo *)NULL );
    nappends = 0;

    for ( i = 0; i < LENGTH (files); i++ ) {
        if ( LENGTH (files) > 1 )
            file = CHAR ( STRING_ELT(files, i) );
        else
            file = CHAR ( asChar(files) );
        strcpy (image_info->filename, file);

	// Prevent an ImageMagick bug when file is an empty string or NULL
	if (file==NULL) image=NULL;
	else if (strlen(file)==0) image=NULL;
	else {
	  image = ReadImage (image_info, &exception);
	  CatchException (&exception);
	}
        if ( image == (Image *)NULL ) {
            warning ("requested image not found or could not be loaded" );
            continue;
        }

	// Automatic color mode guess
	if (_mode==-1) {
	  it = GetImageType(image,&exception);
	  // Rprintf("it=%d G=%d P=%d PM=%d\n",it, GrayscaleType, PaletteType, PaletteMatteType);
	  if (it==BilevelType || it==GrayscaleType || it==GrayscaleMatteType) _mode=MODE_GRAYSCALE;
	  else _mode=MODE_COLOR;
	}
       
        /* do not destroy image here */
        AppendImageToList (&images, image);

        if ( nappends == 0 ) {
            /* set all attributes from the first image */
            strcpy (images->filename, image->filename);
            images->compression = image->compression;
            images->x_resolution = image->x_resolution;
            images->y_resolution = image->y_resolution;
        }
        nappends++;
    }
    /* do not update image properties here because if no image was added to
    the list it will cause segfault, or use GetImageListLength first to check size */
    image_info = DestroyImageInfo (image_info);

    /* convert image list into R object */
    res = PROTECT(magick2SEXP (images, _mode));
    images = DestroyImageList (images);

    DestroyExceptionInfo(&exception);

    UNPROTECT(1);

    return res;
}
示例#12
0
void draw_tiger_map (Widget w,
        char *filenm,
        int destination_pixmap,
        int nocache) {  // For future implementation of a "refresh cached map" option
    char file[MAX_FILENAME];        // Complete path/name of image file
    char short_filenm[MAX_FILENAME];
    FILE *f;                        // Filehandle of image file
    char fileimg[MAX_FILENAME];     // Ascii name of image file, read from GEO file
    char tigertmp[MAX_FILENAME*2];  // Used for putting together the tigermap query
    int width, height;
    tiepoint tp[2];                 // Calibration points for map, read in from .geo file
    register long map_c_T, map_c_L; // map delta NW edge coordinates, DNN: these should be signed
    register long tp_c_dx, tp_c_dy; // tiepoint coordinate differences
    unsigned long c_x_min,  c_y_min;// top left coordinates of map inside screen
    unsigned long c_y_max;          // bottom right coordinates of map inside screen
    double c_x;                     // Xastir coordinates 1/100 sec, 0 = 180°W
    double c_y;                     // Xastir coordinates 1/100 sec, 0 =  90°N

    long map_y_0;                   // map pixel pointer prior to TM adjustment
    register long map_x, map_y;     // map pixel pointers, DNN: this was a float, chg to long
    long map_x_min, map_x_max;      // map boundaries for in screen part of map
    long map_y_min, map_y_max;      //
    long map_x_ctr;                 // half map width in pixel
    long map_y_ctr;                 // half map height in pixel
    int map_seen = 0;
    int map_act;
    int map_done;

    long map_c_yc;                  // map center, vert coordinate
    long map_c_xc;                  // map center, hor  coordinate
    double map_c_dx, map_c_dy;      // map coordinates increment (pixel width)
    double c_dx;                    // adjusted map pixel width

    long scr_x,  scr_y;             // screen pixel plot positions
    long scr_xp, scr_yp;            // previous screen plot positions
    int  scr_dx, scr_dy;            // increments in screen plot positions
    long scr_x_mc;                  // map center in screen units

    long scr_c_xr;

    long scale_xa;                  // adjusted for topo maps
    double scale_x_nm;              // nm per Xastir coordinate unit
    long scale_x0;                  // at widest map area

    char local_filename[MAX_FILENAME];
    
    ExceptionInfo exception;
    Image *image;
    ImageInfo *image_info;
    PixelPacket *pixel_pack;
    PixelPacket temp_pack;
    IndexPacket *index_pack;
    int l;
    XColor my_colors[256];
    double left, right, top, bottom, map_width, map_height;
    double lat_center  = 0;
    double long_center = 0;

    char map_it[MAX_FILENAME];
    char tmpstr[100];
    int geo_image_width;        // Image width  from GEO file
    int geo_image_height;       // Image height from GEO file

    // initialize this
    local_filename[0]='\0';

    // Create a shorter filename for display (one that fits the
    // status line more closely).  Subtract the length of the
    // "Indexing " and/or "Loading " strings as well.
    if (strlen(filenm) > (41 - 9)) {
        int avail = 41 - 11;
        int new_len = strlen(filenm) - avail;

        xastir_snprintf(short_filenm,
            sizeof(short_filenm),
            "..%s",
            &filenm[new_len]);
    }
    else {
        xastir_snprintf(short_filenm,
            sizeof(short_filenm),
            "%s",
            filenm);
    }

    xastir_snprintf(map_it,
        sizeof(map_it),
        langcode ("BBARSTA028"),
        short_filenm);
    statusline(map_it,0);       // Loading ...


        
    // Check whether we're indexing or drawing the map
    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {

        // We're indexing only.  Save the extents in the index.
        // Force the extents to the edges of the earth for the
        // index file.
        index_update_xastir(filenm, // Filename only
            64800000l,      // Bottom
            0l,             // Top
            0l,             // Left
            129600000l,     // Right
            0);             // Default Map Level

        // Update statusline
        xastir_snprintf(map_it,
            sizeof(map_it),
            langcode ("BBARSTA039"),
            short_filenm);
        statusline(map_it,0);       // Loading/Indexing ...

        return; // Done indexing this file
    }


    // Tiepoint for upper left screen corner
    //
    tp[0].img_x = 0;                // Pixel Coordinates
    tp[0].img_y = 0;                // Pixel Coordinates
    tp[0].x_long = NW_corner_longitude;   // Xastir Coordinates
    tp[0].y_lat  = NW_corner_latitude;    // Xastir Coordinates

    // Tiepoint for lower right screen corner
    //
    tp[1].img_x =  screen_width - 1; // Pixel Coordinates
    tp[1].img_y = screen_height - 1; // Pixel Coordinates 

    tp[1].x_long = SE_corner_longitude; // Xastir Coordinates
    tp[1].y_lat  =  SE_corner_latitude; // Xastir Coordinates

    left = (double)((NW_corner_longitude - 64800000l )/360000.0);   // Lat/long Coordinates
    top = (double)(-((NW_corner_latitude - 32400000l )/360000.0));  // Lat/long Coordinates
    right = (double)((SE_corner_longitude - 64800000l)/360000.0);//Lat/long Coordinates
    bottom = (double)(-((SE_corner_latitude - 32400000l)/360000.0));//Lat/long Coordinates

    map_width = right - left;   // Lat/long Coordinates
    map_height = top - bottom;  // Lat/long Coordinates

    geo_image_width  = screen_width;
    geo_image_height = screen_height;

    long_center = (left + right)/2.0l;
    lat_center  = (top + bottom)/2.0l;

//  Example query to the census map server....
/*        xastir_snprintf(fileimg, sizeof(fileimg), 
        "\'http://tiger.census.gov/cgi-bin/mapper/map.gif?on=CITIES&on=GRID&on=counties&on=majroads&on=places&&on=interstate&on=states&on=ushwy&on=statehwy&lat=%f\046lon=%f\046wid=%f\046ht=%f\046iwd=%i\046iht=%i\'",\
                   lat_center, long_center, map_width, map_height, tp[1].img_x + 1, tp[1].img_y + 1); */

    xastir_snprintf(tigertmp, sizeof(tigertmp), "http://tiger.census.gov/cgi-bin/mapper/map.gif?");

    if (tiger_show_grid)
        strncat(tigertmp, "&on=GRID", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=GRID", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_counties)
        strncat(tigertmp, "&on=counties", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=counties", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_cities)
        strncat(tigertmp, "&on=CITIES", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=CITIES", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_places)
        strncat(tigertmp, "&on=places", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=places", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_majroads)
        strncat(tigertmp, "&on=majroads", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=majroads", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_streets)
        strncat(tigertmp, "&on=streets", sizeof(tigertmp) - 1 - strlen(tigertmp));
    // Don't turn streets off since this will automagically show up as you zoom in.

    if (tiger_show_railroad)
        strncat(tigertmp, "&on=railroad", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=railroad", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_states)
        strncat(tigertmp, "&on=states", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=states", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_interstate)
        strncat(tigertmp, "&on=interstate", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=interstate", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_ushwy)
        strncat(tigertmp, "&on=ushwy", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=ushwy", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_statehwy)
        strncat(tigertmp, "&on=statehwy", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=statehwy", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_water)
        strncat(tigertmp, "&on=water", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=water", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_lakes)
        strncat(tigertmp, "&on=shorelin", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=shorelin", sizeof(tigertmp) - 1 - strlen(tigertmp));

    if (tiger_show_misc)
        strncat(tigertmp, "&on=miscell", sizeof(tigertmp) - 1 - strlen(tigertmp));
    else
        strncat(tigertmp, "&off=miscell", sizeof(tigertmp) - 1 - strlen(tigertmp));

    xastir_snprintf(tmpstr, sizeof(tmpstr), "&lat=%f\046lon=%f\046", lat_center, long_center);    
    strncat (tigertmp, tmpstr, sizeof(tigertmp) - 1 - strlen(tigertmp));
    xastir_snprintf(tmpstr, sizeof(tmpstr), "wid=%f\046ht=%f\046", map_width, map_height);
    strncat (tigertmp, tmpstr, sizeof(tigertmp) - 1 - strlen(tigertmp));
    xastir_snprintf(tmpstr, sizeof(tmpstr), "iwd=%i\046iht=%i", tp[1].img_x + 1, tp[1].img_y + 1);
    strncat (tigertmp, tmpstr, sizeof(tigertmp) - 1 - strlen(tigertmp));
    xastir_snprintf(fileimg, sizeof(fileimg), "%s", tigertmp);

    if (debug_level & 512) {
          fprintf(stderr,"left side is %f\n", left);
          fprintf(stderr,"right side is %f\n", right);
          fprintf(stderr,"top  is %f\n", top);
          fprintf(stderr,"bottom is %f\n", bottom);
          fprintf(stderr,"lat center is %f\n", lat_center);
          fprintf(stderr,"long center is %f\n", long_center);
          fprintf(stderr,"screen width is %li\n", screen_width);
          fprintf(stderr,"screen height is %li\n", screen_height);
          fprintf(stderr,"map width is %f\n", map_width);
          fprintf(stderr,"map height is %f\n", map_height);
          fprintf(stderr,"fileimg is %s\n", fileimg);
          fprintf(stderr,"ftp or http file: %s\n", fileimg);
    }


// Hopefully this will eventually allow us to get maps in the background
//    while (sometimeout !=0 && local_filename[0]==NULL){

    if  (local_filename[0]=='\0' ){

        if (debug_level & 512 ) { 
            fprintf(stderr,"tiger_local_file=<%s>\n",local_filename);
        }

        HandlePendingEvents(app_context);
        if (interrupt_drawing_now) {
            // Update to screen
            (void)XCopyArea(XtDisplay(da),
                pixmap,
                XtWindow(da),
                gc,
                0,
                0,
                (unsigned int)screen_width,
                (unsigned int)screen_height,
                0,
                0);
            return;
        }

        get_tiger_local_file(local_filename,fileimg); 

    }

// whackadoodle


    // Tell ImageMagick where to find it
    xastir_snprintf(file,
        sizeof(file),
        "%s",
        local_filename);

    GetExceptionInfo(&exception);

    image_info=CloneImageInfo((ImageInfo *) NULL);

    xastir_snprintf(image_info->filename,
        sizeof(image_info->filename),
        "%s",
        file);

    if (debug_level & 512) {
           fprintf(stderr,"Copied %s into image info.\n", file);
           fprintf(stderr,"image_info got: %s\n", image_info->filename);
           fprintf(stderr,"Entered ImageMagick code.\n");
           fprintf(stderr,"Attempting to open: %s\n", image_info->filename);
    }

    // We do a test read first to see if the file exists, so we
    // don't kill Xastir in the ReadImage routine.
    f = fopen (image_info->filename, "r");
    if (f == NULL) {
        if (debug_level & 512)
            fprintf(stderr,"File could not be read\n");

#ifdef USE_MAP_CACHE

        // clear from cache if bad    
        if (map_cache_del(fileimg)) {
            if (debug_level & 512) {
                fprintf(stderr,"Couldn't delete unreadable map from cache\n");
            }
        }
#endif
         
        if (image_info)
            DestroyImageInfo(image_info);
	DestroyExceptionInfo(&exception);
        return;
    }
    (void)fclose (f);


    image = ReadImage(image_info, &exception);

    if (image == (Image *) NULL) {
        MagickWarning(exception.severity, exception.reason, exception.description);
        //fprintf(stderr,"MagickWarning\n");

#ifdef USE_MAP_CACHE
        // clear from cache if bad    
        if (map_cache_del(fileimg)) {
            if (debug_level & 512) {
                fprintf(stderr,"Couldn't delete map from cache\n");
            }
        }
#endif

        if (image_info)
            DestroyImageInfo(image_info);
	DestroyExceptionInfo(&exception);
        return;
    }


    if (debug_level & 512)
        fprintf(stderr,"Color depth is %i \n", (int)image->depth);

    if (image->colorspace != RGBColorspace) {
        fprintf(stderr,"TBD: I don't think we can deal with colorspace != RGB");
        if (image)
            DestroyImage(image);
        if (image_info)
            DestroyImageInfo(image_info);
	DestroyExceptionInfo(&exception);
        return;
    }

    width = image->columns;
    height = image->rows;

    //  Code to mute the image so it's not as bright.
/*    if (raster_map_intensity < 1.0) {
        char tempstr[30];

        if (debug_level & 512)
            fprintf(stderr,"level=%s\n", tempstr);

        xastir_snprintf(tempstr,
            sizeof(tempstr),
            "%d, 100, 100",
            (int)(raster_map_intensity * 100.0));

        ModulateImage(image, tempstr);
    }
*/


    // If were are drawing to a low bpp display (typically < 8bpp)
    // try to reduce the number of colors in an image.
    // This may take some time, so it would be best to do ahead of
    // time if it is a static image.
#if (MagickLibVersion < 0x0540)
    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL) > 128) {
#else   // MagickLib >= 540
    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL, &exception) > 128) {
#endif  // MagickLib Version

        if (image->storage_class == PseudoClass) {
#if (MagickLibVersion < 0x0549)
            CompressColormap(image); // Remove duplicate colors
#else // MagickLib >= 0x0549
            CompressImageColormap(image); // Remove duplicate colors
#endif  // MagickLibVersion < 0x0549
        }

        // Quantize down to 128 will go here...
    }


    pixel_pack = GetImagePixels(image, 0, 0, image->columns, image->rows);
    if (!pixel_pack) {
        fprintf(stderr,"pixel_pack == NULL!!!");
        if (image)
            DestroyImage(image);
        if (image_info)
            DestroyImageInfo(image_info);
	DestroyExceptionInfo(&exception);
        return;
    }


    index_pack = GetIndexes(image);
    if (image->storage_class == PseudoClass && !index_pack) {
        fprintf(stderr,"PseudoClass && index_pack == NULL!!!");
        if (image)
            DestroyImage(image);
        if (image_info)
            DestroyImageInfo(image_info);
	DestroyExceptionInfo(&exception);
        return;
    }


    if (image->storage_class == PseudoClass && image->colors <= 256) {
        for (l = 0; l < (int)image->colors; l++) {
            // Need to check how to do this for ANY image, as ImageMagick can read in all sorts
            // of image files
            temp_pack = image->colormap[l];
            if (debug_level & 512)
                fprintf(stderr,"Colormap color is %i  %i  %i \n",
                       temp_pack.red, temp_pack.green, temp_pack.blue);

            // Here's a tricky bit:  PixelPacket entries are defined as Quantum's.  Quantum
            // is defined in /usr/include/magick/image.h as either an unsigned short or an
            // unsigned char, depending on what "configure" decided when ImageMagick was installed.
            // We can determine which by looking at MaxRGB or QuantumDepth.
            //
            if (QuantumDepth == 16) {   // Defined in /usr/include/magick/image.h
                if (debug_level & 512)
                    fprintf(stderr,"Color quantum is [0..65535]\n");
                my_colors[l].red   = temp_pack.red * raster_map_intensity;
                my_colors[l].green = temp_pack.green * raster_map_intensity;
                my_colors[l].blue  = temp_pack.blue * raster_map_intensity;
            }
            else {  // QuantumDepth = 8
                if (debug_level & 512)
                    fprintf(stderr,"Color quantum is [0..255]\n");
                my_colors[l].red   = (temp_pack.red << 8) * raster_map_intensity;
                my_colors[l].green = (temp_pack.green << 8) * raster_map_intensity;
                my_colors[l].blue  = (temp_pack.blue << 8) * raster_map_intensity;
            }

            // Get the color allocated on < 8bpp displays. pixel color is written to my_colors.pixel
            if (visual_type == NOT_TRUE_NOR_DIRECT) {
//                XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0);
                XAllocColor(XtDisplay(w), cmap, &my_colors[l]);
            }
            else {
                pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue,
                                &my_colors[l].pixel);
            }

            if (debug_level & 512)
                fprintf(stderr,"Color allocated is %li  %i  %i  %i \n", my_colors[l].pixel,
                       my_colors[l].red, my_colors[l].blue, my_colors[l].green);
        }
    }



    /*
    * Here are the corners of our viewport, using the Xastir
    * coordinate system.  Notice that Y is upside down:
    *
    *   left edge of view = NW_corner_longitude
    *  right edge of view = SE_corner_longitude
    *    top edge of view =  NW_corner_latitude
    * bottom edge of view =  SE_corner_latitude
    *
    * The corners of our map will soon be (after translating the
    * tiepoints to the corners if they're not already there):
    *
    *   left edge of map = tp[0].x_long   in Xastir format
    *  right edge of map = tp[1].x_long
    *    top edge of map = tp[0].y_lat
    * bottom edge of map = tp[1].y_lat
    *
    */
    map_c_L = tp[0].x_long - NW_corner_longitude;     // map left coordinate
    map_c_T = tp[0].y_lat  - NW_corner_latitude;      // map top  coordinate

    tp_c_dx = (long)(tp[1].x_long - tp[0].x_long);//  Width between tiepoints
    tp_c_dy = (long)(tp[1].y_lat  - tp[0].y_lat); // Height between tiepoints


    // Check for tiepoints being in wrong relation to one another
    if (tp_c_dx < 0) 
        tp_c_dx = -tp_c_dx;       // New  width between tiepoints
    if (tp_c_dy < 0) 
        tp_c_dy = -tp_c_dy;       // New height between tiepoints

    // Calculate step size per pixel
    map_c_dx = ((double) tp_c_dx / abs(tp[1].img_x - tp[0].img_x));
    map_c_dy = ((double) tp_c_dy / abs(tp[1].img_y - tp[0].img_y));

    // Scaled screen step size for use with XFillRectangle below
    scr_dx = (int) (map_c_dx / scale_x) + 1;
    scr_dy = (int) (map_c_dy / scale_y) + 1;

    // calculate top left map corner from tiepoints
    if (tp[0].img_x != 0) {
        tp[0].x_long -= (tp[0].img_x * map_c_dx);   // map left edge longitude
        map_c_L = tp[0].x_long - NW_corner_longitude;     // delta ??
        tp[0].img_x = 0;
        if (debug_level & 512)
            fprintf(stderr,"Translated tiepoint_0 x: %d\t%lu\n", tp[0].img_x, tp[0].x_long);
    }
    if (tp[0].img_y != 0) {
        tp[0].y_lat -= (tp[0].img_y * map_c_dy);    // map top edge latitude
        map_c_T = tp[0].y_lat - NW_corner_latitude;
        tp[0].img_y = 0;
        if (debug_level & 512)
            fprintf(stderr,"Translated tiepoint_0 y: %d\t%lu\n", tp[0].img_y, tp[0].y_lat);
    }

    // calculate bottom right map corner from tiepoints
    // map size is geo_image_width / geo_image_height
    if (tp[1].img_x != (geo_image_width - 1) ) {
        tp[1].img_x = geo_image_width - 1;
        tp[1].x_long = tp[0].x_long + (tp[1].img_x * map_c_dx); // right
        if (debug_level & 512)
            fprintf(stderr,"Translated tiepoint_1 x: %d\t%lu\n", tp[1].img_x, tp[1].x_long);
    }
    if (tp[1].img_y != (geo_image_height - 1) ) {
        tp[1].img_y = geo_image_height - 1;
        tp[1].y_lat = tp[0].y_lat + (tp[1].img_y * map_c_dy);   // bottom
        if (debug_level & 512)
            fprintf(stderr,"Translated tiepoint_1 y: %d\t%lu\n", tp[1].img_y, tp[1].y_lat);
    }

    if (debug_level & 512) {
        fprintf(stderr,"X tiepoint width: %ld\n", tp_c_dx);
        fprintf(stderr,"Y tiepoint width: %ld\n", tp_c_dy);
        fprintf(stderr,"Loading imagemap: %s\n", file);
        fprintf(stderr,"\nImage: %s\n", file);
        fprintf(stderr,"Image size %d %d\n", geo_image_width, geo_image_height);
        fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n",
            map_c_L, map_c_T, map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y));
        fprintf(stderr,"Image size %d %d\n", width, height);
#if (MagickLibVersion < 0x0540)
        fprintf(stderr,"Unique colors = %d\n", GetNumberColors(image, NULL));
#else // MagickLib < 540
        fprintf(stderr,"Unique colors = %ld\n", GetNumberColors(image, NULL, &exception));
#endif // MagickLib < 540
        fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n", map_c_L, map_c_T,
            map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y));
        fprintf(stderr,"image matte is %i\n", image->matte);
    } // debug_level & 512

    // draw the image from the file out to the map screen

    // Get the border values for the X and Y for loops used
    // for the XFillRectangle call later.

    map_c_yc = (tp[0].y_lat + tp[1].y_lat) / 2;     // vert center of map as reference
    map_y_ctr = (long)(height / 2 +0.499);
    scale_x0 = get_x_scale(0,map_c_yc,scale_y);     // reference scaling at vert map center

    map_c_xc  = (tp[0].x_long + tp[1].x_long) / 2;  // hor center of map as reference
    map_x_ctr = (long)(width  / 2 +0.499);
    scr_x_mc  = (map_c_xc - NW_corner_longitude) / scale_x; // screen coordinates of map center

    // calculate map pixel range in y direction that falls into screen area
    c_y_max = 0ul;
    map_y_min = map_y_max = 0l;
    for (map_y_0 = 0, c_y = tp[0].y_lat; map_y_0 < (long)height; map_y_0++, c_y += map_c_dy) {
        scr_y = (c_y - NW_corner_latitude) / scale_y;   // current screen position
        if (scr_y > 0) {
            if (scr_y < screen_height) {
                map_y_max = map_y_0;          // update last map pixel in y
                c_y_max = (unsigned long)c_y;// bottom map inside screen coordinate
            } else
                break;                      // done, reached bottom screen border
        } else {                            // pixel is above screen
            map_y_min = map_y_0;              // update first map pixel in y
        }
    }
    c_y_min = (unsigned long)(tp[0].y_lat + map_y_min * map_c_dy);   // top map inside screen coordinate

        map_x_min = map_x_max = 0l;
        for (map_x = 0, c_x = tp[0].x_long; map_x < (long)width; map_x++, c_x += map_c_dx) {
            scr_x = (c_x - NW_corner_longitude)/ scale_x;  // current screen position
            if (scr_x > 0) {
                if (scr_x < screen_width)
                    map_x_max = map_x;          // update last map pixel in x
                else
                    break;                      // done, reached right screen border
            } else {                            // pixel is left from screen
                map_x_min = map_x;              // update first map pixel in x
            }
        }
        c_x_min = (unsigned long)(tp[0].x_long + map_x_min * map_c_dx);   // left map inside screen coordinate

    scr_yp = -1;
    scr_c_xr = SE_corner_longitude;
    c_dx = map_c_dx;                            // map pixel width
    scale_xa = scale_x0;                        // the compiler likes it ;-)

    map_done = 0;
    map_act  = 0;
    map_seen = 0;
    scr_y = screen_height - 1;


    // loop over map pixel rows
    for (map_y_0 = map_y_min, c_y = (double)c_y_min; (map_y_0 <= map_y_max); map_y_0++, c_y += map_c_dy) {

        HandlePendingEvents(app_context);
        if (interrupt_drawing_now) {
            if (image)
               DestroyImage(image);
            if (image_info)
               DestroyImageInfo(image_info);
            // Update to screen
            (void)XCopyArea(XtDisplay(da),
                pixmap,
                XtWindow(da),
                gc,
                0,
                0,
                (unsigned int)screen_width,
                (unsigned int)screen_height,
                0,
                0);
            DestroyExceptionInfo(&exception);
            return;
        }

        scr_y = (c_y - NW_corner_latitude) / scale_y;
        if (scr_y != scr_yp) {                  // don't do a row twice
            scr_yp = scr_y;                     // remember as previous y
            scr_xp = -1;
            // loop over map pixel columns
            map_act = 0;
            scale_x_nm = calc_dscale_x(0,(long)c_y) / 1852.0;  // nm per Xastir coordinate
            for (map_x = map_x_min, c_x = (double)c_x_min; map_x <= map_x_max; map_x++, c_x += c_dx) {
                scr_x = (c_x - NW_corner_longitude) / scale_x;
                if (scr_x != scr_xp) {      // don't do a pixel twice
                    scr_xp = scr_x;         // remember as previous x
                    map_y = map_y_0;

                    if (map_y >= 0 && map_y <= tp[1].img_y) { // check map boundaries in y direction
                        map_seen = 1;
                        map_act = 1;    // detects blank screen rows (end of map)

                        // now copy a pixel from the map image to the screen
                        l = map_x + map_y * image->columns;
                        if (image->storage_class == PseudoClass) {
                            XSetForeground(XtDisplay(w), gc, my_colors[index_pack[l]].pixel);
                        }
                        else {
                            // It is not safe to assume that the red/green/blue
                            // elements of pixel_pack of type Quantum are the
                            // same as the red/green/blue of an XColor!
                            if (QuantumDepth==16) {
                                my_colors[0].red=pixel_pack[l].red;
                                my_colors[0].green=pixel_pack[l].green;
                                my_colors[0].blue=pixel_pack[l].blue;
                            }
                            else { // QuantumDepth=8
                                // shift the bits of the 8-bit quantity so that
                                // they become the high bigs of my_colors.*
                                my_colors[0].red=pixel_pack[l].red<<8;
                                my_colors[0].green=pixel_pack[l].green<<8;
                                my_colors[0].blue=pixel_pack[l].blue<<8;
                            }
                            // NOW my_colors has the right r,g,b range for
                            // pack_pixel_bits
                            pack_pixel_bits(my_colors[0].red * raster_map_intensity,
                                            my_colors[0].green * raster_map_intensity,
                                            my_colors[0].blue * raster_map_intensity,
                                            &my_colors[0].pixel);
                            XSetForeground(XtDisplay(w), gc, my_colors[0].pixel);
                        }
                        (void)XFillRectangle (XtDisplay (w),pixmap,gc,scr_x,scr_y,scr_dx,scr_dy);
                    } // check map boundaries in y direction
                }
            } // loop over map pixel columns
            if (map_seen && !map_act)
                map_done = 1;
        }
    } // loop over map pixel rows

    if (image)
       DestroyImage(image);
    if (image_info)
       DestroyImageInfo(image_info);
    DestroyExceptionInfo(&exception);
}
示例#13
0
MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file,
        const MagickBooleanType verbose)
{
    char
    color[MaxTextExtent],
          format[MaxTextExtent],
          key[MaxTextExtent];

    ChannelFeatures
    *channel_features;

    ChannelStatistics
    *channel_statistics;

    ColorspaceType
    colorspace;

    const char
    *artifact,
    *name,
    *property,
    *registry,
    *value;

    const MagickInfo
    *magick_info;

    const PixelPacket
    *pixels;

    double
    elapsed_time,
    user_time;

    ExceptionInfo
    *exception;

    ImageType
    type;

    ssize_t
    y;

    MagickBooleanType
    ping;

    register ssize_t
    i,
    x;

    size_t
    distance,
    scale;

    assert(image != (Image *) NULL);
    assert(image->signature == MagickSignature);
    if (image->debug != MagickFalse)
        (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    if (file == (FILE *) NULL)
        file=stdout;
    *format='\0';
    elapsed_time=GetElapsedTime(&image->timer);
    user_time=GetUserTime(&image->timer);
    GetTimerInfo(&image->timer);
    if (verbose == MagickFalse)
    {
        /*
          Display summary info about the image.
        */
        if (*image->magick_filename != '\0')
            if (LocaleCompare(image->magick_filename,image->filename) != 0)
                (void) fprintf(file,"%s=>",image->magick_filename);
        if ((GetPreviousImageInList(image) == (Image *) NULL) &&
                (GetNextImageInList(image) == (Image *) NULL) &&
                (image->scene == 0))
            (void) fprintf(file,"%s ",image->filename);
        else
            (void) fprintf(file,"%s[%.20g] ",image->filename,(double) image->scene);
        (void) fprintf(file,"%s ",image->magick);
        if ((image->magick_columns != 0) || (image->magick_rows != 0))
            if ((image->magick_columns != image->columns) ||
                    (image->magick_rows != image->rows))
                (void) fprintf(file,"%.20gx%.20g=>",(double) image->magick_columns,
                               (double) image->magick_rows);
        (void) fprintf(file,"%.20gx%.20g ",(double) image->columns,(double)
                       image->rows);
        if ((image->page.width != 0) || (image->page.height != 0) ||
                (image->page.x != 0) || (image->page.y != 0))
            (void) fprintf(file,"%.20gx%.20g%+.20g%+.20g ",(double)
                           image->page.width,(double) image->page.height,(double) image->page.x,
                           (double) image->page.y);
        (void) fprintf(file,"%.20g-bit ",(double) image->depth);
        if (image->type != UndefinedType)
            (void) fprintf(file,"%s ",MagickOptionToMnemonic(MagickTypeOptions,
                           (ssize_t) image->type));
        if (image->storage_class == DirectClass)
        {
            (void) fprintf(file,"DirectClass ");
            if (image->total_colors != 0)
            {
                (void) FormatMagickSize(image->total_colors,MagickFalse,format);
                (void) fprintf(file,"%s ",format);
            }
        }
        else if (image->total_colors <= image->colors)
            (void) fprintf(file,"PseudoClass %.20gc ",(double) image->colors);
        else
            (void) fprintf(file,"PseudoClass %.20g=>%.20gc ",(double)
                           image->total_colors,(double) image->colors);
        if (image->error.mean_error_per_pixel != 0.0)
            (void) fprintf(file,"%.20g/%f/%fdb ",(double)
                           (image->error.mean_error_per_pixel+0.5),
                           image->error.normalized_mean_error,
                           image->error.normalized_maximum_error);
        if (GetBlobSize(image) != 0)
        {
            (void) FormatMagickSize(GetBlobSize(image),MagickFalse,format);
            (void) fprintf(file,"%sB ",format);
        }
        (void) fprintf(file,"%0.3fu %lu:%02lu.%03lu",user_time,(unsigned long)
                       (elapsed_time/60.0),(unsigned long) floor(fmod(elapsed_time,60.0)),
                       (unsigned long) (1000.0*(elapsed_time-floor(elapsed_time))));
        (void) fprintf(file,"\n");
        (void) fflush(file);
        return(ferror(file) != 0 ? MagickFalse : MagickTrue);
    }
    /*
      Display verbose info about the image.
    */
    exception=AcquireExceptionInfo();
    pixels=GetVirtualPixels(image,0,0,1,1,exception);
    exception=DestroyExceptionInfo(exception);
    ping=pixels == (const PixelPacket *) NULL ? MagickTrue : MagickFalse;
    type=GetImageType(image,&image->exception);
    (void) SignatureImage(image);
    (void) fprintf(file,"Image: %s\n",image->filename);
    if (*image->magick_filename != '\0')
        if (LocaleCompare(image->magick_filename,image->filename) != 0)
        {
            char
            filename[MaxTextExtent];

            GetPathComponent(image->magick_filename,TailPath,filename);
            (void) fprintf(file,"  Base filename: %s\n",filename);
        }
    magick_info=GetMagickInfo(image->magick,&image->exception);
    if ((magick_info == (const MagickInfo *) NULL) ||
            (*GetMagickDescription(magick_info) == '\0'))
        (void) fprintf(file,"  Format: %s\n",image->magick);
    else
        (void) fprintf(file,"  Format: %s (%s)\n",image->magick,
                       GetMagickDescription(magick_info));
    (void) fprintf(file,"  Class: %s\n",MagickOptionToMnemonic(MagickClassOptions,
                   (ssize_t) image->storage_class));
    (void) fprintf(file,"  Geometry: %.20gx%.20g%+.20g%+.20g\n",(double)
                   image->columns,(double) image->rows,(double) image->tile_offset.x,(double)
                   image->tile_offset.y);
    if ((image->magick_columns != 0) || (image->magick_rows != 0))
        if ((image->magick_columns != image->columns) ||
                (image->magick_rows != image->rows))
            (void) fprintf(file,"  Base geometry: %.20gx%.20g\n",(double)
                           image->magick_columns,(double) image->magick_rows);
    if ((image->x_resolution != 0.0) && (image->y_resolution != 0.0))
    {
        (void) fprintf(file,"  Resolution: %gx%g\n",image->x_resolution,
                       image->y_resolution);
        (void) fprintf(file,"  Print size: %gx%g\n",(double) image->columns/
                       image->x_resolution,(double) image->rows/image->y_resolution);
    }
    (void) fprintf(file,"  Units: %s\n",MagickOptionToMnemonic(
                       MagickResolutionOptions,(ssize_t) image->units));
    (void) fprintf(file,"  Type: %s\n",MagickOptionToMnemonic(MagickTypeOptions,
                   (ssize_t) type));
    if (image->type != UndefinedType)
        (void) fprintf(file,"  Base type: %s\n",MagickOptionToMnemonic(
                           MagickTypeOptions,(ssize_t) image->type));
    (void) fprintf(file,"  Endianess: %s\n",MagickOptionToMnemonic(
                       MagickEndianOptions,(ssize_t) image->endian));
    /*
      Detail channel depth and extrema.
    */
    (void) fprintf(file,"  Colorspace: %s\n",MagickOptionToMnemonic(
                       MagickColorspaceOptions,(ssize_t) image->colorspace));
    channel_statistics=(ChannelStatistics *) NULL;
    channel_features=(ChannelFeatures *) NULL;
    colorspace=image->colorspace;
    if (ping == MagickFalse)
    {
        size_t
        depth;

        channel_statistics=GetImageChannelStatistics(image,&image->exception);
        artifact=GetImageArtifact(image,"identify:features");
        if (artifact != (const char *) NULL)
        {
            distance=StringToUnsignedLong(artifact);
            channel_features=GetImageChannelFeatures(image,distance,
                             &image->exception);
        }
        depth=GetImageDepth(image,&image->exception);
        if (image->depth == depth)
            (void) fprintf(file,"  Depth: %.20g-bit\n",(double) image->depth);
        else
            (void) fprintf(file,"  Depth: %.20g/%.20g-bit\n",(double)
                           image->depth,(double) depth);
        (void) fprintf(file,"  Channel depth:\n");
        if (IsGrayImage(image,&image->exception) != MagickFalse)
            colorspace=GRAYColorspace;
        switch (colorspace)
        {
        case RGBColorspace:
        default:
        {
            (void) fprintf(file,"    red: %.20g-bit\n",(double)
                           channel_statistics[RedChannel].depth);
            (void) fprintf(file,"    green: %.20g-bit\n",(double)
                           channel_statistics[GreenChannel].depth);
            (void) fprintf(file,"    blue: %.20g-bit\n",(double)
                           channel_statistics[BlueChannel].depth);
            break;
        }
        case CMYKColorspace:
        {
            (void) fprintf(file,"    cyan: %.20g-bit\n",(double)
                           channel_statistics[CyanChannel].depth);
            (void) fprintf(file,"    magenta: %.20g-bit\n",(double)
                           channel_statistics[MagentaChannel].depth);
            (void) fprintf(file,"    yellow: %.20g-bit\n",(double)
                           channel_statistics[YellowChannel].depth);
            (void) fprintf(file,"    black: %.20g-bit\n",(double)
                           channel_statistics[BlackChannel].depth);
            break;
        }
        case GRAYColorspace:
        {
            (void) fprintf(file,"    gray: %.20g-bit\n",(double)
                           channel_statistics[GrayChannel].depth);
            break;
        }
        }
        if (image->matte != MagickFalse)
            (void) fprintf(file,"    alpha: %.20g-bit\n",(double)
                           channel_statistics[OpacityChannel].depth);
        scale=1;
        if (image->depth <= MAGICKCORE_QUANTUM_DEPTH)
            scale=QuantumRange/((size_t) QuantumRange >> ((size_t)
                                MAGICKCORE_QUANTUM_DEPTH-image->depth));
    }
示例#14
0
static Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
#define MaxBufferExtent  8192

  char
    filename[MaxTextExtent];

  FILE
    *file;

  Image
    *image;

  ImageInfo
    *read_info;

  int
    unique_file;

  image=(Image *) NULL;
  read_info=CloneImageInfo(image_info);
  SetImageInfoBlob(read_info,(void *) NULL,0);
  file=(FILE *) NULL;
  unique_file=AcquireUniqueFileResource(read_info->filename);
  if (unique_file != -1)
    file=fdopen(unique_file,"wb");
  if ((unique_file == -1) || (file == (FILE *) NULL))
    {
      ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
        read_info->filename);
      read_info=DestroyImageInfo(read_info);
      return((Image *) NULL);
    }
  (void) CopyMagickString(filename,image_info->magick,MaxTextExtent);
  (void) ConcatenateMagickString(filename,":",MaxTextExtent);
  LocaleLower(filename);
  (void) ConcatenateMagickString(filename,image_info->filename,MaxTextExtent);
  if (LocaleCompare(read_info->magick,"file") == 0)
    {
      (void) RelinquishUniqueFileResource(read_info->filename);
      unique_file=(-1);
      (void) CopyMagickString(read_info->filename,image_info->filename+2,
        MaxTextExtent);
    }
#if defined(MAGICKCORE_WINDOWS_SUPPORT) && \
    !(defined(__MINGW32__) || defined(__MINGW64__))
  (void) fclose(file);
  if (URLDownloadToFile(NULL,filename,read_info->filename,0,NULL) != S_OK)
    {
      ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
        filename);
      (void) RelinquishUniqueFileResource(read_info->filename);
      read_info=DestroyImageInfo(read_info);
      return((Image *) NULL);
    }
#else
#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED)
  if (LocaleCompare(read_info->magick,"ftp") == 0)
    {
      void
        *context;

      xmlNanoFTPInit();
      context=xmlNanoFTPNewCtxt(filename);
      if (context != (void *) NULL)
        {
          if (xmlNanoFTPConnect(context) >= 0)
            (void) xmlNanoFTPGet(context,GetFTPData,(void *) file,
              (char *) NULL);
          (void) xmlNanoFTPClose(context);
        }
    }
#endif
#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_HTTP_ENABLED)
  if (LocaleCompare(read_info->magick,"http") == 0)
    {
      char
        buffer[MaxBufferExtent],
        *type;

      int
        bytes;

      void
        *context;

      type=(char *) NULL;
      context=xmlNanoHTTPMethod(filename,(const char *) NULL,
        (const char *) NULL,&type,(const char *) NULL,0);
      if (context != (void *) NULL)
        {
          ssize_t
            count;

          while ((bytes=xmlNanoHTTPRead(context,buffer,MaxBufferExtent)) > 0)
            count=(ssize_t) fwrite(buffer,bytes,1,file);
          (void) count;
          xmlNanoHTTPClose(context);
          xmlFree(type);
          xmlNanoHTTPCleanup();
        }
    }
#endif
  (void) fclose(file);
#endif
  {
    ExceptionInfo
      *sans;

    ImageInfo
      *clone_info;

    /*
      Guess image format from URL.
    */
    clone_info=CloneImageInfo(image_info);
    sans=AcquireExceptionInfo();
    (void) SetImageInfo(clone_info,0,sans);
    (void) CopyMagickString(read_info->magick,clone_info->magick,MaxTextExtent);
    clone_info=DestroyImageInfo(clone_info);
    sans=DestroyExceptionInfo(sans);
  }
  image=ReadImage(read_info,exception);
  if (unique_file != -1)
    (void) RelinquishUniqueFileResource(read_info->filename);
  read_info=DestroyImageInfo(read_info);
  if (image != (Image *) NULL)
    GetPathComponent(image_info->filename,TailPath,image->filename);
  else
    {
      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
        "NoDataReturned","`%s'",filename);
      return((Image *) NULL);
    }
  return(GetFirstImageInList(image));
}
示例#15
0
文件: imgmin.c 项目: dpq/imgmin
/*
 * given a source image, a destination filepath and a set of image metadata thresholds,
 * search for the lowest-quality version of the source image whose properties fall within our
 * thresholds.
 * this will produce an image file that looks the same to the casual observer, but which
 * contains much less information and results in a smaller file.
 * typical savings on unoptimized images vary widely from 10-80%, with 25-50% being most common.
 */
MagickWand * search_quality(MagickWand *mw, const char *dst,
                                   const struct imgmin_options *opt)
{
    MagickWand *tmp = NULL;
    char tmpfile[MAX_PATH] = "/tmp/imgminXXXXXX";
    if (0 == strcmp("-", dst))
    {
        if (-1 == mkstemp(tmpfile))
        {
            perror("mkstemp");
            return CloneMagickWand(mw);
        }
    } else {
        strcpy(tmpfile, dst);
    }

    /*
     * The overwhelming majority of JPEGs are TrueColorType; it is those types, with a low
     * unique color count, that we must avoid.
     */
    if (!enough_colors(mw, opt))
    {
        fprintf(stdout, " Color count is too low, skipping...\n");
        return CloneMagickWand(mw);
    }

    if (quality(mw) < opt->quality_in_min)
    {
        fprintf(stdout, " Quality < %u, won't second-guess...\n", opt->quality_in_min);
        return CloneMagickWand(mw);
    }

    size_t width = MagickGetImageWidth(mw);
    size_t height = MagickGetImageHeight(mw);

    dssim_info *dssim = dssim_init(1);

    void *convert_data = convert_row_start(mw);
    dssim_set_original_float_callback(dssim, width, height, convert_row_callback, convert_data);
    convert_row_finish(convert_data);

    {
        ExceptionInfo *exception = AcquireExceptionInfo();

        const double original_density = color_density(mw);
        unsigned qmax = min(quality(mw), opt->quality_out_max);
        unsigned qmin = opt->quality_out_min;
        unsigned steps = 0;

        /*
         * binary search of quality space for optimally lowest quality that
         * produces an acceptable level of distortion
         */
        while (qmax > qmin + 1 && steps < opt->max_steps)
        {
            double density_ratio;
            unsigned q;

            steps++;
            q = (qmax + qmin) / 2;

            /* change quality */
            tmp = CloneMagickWand(mw);
            MagickSetImageCompressionQuality(tmp, q);

            /* apply quality change */
            MagickWriteImages(tmp, tmpfile, MagickTrue);
            DestroyMagickWand(tmp);
            tmp = NewMagickWand();
            MagickReadImage(tmp, tmpfile);

            void *convert_data = convert_row_start(tmp);
            dssim_set_modified_float_callback(dssim, width, height, convert_row_callback, convert_data);
            convert_row_finish(convert_data);

            double error = 20.0 * dssim_compare(dssim, NULL); // scaled to threshold of previous implementation

            density_ratio = fabs(color_density(tmp) - original_density) / original_density;

            /* color density ratio threshold is an alternative quality measure.
               If it's exceeded, pretend MSE was higher to increase quality */
            if (density_ratio > opt->color_density_ratio) {
                error *= 1.25 + density_ratio; // fudge factor
            }

            /* eliminate half search space based on whether distortion within thresholds */
            if (error > opt->error_threshold)
            {
                qmin = q;
            } else {
                qmax = q;
            }
            if (opt->show_progress)
            {
                fprintf(stdout, "%.2f/%.2f@%u ", error, density_ratio, q);
            }

            /* Stop searching if close enough to the target */
            if (fabs(error - opt->error_threshold) < opt->error_threshold * ERROR_THRESHOLD_INACCURACY) {
                qmax = q;
                break;
            }
        }
        if (opt->show_progress)
        {
            putc('\n', stdout);
        }

        MagickSetImageCompressionQuality(mw, qmax);

        /* "Chroma sub-sampling works because human vision is relatively insensitive to
         * small areas of colour. It gives a significant reduction in file sizes, with
         * little loss of perceived quality." [3]
         */
#if MagickLibVersion >= 0x630 /* FIXME: available in 0x660, not available in 0x628, not sure which version it was introduced in */
        (void) MagickSetImageProperty(mw, "jpeg:sampling-factor", "2x2");
#endif

        /* strip an image of all profiles and comments */
        (void) MagickStripImage(mw);

        MagickWriteImages(mw, tmpfile, MagickTrue);
        (void) DestroyMagickWand(tmp);
        tmp = NewMagickWand();
        MagickReadImage(tmp, tmpfile);

        exception = DestroyExceptionInfo(exception);
    }

    return tmp;
}
示例#16
0
/**
 * Write all the images to the specified file. If the file format supports
 * multi-image files, and the 'images' array contains more than one image, then
 * the images will be written as a single multi-image file. Otherwise each image
 * will be written to a separate file.
 *
 * Ruby usage:
 *   - @verbatim ImageList#write(file) @endverbatim
 *
 * @param self this object
 * @param file the file
 * @return self
 */
VALUE
ImageList_write(VALUE self, VALUE file)
{
    Image *images, *img;
    Info *info;
    const MagickInfo *m;
    VALUE info_obj;
    unsigned long scene;
    ExceptionInfo *exception;

    info_obj = rm_info_new();
    Data_Get_Struct(info_obj, Info, info);


    if (TYPE(file) == T_FILE)
    {
        OpenFile *fptr;

        // Ensure file is open - raise error if not
        GetOpenFile(file, fptr);
#if defined(_WIN32)
        add_format_prefix(info, fptr->pathv);
        SetImageInfoFile(info, NULL);
#else
        SetImageInfoFile(info, GetReadFile(fptr));
#endif
    }
    else
    {
        add_format_prefix(info, file);
        SetImageInfoFile(info, NULL);
    }

    // Convert the images array to an images sequence.
    images = images_from_imagelist(self);

    // Copy the filename into each image. Set a scene number to be used if
    // writing multiple files. (Ref: ImageMagick's utilities/convert.c
    for (scene = 0, img = images; img; img = GetNextImageInList(img))
    {
        img->scene = scene++;
        strcpy(img->filename, info->filename);
    }

    // Find out if the format supports multi-images files.
    exception = AcquireExceptionInfo();
    (void) SetImageInfo(info, MagickTrue, exception);
    rm_check_exception(exception, images, RetainOnError);

    m = GetMagickInfo(info->magick, exception);
    rm_check_exception(exception, images, RetainOnError);
    (void) DestroyExceptionInfo(exception);

    // Tell WriteImage if we want a multi-images file.
    if (imagelist_length(self) > 1L && m->adjoin)
    {
        info->adjoin = MagickTrue;
    }

    for (img = images; img; img = GetNextImageInList(img))
    {
        rm_sync_image_options(img, info);
        (void) WriteImage(info, img);
        // images will be split before raising an exception
        rm_check_image_exception(images, RetainOnError);
        if (info->adjoin)
        {
            break;
        }
    }

    rm_split(images);

    RB_GC_GUARD(info_obj);

    return self;
}
示例#17
0
/**
 * Equivalent to -layers option in ImageMagick 6.2.6.
 *
 * Ruby usage:
 *   - @verbatim ImageList#optimize_layers(method) @endverbatim
 *
 * @param self this object
 * @param method the method to use
 * @return a new imagelist
 */
VALUE
ImageList_optimize_layers(VALUE self, VALUE method)
{
    Image *images, *new_images, *new_images2;
    LAYERMETHODTYPE mthd;
    ExceptionInfo *exception;
    QuantizeInfo quantize_info;

    new_images2 = NULL;     // defeat "unused variable" message

    exception = AcquireExceptionInfo();
#if defined(HAVE_TYPE_IMAGELAYERMETHOD)
    VALUE_TO_ENUM(method, mthd, ImageLayerMethod);
#else
    VALUE_TO_ENUM(method, mthd, MagickLayerMethod);
#endif
    images = images_from_imagelist(self);

    switch (mthd)
    {
        case CoalesceLayer:
            new_images = CoalesceImages(images, exception);
            break;
        case DisposeLayer:
            new_images = DisposeImages(images, exception);
            break;
        case OptimizeTransLayer:
            new_images = clone_imagelist(images);
            OptimizeImageTransparency(new_images, exception);
            break;
        case RemoveDupsLayer:
            new_images = clone_imagelist(images);
            RemoveDuplicateLayers(&new_images, exception);
            break;
        case RemoveZeroLayer:
            new_images = clone_imagelist(images);
            RemoveZeroDelayLayers(&new_images, exception);
            break;
        case CompositeLayer:
            rm_split(images);
            rb_raise(rb_eNotImpError, "Magick::CompositeLayer is not supported. Use the composite_layers method instead.");
            break;
            // In 6.3.4-ish, OptimizeImageLayer replaced OptimizeLayer
        case OptimizeImageLayer:
            new_images = OptimizeImageLayers(images, exception);
            break;
            // and OptimizeLayer became a "General Purpose, GIF Animation Optimizer" (ref. mogrify.c)
        case OptimizeLayer:
            new_images = CoalesceImages(images, exception);
            rm_split(images);
            rm_check_exception(exception, new_images, DestroyOnError);
            new_images2 = OptimizeImageLayers(new_images, exception);
            DestroyImageList(new_images);
            rm_check_exception(exception, new_images2, DestroyOnError);
            new_images = new_images2;
            OptimizeImageTransparency(new_images, exception);
            rm_check_exception(exception, new_images, DestroyOnError);
            // mogrify supports -dither here. We don't.
#if defined(HAVE_REMAPIMAGE)
            GetQuantizeInfo(&quantize_info);
            (void) RemapImages(&quantize_info, new_images, NULL);
#else
            (void) MapImages(new_images, NULL, 0);
#endif
            break;
        case OptimizePlusLayer:
            new_images = OptimizePlusImageLayers(images, exception);
            break;
        case CompareAnyLayer:
        case CompareClearLayer:
        case CompareOverlayLayer:
            new_images = CompareImageLayers(images, mthd, exception);
            break;
#if defined(HAVE_ENUM_MOSAICLAYER)
        case MosaicLayer:
            new_images = MergeImageLayers(images, mthd, exception);
            break;
#endif
#if defined(HAVE_ENUM_FLATTENLAYER)
        case FlattenLayer:
            new_images = MergeImageLayers(images, mthd, exception);
            break;
#endif
#if defined(HAVE_ENUM_MERGELAYER)
        case MergeLayer:
            new_images = MergeImageLayers(images, mthd, exception);
            break;
#endif
#if defined(HAVE_ENUM_TRIMBOUNDSLAYER)
        case TrimBoundsLayer:
            new_images = MergeImageLayers(images, mthd, exception);
            break;
#endif
        default:
            rm_split(images);
            rb_raise(rb_eArgError, "undefined layer method");
            break;
    }

    rm_split(images);
    rm_check_exception(exception, new_images, DestroyOnError);
    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_images);

    return rm_imagelist_from_images(new_images);
}
示例#18
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   G l o b E x p r e s s i o n                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GlobExpression() returns MagickTrue if the expression matches the pattern.
%
%  The format of the GlobExpression function is:
%
%      MagickBooleanType GlobExpression(const char *expression,
%        const char *pattern)
%
%  A description of each parameter follows:
%
%    o expression: Specifies a pointer to a text string containing a file name.
%
%    o pattern: Specifies a pointer to a text string containing a pattern.
%
%
*/
MagickExport MagickBooleanType GlobExpression(const char *expression,
  const char *pattern)
{
  MagickBooleanType
    done;

  register const char
    *p;

  /*
    Return on empty pattern or '*'.
  */
  if (pattern == (char *) NULL)
    return(MagickTrue);
  if (*pattern == '\0')
    return(MagickTrue);
  if (LocaleCompare(pattern,"*") == 0)
    return(MagickTrue);
  p=pattern+strlen(pattern)-1;
  if ((*p == ']') && (strchr(pattern,'[') != (char *) NULL))
    {
      ExceptionInfo
        exception;

      ImageInfo
        *image_info;

      /*
        Determine if pattern is a scene, i.e. img0001.pcd[2].
      */
      image_info=CloneImageInfo((ImageInfo *) NULL);
      (void) CopyMagickString(image_info->filename,pattern,MaxTextExtent);
      GetExceptionInfo(&exception);
      (void) SetImageInfo(image_info,MagickTrue,&exception);
      DestroyExceptionInfo(&exception);
      if (LocaleCompare(image_info->filename,pattern) != 0)
        {
          image_info=DestroyImageInfo(image_info);
          return(MagickFalse);
        }
      image_info=DestroyImageInfo(image_info);
    }
  /*
    Evaluate glob expression.
  */
  done=MagickFalse;
  while ((*pattern != '\0') && (done == MagickFalse))
  {
    if (*expression == '\0')
      if ((*pattern != '{') && (*pattern != '*'))
        break;
    switch (*pattern)
    {
      case '\\':
      {
        pattern++;
        if (*pattern != '\0')
          pattern++;
        break;
      }
      case '*':
      {
        MagickBooleanType
          status;

        pattern++;
        status=MagickFalse;
        while ((*expression != '\0') && (status == MagickFalse))
          status=GlobExpression(expression++,pattern);
        if (status != MagickFalse)
          {
            while (*expression != '\0')
              expression++;
            while (*pattern != '\0')
              pattern++;
          }
        break;
      }
      case '[':
      {
        char
          c;

        pattern++;
        for ( ; ; )
        {
          if ((*pattern == '\0') || (*pattern == ']'))
            {
              done=MagickTrue;
              break;
            }
          if (*pattern == '\\')
            {
              pattern++;
              if (*pattern == '\0')
                {
                  done=MagickTrue;
                  break;
                }
             }
          if (*(pattern+1) == '-')
            {
              c=(*pattern);
              pattern+=2;
              if (*pattern == ']')
                {
                  done=MagickTrue;
                  break;
                }
              if (*pattern == '\\')
                {
                  pattern++;
                  if (*pattern == '\0')
                    {
                      done=MagickTrue;
                      break;
                    }
                }
              if ((*expression < c) || (*expression > *pattern))
                {
                  pattern++;
                  continue;
                }
            }
          else
            if (*pattern != *expression)
              {
                pattern++;
                continue;
              }
          pattern++;
          while ((*pattern != ']') && (*pattern != '\0'))
          {
            if ((*pattern == '\\') && (*(pattern+1) != '\0'))
              pattern++;
            pattern++;
          }
          if (*pattern != '\0')
            {
              pattern++;
              expression++;
            }
          break;
        }
        break;
      }
      case '?':
      {
        pattern++;
        expression++;
        break;
      }
      case '{':
      {
        MagickBooleanType
          match;

        register const char
          *p;

        pattern++;
        while ((*pattern != '}') && (*pattern != '\0'))
        {
          p=expression;
          match=MagickTrue;
          while ((*p != '\0') && (*pattern != '\0') &&
                 (*pattern != ',') && (*pattern != '}') &&
                 (match != MagickFalse))
          {
            if (*pattern == '\\')
              pattern++;
            match=(MagickBooleanType) (*pattern == *p);
            p++;
            pattern++;
          }
          if (*pattern == '\0')
            {
              match=MagickFalse;
              done=MagickTrue;
              break;
            }
          else
            if (match != MagickFalse)
              {
                expression=p;
                while ((*pattern != '}') && (*pattern != '\0'))
                {
                  pattern++;
                  if (*pattern == '\\')
                    {
                      pattern++;
                      if (*pattern == '}')
                        pattern++;
                    }
                }
              }
            else
              {
                while ((*pattern != '}') && (*pattern != ',') &&
                       (*pattern != '\0'))
                {
                  pattern++;
                  if (*pattern == '\\')
                    {
                      pattern++;
                      if ((*pattern == '}') || (*pattern == ','))
                        pattern++;
                    }
                }
              }
            if (*pattern != '\0')
              pattern++;
          }
        break;
      }
      default:
      {
        if (*expression != *pattern)
          done=MagickTrue;
        else
          {
            expression++;
            pattern++;
          }
      }
    }
  }
  while (*pattern == '*')
    pattern++;
  return((MagickBooleanType) ((*expression == '\0') && (*pattern == '\0')));
}
示例#19
0
Tagimage::~Tagimage()
{
	DestroyImage(image);
	DestroyExceptionInfo(&exception);
}
示例#20
0
// load a full-res thumbnail:
int dt_imageio_large_thumbnail(const char *filename, uint8_t **buffer, int32_t *width, int32_t *height,
                               dt_colorspaces_color_profile_type_t *color_space)
{
  int res = 1;

  uint8_t *buf = NULL;
  char *mime_type = NULL;
  size_t bufsize;

  // get the biggest thumb from exif
  if(dt_exif_get_thumbnail(filename, &buf, &bufsize, &mime_type)) goto error;

  if(strcmp(mime_type, "image/jpeg") == 0)
  {
    // Decompress the JPG into our own memory format
    dt_imageio_jpeg_t jpg;
    if(dt_imageio_jpeg_decompress_header(buf, bufsize, &jpg)) goto error;
    *buffer = (uint8_t *)malloc((size_t)sizeof(uint8_t) * jpg.width * jpg.height * 4);
    if(!*buffer) goto error;

    *width = jpg.width;
    *height = jpg.height;
    // TODO: check if the embedded thumbs have a color space set! currently we assume that it's always sRGB
    *color_space = DT_COLORSPACE_SRGB;
    if(dt_imageio_jpeg_decompress(&jpg, *buffer))
    {
      free(*buffer);
      *buffer = NULL;
      goto error;
    }

    res = 0;
  }
  else
  {
#ifdef HAVE_GRAPHICSMAGICK
    ExceptionInfo exception;
    Image *image = NULL;
    ImageInfo *image_info = NULL;

    GetExceptionInfo(&exception);
    image_info = CloneImageInfo((ImageInfo *)NULL);

    image = BlobToImage(image_info, buf, bufsize, &exception);

    if(exception.severity != UndefinedException) CatchException(&exception);

    if(!image)
    {
      fprintf(stderr, "[dt_imageio_large_thumbnail GM] thumbnail not found?\n");
      goto error_gm;
    }

    *width = image->columns;
    *height = image->rows;
    *color_space = DT_COLORSPACE_SRGB; // FIXME: this assumes that embedded thumbnails are always srgb

    *buffer = (uint8_t *)malloc((size_t)sizeof(uint8_t) * image->columns * image->rows * 4);
    if(!*buffer) goto error_gm;

    for(uint32_t row = 0; row < image->rows; row++)
    {
      uint8_t *bufprt = *buffer + (size_t)4 * row * image->columns;
      int gm_ret = DispatchImage(image, 0, row, image->columns, 1, "RGBP", CharPixel, bufprt, &exception);

      if(exception.severity != UndefinedException) CatchException(&exception);

      if(gm_ret != MagickPass)
      {
        fprintf(stderr, "[dt_imageio_large_thumbnail GM] error_gm reading thumbnail\n");
        free(*buffer);
        *buffer = NULL;
        goto error_gm;
      }
    }

    // fprintf(stderr, "[dt_imageio_large_thumbnail GM] successfully decoded thumbnail\n");
    res = 0;

  error_gm:
    if(image) DestroyImage(image);
    if(image_info) DestroyImageInfo(image_info);
    DestroyExceptionInfo(&exception);
    if(res) goto error;
#else
    fprintf(stderr, "[dt_imageio_large_thumbnail] error: The thumbnail image is not in JPEG format, but DT "
                    "was built without GraphicsMagick. Please rebuild DT with GraphicsMagick support "
                    "enabled.\n");
#endif
  }

  if(res)
  {
    fprintf(
        stderr,
        "[dt_imageio_large_thumbnail] error: Not a supported thumbnail image format or broken thumbnail: %s\n",
        mime_type);
    goto error;
  }

error:
  free(mime_type);
  free(buf);
  return res;
}
示例#21
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e I m a g e s                                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteImages() writes an image sequence into one or more files.  While
%  WriteImage() can write an image sequence, it is limited to writing
%  the sequence into a single file using a format which supports multiple
%  frames.   WriteImages(), however, does not have this limitation, instead it
%  generates multiple output files if necessary (or when requested).  When
%  ImageInfo's adjoin flag is set to MagickFalse, the file name is expected
%  to include a printf-style formatting string for the frame number (e.g.
%  "image%02d.png").
%
%  The format of the WriteImages method is:
%
%      MagickBooleanType WriteImages(const ImageInfo *image_info,Image *images,
%        const char *filename,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o images: the image list.
%
%    o filename: the image filename.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType WriteImages(const ImageInfo *image_info,
  Image *images,const char *filename,ExceptionInfo *exception)
{
#define WriteImageTag  "Write/Image"

  BlobInfo
    *blob;

  ExceptionInfo
    *sans_exception;

  ImageInfo
    *write_info;

  MagickBooleanType
    proceed;

  MagickOffsetType
    i;

  MagickProgressMonitor
    progress_monitor;

  MagickSizeType
    number_images;

  MagickStatusType
    status;

  register Image
    *p;

  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(images != (Image *) NULL);
  assert(images->signature == MagickSignature);
  if (images->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
  assert(exception != (ExceptionInfo *) NULL);
  write_info=CloneImageInfo(image_info);
  images=GetFirstImageInList(images);
  blob=CloneBlobInfo(images->blob);  /* thread specific I/O handler */
  DestroyBlob(images);
  images->blob=blob;
  if (filename != (const char *) NULL)
    for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
      (void) CopyMagickString(p->filename,filename,MaxTextExtent);
  (void) CopyMagickString(write_info->filename,images->filename,MaxTextExtent);
  if (*write_info->magick == '\0')
    (void) CopyMagickString(write_info->magick,images->magick,MaxTextExtent);
  sans_exception=AcquireExceptionInfo();
  (void) SetImageInfo(write_info,(unsigned int) GetImageListLength(images),
    sans_exception);
  sans_exception=DestroyExceptionInfo(sans_exception);
  p=images;
  for ( ; GetNextImageInList(p) != (Image *) NULL; p=GetNextImageInList(p))
    if (p->scene >= GetNextImageInList(p)->scene)
      {
        register ssize_t
          i;

        /*
          Generate consistent scene numbers.
        */
        i=(ssize_t) images->scene;
        for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
          p->scene=(size_t) i++;
        break;
      }
  /*
    Write images.
  */
  status=MagickTrue;
  progress_monitor=(MagickProgressMonitor) NULL;
  i=0;
  number_images=GetImageListLength(images);
  for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
  {
    if (number_images != 1)
      progress_monitor=SetImageProgressMonitor(p,(MagickProgressMonitor) NULL,
        p->client_data);
    status&=WriteImage(write_info,p,exception);
    if (number_images != 1)
      (void) SetImageProgressMonitor(p,progress_monitor,p->client_data);
    if (write_info->adjoin != MagickFalse)
      break;
    if (number_images != 1)
      {
        proceed=SetImageProgress(p,WriteImageTag,i++,number_images);
        if (proceed == MagickFalse)
          break;
      }
  }
  write_info=DestroyImageInfo(write_info);
  return(status != 0 ? MagickTrue : MagickFalse);
}
示例#22
0
std::string
imageproc::ChangeImage(const std::string & inPath,
                       const std::string & tmpDir,
                       Type outputFormat,
                       const bp::List & transformations,
                       int quality,
                       unsigned int & x, unsigned int & y, 
                       unsigned int & orig_x, unsigned int & orig_y, 
                       std::string & oError)
{
    ExceptionInfo exception;
    Image *images;
    ImageInfo *image_info;

    orig_x = orig_y = x = y = 0;
    
    GetExceptionInfo(&exception);
    image_info = CloneImageInfo((ImageInfo *) NULL);

    // first we read the image
    if (exception.severity != UndefinedException)
    {
		if (exception.reason)
            g_bpCoreFunctions->log(BP_ERROR, "after: %s\n",
                                   exception.reason);
		if (exception.description)
            g_bpCoreFunctions->log(BP_ERROR, "after: %s\n",
                                   exception.description);
		CatchException(&exception);
    }


	(void) strcpy(image_info->filename, inPath.c_str());
    images = IP_ReadImageFile(image_info, inPath, &exception);
    
    if (exception.severity != UndefinedException)
    {
		if (exception.reason)
            g_bpCoreFunctions->log(BP_ERROR, "after: %s\n",
                                   exception.reason);
		if (exception.description)
            g_bpCoreFunctions->log(BP_ERROR, "after: %s\n",
                                   exception.description);
		CatchException(&exception);
    }
    
    if (!images)
    {
        oError.append("couldn't read image");
        DestroyImageInfo(image_info);
        image_info = NULL;
        DestroyExceptionInfo(&exception);
        return std::string();
    }

	g_bpCoreFunctions->log(
        BP_INFO, "Image contains %lu frames, type: %s\n",
        GetImageListLength(images),
        images->magick);

    // set quality
    if (quality > 100) quality = 100;
    if (quality < 0) quality = 0;
    image_info->quality = quality;

    g_bpCoreFunctions->log(
        BP_INFO, "Quality set to %d (0-100, worst-best)", quality);

    // execute 'actions' 
    images = runTransformations(images, transformations, quality, oError);

    // was all that successful?
    if (!images)
    {
        DestroyImageInfo(image_info);
        image_info = NULL;
        DestroyExceptionInfo(&exception);
        return std::string();
    } 

    // set the output size
    orig_x = images->magick_columns;
    orig_y = images->magick_rows;
    x = images->columns;
    y = images->rows;

    // let's set the output format correctly (default to input format)
    std::string name;
    if (outputFormat == UNKNOWN) name.append(ft::basename(inPath));
    else {
        name.append("img.");
        name.append(typeToExt(outputFormat));
        (void) sprintf(images->magick, outputFormat);
        g_bpCoreFunctions->log(BP_INFO, "Output to format: %s", outputFormat);
    }
    
    // Now let's go directly from blob to file.  We bypass
    // GM to-file functions so that we can handle wide filenames
    // safely on win32 systems.  A superior solution would
    // be to use GM stream facilities (if they exist)
    
    // upon success, will hold path to output file and will be returned to
    // client
    std::string rv;
    
    {
        size_t l = 0;
        void * blob = NULL;
        blob = ImageToBlob( image_info, images, &l, &exception );

        if (exception.severity != UndefinedException)
        {
            oError.append("ImageToBlob failed.");
            CatchException(&exception);
        }
        else
        {
            g_bpCoreFunctions->log(BP_INFO, "Writing %lu bytes to %s",
                                   l, name.c_str());

            if (!ft::mkdir(tmpDir, false)) {
                oError.append("Couldn't create temp dir");
            } else {
                std::string outpath = ft::getPath(tmpDir, name);
                FILE * f = ft::fopen_binary_write(outpath);
                if (f == NULL) { 
                    g_bpCoreFunctions->log(
                        BP_ERROR, "Couldn't open '%s' for writing!",
                        outpath.c_str());
                    oError.append("Error saving output image");
                } else {
                    size_t wt;
                    wt = fwrite(blob, sizeof(char), l, f);
                    fclose(f);

                    if (wt != l) {
                        g_bpCoreFunctions->log(
                            BP_ERROR,
                            "Partial write (%lu/%lu) when writing resultant "
                            "image '%s'",
                            wt, l, outpath.c_str());
                        oError.append("Error saving output image");
                    } else {
                        // success!
                        rv = outpath;
                    }
                }
            }
        }
    }
    
    DestroyImage(images);
    DestroyImageInfo(image_info);
    image_info = NULL;
    DestroyExceptionInfo(&exception);

    return rv;
}
示例#23
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d I m a g e s                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadImages() reads one or more images and returns them as an image list.
%
%  The format of the ReadImage method is:
%
%      Image *ReadImages(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.
%
*/
MagickExport Image *ReadImages(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  char
    filename[MaxTextExtent];

  Image
    *image,
    *images;

  ImageInfo
    *read_info;

  /*
    Read image list from a file.
  */
  assert(image_info != (ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  (void) InterpretImageFilename(image_info,(Image *) NULL,image_info->filename,
    (int) image_info->scene,filename,exception);
  if (LocaleCompare(filename,image_info->filename) != 0)
    {
      ExceptionInfo
        *sans;

      ssize_t
        extent,
        scene;

      /*
        Images of the form image-%d.png[1-5].
      */
      read_info=CloneImageInfo(image_info);
      sans=AcquireExceptionInfo();
      (void) SetImageInfo(read_info,0,sans);
      sans=DestroyExceptionInfo(sans);
      if (read_info->number_scenes == 0)
        {
          read_info=DestroyImageInfo(read_info);
          return(ReadImage(image_info,exception));
        }
      (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
      images=NewImageList();
      extent=(ssize_t) (read_info->scene+read_info->number_scenes);
      for (scene=(ssize_t) read_info->scene; scene < (ssize_t) extent; scene++)
      {
        (void) InterpretImageFilename(image_info,(Image *) NULL,filename,(int)
          scene,read_info->filename,exception);
        image=ReadImage(read_info,exception);
        if (image == (Image *) NULL)
          continue;
        AppendImageToList(&images,image);
      }
      read_info=DestroyImageInfo(read_info);
      return(images);
    }
  return(ReadImage(image_info,exception));
}
示例#24
0
/*----------------------------------------------------------
 * int_imread: 
 *     interface for imread function.
 *     should provide   [RGB]=imread(name) 
 *                [Index,Map]=imread(name) at Scilab level 
 *  
 * TO-DO
 *    - return on errors, even if exeption is NULL
 *
 * $Revision: 1.2 $ $Date: 2009-03-29 21:34:48 $
 *----------------------------------------------------------*/
SipExport int 
int_imread(char *fname) 
{
   /* Interface variables */ 
   HyperMat *Img;
   int   m1, n1,l1, /* for name input argument      */
         m2, n2,    /* for index output argument    */
         minlhs=1, maxlhs=2, minrhs=1, maxrhs=1, i;
   double *l2;

   /* Other variables */
   unsigned long  imgsize;
 
   /* ImageMagick variables */
   ExceptionInfo  exception;
   Image          *image;
   ImageInfo      *image_info;
   PixelPacket    *pix;
   ImageType      imgtype;

   bool stat;


   CheckRhs(minrhs,maxrhs) ;
   CheckLhs(minlhs,maxlhs) ;
 
   /* Get name (#1) */
   GetRhsVar(1, "c", &m1, &n1, &l1);  
 
   /* Initialize the image info structure and read an image.  */
   InitializeMagick(NULL);
   GetExceptionInfo(&exception);
   image_info=CloneImageInfo((ImageInfo *) NULL);
   (void) strncpy(image_info->filename,cstk(l1),MaxTextExtent);
    
   image=ReadImage(image_info,&exception);

   if (image == (Image *) NULL) {
      /* clean up */
      if(exception.reason != NULL) {
         char errmsg[50];
         for (i=0; i<49; i++)
            errmsg[i]=' ';
         errmsg[49]='\0';
         strncpy(errmsg,SipGetLocaleExceptionMessage(exception.severity,exception.reason),50);
         DestroyImageInfo(image_info);
         DestroyExceptionInfo(&exception);
         DestroyMagick();
         sip_error(errmsg);
      }
      DestroyImageInfo(image_info);
      DestroyExceptionInfo(&exception);
      DestroyMagick();
      sip_error("unknown reason");
   }
   

   m2 = image->rows; n2 = image->columns;

   if (sip_verbose == SIP_WORDY)
      sciprint("Size:\t%ld rows X %ld columns\n\r", m2, n2);

   imgsize = m2 * n2;
   
 
   pix=GetImagePixels(image, 0, 0, n2, m2);
   if(pix == (PixelPacket *) NULL)
      SIP_MAGICK_ERROR;
   
   switch(image->storage_class) {
   case DirectClass: {
      imgtype = GetImageType(image, &exception);
      if(imgtype == BilevelType) {
         stat = magick_binary_image_to_double_array(fname,pix,&l2, m2, n2);
         if (!stat) return false;
         CreateVarFromPtr(2, "d",&m2,&n2,&l2);  
         free(l2);
      } else {
         stat= magick_truecolor_image_to_double_hypermat(fname,pix,&Img,m2,n2);
         if (!stat) return false;
         CreateHMat(2,Img);
         free_sci_tru_img(&Img);
      }
      m1 = n1 = 0;
      CreateVar(3,"d",&m1,&n1,&l1);
      break;
   }
   case PseudoClass:   {
      stat= magick_index_map_to_sci_dbl(fname,image,2);
      if (!stat) return false;
      break;
   }
   default: 
      sip_error("unknown color class");
      break;
   }
   LhsVar(1) = 2;
   LhsVar(2) = 3;

   /* Terminate Imagemagick */
   DestroyImageInfo(image_info);
   DestroyImage(image);
   DestroyExceptionInfo(&exception);
   DestroyMagick();
   return true;
}
示例#25
0
文件: dng.c 项目: 0xPr0xy/ImageMagick
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d D N G I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadDNGImage() reads an binary file in the Digital Negative format 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 ReadDNGImage method is:
%
%      Image *ReadDNGImage(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 *ReadDNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  ExceptionInfo
    *sans_exception;

  Image
    *image;

  ImageInfo
    *read_info;

  MagickBooleanType
    status;

  /*
    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) CloseBlob(image);
  (void) DestroyImageList(image);
  /*
    Convert DNG to PPM with delegate.
  */
  image=AcquireImage(image_info);
  read_info=CloneImageInfo(image_info);
  (void) InvokeDelegate(read_info,image,"dng:decode",(char *) NULL,exception);
  image=DestroyImage(image);
  (void) FormatMagickString(read_info->filename,MaxTextExtent,"%s.png",
    read_info->unique);
  sans_exception=AcquireExceptionInfo();
  image=ReadImage(read_info,sans_exception);
  sans_exception=DestroyExceptionInfo(sans_exception);
  if (image == (Image *) NULL)
    {
      (void) FormatMagickString(read_info->filename,MaxTextExtent,"%s.ppm",
        read_info->unique);
      image=ReadImage(read_info,exception);
    }
  (void) RelinquishUniqueFileResource(read_info->filename);
  if (image != (Image *) NULL)
    {
      char
        filename[MaxTextExtent],
        *xml;

      ExceptionInfo
        *sans;

      (void) CopyMagickString(image->magick,read_info->magick,MaxTextExtent);
      (void) FormatMagickString(filename,MaxTextExtent,"%s.ufraw",
        read_info->unique);
      sans=AcquireExceptionInfo();
      xml=FileToString(filename,MaxTextExtent,sans);
      (void) RelinquishUniqueFileResource(filename);
      if (xml != (char *) NULL)
        {
          XMLTreeInfo
           *ufraw;

          /*
            Inject 
          */
          ufraw=NewXMLTree(xml,sans);
          if (ufraw != (XMLTreeInfo *) NULL)
            {
              char
                *content,
                property[MaxTextExtent];

              const char
                *tag;

              XMLTreeInfo
                *next;

              if (image->properties == (void *) NULL)
                ((Image *) image)->properties=NewSplayTree(
                  CompareSplayTreeString,RelinquishMagickMemory,
                  RelinquishMagickMemory);
              next=GetXMLTreeChild(ufraw,(const char *) NULL);
              while (next != (XMLTreeInfo *) NULL)
              {
                tag=GetXMLTreeTag(next);
                if (tag == (char *) NULL)
                  tag="unknown";
                (void) FormatMagickString(property,MaxTextExtent,"dng:%s",tag);
                content=ConstantString(GetXMLTreeContent(next)); 
                StripString(content);
                if ((LocaleCompare(tag,"log") != 0) &&
                    (LocaleCompare(tag,"InputFilename") != 0) &&
                    (LocaleCompare(tag,"OutputFilename") != 0) &&
                    (LocaleCompare(tag,"OutputType") != 0) &&
                    (strlen(content) != 0))
                  (void) AddValueToSplayTree((SplayTreeInfo *)
                    ((Image *) image)->properties,ConstantString(property),
                    content);
                next=GetXMLTreeSibling(next);
              }
              ufraw=DestroyXMLTree(ufraw);
            }
          xml=DestroyString(xml);
        }
      sans=DestroyExceptionInfo(sans);
    }
  read_info=DestroyImageInfo(read_info);
  return(image);
}
示例#26
0
dt_imageio_retval_t
dt_imageio_open_gm(
  dt_image_t *img,
  const char *filename,
  dt_mipmap_cache_allocator_t a)
{
  int err = DT_IMAGEIO_FILE_CORRUPTED;
  float *buf = NULL;
  ExceptionInfo exception;
  Image *image = NULL;
  ImageInfo *image_info = NULL;
  uint32_t width, height, orientation;

  if(!_supported_image(filename)) return DT_IMAGEIO_FILE_CORRUPTED;

  if(!img->exif_inited)
    (void) dt_exif_read(img, filename);

  GetExceptionInfo(&exception);
  image_info=CloneImageInfo((ImageInfo *) NULL);

  g_strlcpy(image_info->filename,filename,sizeof(image_info->filename));

  image=ReadImage(image_info,&exception);
  if (exception.severity != UndefinedException)
    CatchException(&exception);
  if (!image)
  {
    fprintf(stderr, "[GraphicsMagick_open] image `%s' not found\n", img->filename);
    err = DT_IMAGEIO_FILE_NOT_FOUND;
    goto error;
  }

  width = image->columns;
  height = image->rows;
  orientation = image->orientation;

  if(orientation & 4)
  {
    img->width = height;
    img->height = width;
  }
  else
  {
    img->width = width;
    img->height = height;
  }

  img->bpp = 4*sizeof(float);

  float *mipbuf = (float *)dt_mipmap_cache_alloc(img, DT_MIPMAP_FULL, a);
  if(!mipbuf)
  {
    fprintf(stderr, "[GraphicsMagick_open] could not alloc full buffer for image `%s'\n", img->filename);
    err = DT_IMAGEIO_CACHE_FULL;
    goto error;
  }

  buf = (float *)dt_alloc_align(16, width*img->bpp);
  if(!buf) goto error;

  const int ht2 = orientation & 4 ? img->width  : img->height; // pretend unrotated, rotate in write_pos
  const int wd2 = orientation & 4 ? img->height : img->width;

  for (uint32_t row = 0; row < height; row++)
  {
    int ret = DispatchImage(image, 0, row, width, 1, "RGBP", FloatPixel, (void *)buf, &exception);
    if (exception.severity != UndefinedException)
      CatchException(&exception);
    if(ret != MagickPass)
    {
      fprintf(stderr, "[GraphicsMagick_open] error reading image `%s'\n", img->filename);
      err = DT_IMAGEIO_FILE_CORRUPTED;
      goto error;
    }

    for(uint32_t i=0; i<width; i++)
      for(int k=0; k<4; k++) mipbuf[4*dt_imageio_write_pos(i, row, wd2, ht2, wd2, ht2, orientation) + k] = buf[4*i + k];
  }

  if(buf) dt_free_align(buf);
  if(image) DestroyImage(image);
  if(image_info) DestroyImageInfo(image_info);
  DestroyExceptionInfo(&exception);

  img->filters = 0;
  img->flags &= ~DT_IMAGE_RAW;
  img->flags &= ~DT_IMAGE_HDR;
  img->flags |= DT_IMAGE_LDR;

  return DT_IMAGEIO_OK;

error:
  if(buf) dt_free_align(buf);
  if(image) DestroyImage(image);
  if(image_info) DestroyImageInfo(image_info);
  DestroyExceptionInfo(&exception);
  return err;
}
示例#27
0
static MagickBooleanType LoadTypeList(const char *xml,const char *filename,
  const size_t depth,ExceptionInfo *exception)
{
  char
    font_path[MaxTextExtent],
    keyword[MaxTextExtent],
    *token;

  const char
    *q;

  MagickBooleanType
    status;

  TypeInfo
    *type_info;

  /*
    Load the type map file.
  */
  (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
    "Loading type configure file \"%s\" ...",filename);
  if (xml == (const char *) NULL)
    return(MagickFalse);
  if (type_list == (SplayTreeInfo *) NULL)
    {
      type_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL,
        DestroyTypeNode);
      if (type_list == (SplayTreeInfo *) NULL)
        {
          ThrowFileException(exception,ResourceLimitError,
            "MemoryAllocationFailed",filename);
          return(MagickFalse);
        }
    }
  status=MagickTrue;
  type_info=(TypeInfo *) NULL;
  token=AcquireString(xml);
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
  /*
    Determine the Ghostscript font path.
  */
  *font_path='\0';
  if (NTGhostscriptFonts(font_path,MaxTextExtent-2))
    (void) ConcatenateMagickString(font_path,DirectorySeparator,MaxTextExtent);
#endif
  for (q=(char *) xml; *q != '\0'; )
  {
    /*
      Interpret XML.
    */
    GetMagickToken(q,&q,token);
    if (*token == '\0')
      break;
    (void) CopyMagickString(keyword,token,MaxTextExtent);
    if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
      {
        /*
          Doctype element.
        */
        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
          GetMagickToken(q,&q,token);
        continue;
      }
    if (LocaleNCompare(keyword,"<!--",4) == 0)
      {
        /*
          Comment element.
        */
        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
          GetMagickToken(q,&q,token);
        continue;
      }
    if (LocaleCompare(keyword,"<include") == 0)
      {
        /*
          Include element.
        */
        while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
        {
          (void) CopyMagickString(keyword,token,MaxTextExtent);
          GetMagickToken(q,&q,token);
          if (*token != '=')
            continue;
          GetMagickToken(q,&q,token);
          if (LocaleCompare(keyword,"file") == 0)
            {
              if (depth > 200)
                (void) ThrowMagickException(exception,GetMagickModule(),
                  ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token);
              else
                {
                  char
                    path[MaxTextExtent],
                    *xml;

                  ExceptionInfo
                    *sans_exception;

                  *path='\0';
                  GetPathComponent(filename,HeadPath,path);
                  if (*path != '\0')
                    (void) ConcatenateMagickString(path,DirectorySeparator,
                      MaxTextExtent);
                  if (*token == *DirectorySeparator)
                    (void) CopyMagickString(path,token,MaxTextExtent);
                  else
                    (void) ConcatenateMagickString(path,token,MaxTextExtent);
                  sans_exception=AcquireExceptionInfo();
                  xml=FileToString(path,~0UL,sans_exception);
                  sans_exception=DestroyExceptionInfo(sans_exception);
                  if (xml != (char *) NULL)
                    {
                      status=LoadTypeList(xml,path,depth+1,exception);
                      xml=(char *) RelinquishMagickMemory(xml);
                    }
                }
            }
        }
        continue;
      }
    if (LocaleCompare(keyword,"<type") == 0)
      {
        /*
          Type element.
        */
        type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info));
        if (type_info == (TypeInfo *) NULL)
          ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
        (void) ResetMagickMemory(type_info,0,sizeof(*type_info));
        type_info->path=ConstantString(filename);
        type_info->signature=MagickSignature;
        continue;
      }
    if (type_info == (TypeInfo *) NULL)
      continue;
    if (LocaleCompare(keyword,"/>") == 0)
      {
        status=AddValueToSplayTree(type_list,type_info->name,type_info);
        if (status == MagickFalse)
          (void) ThrowMagickException(exception,GetMagickModule(),
            ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name);
        type_info=(TypeInfo *) NULL;
      }
    GetMagickToken(q,(const char **) NULL,token);
    if (*token != '=')
      continue;
    GetMagickToken(q,&q,token);
    GetMagickToken(q,&q,token);
    switch (*keyword)
    {
      case 'E':
      case 'e':
      {
        if (LocaleCompare((char *) keyword,"encoding") == 0)
          {
            type_info->encoding=ConstantString(token);
            break;
          }
        break;
      }
      case 'F':
      case 'f':
      {
        if (LocaleCompare((char *) keyword,"face") == 0)
          {
            type_info->face=StringToUnsignedLong(token);
            break;
          }
        if (LocaleCompare((char *) keyword,"family") == 0)
          {
            type_info->family=ConstantString(token);
            break;
          }
        if (LocaleCompare((char *) keyword,"format") == 0)
          {
            type_info->format=ConstantString(token);
            break;
          }
        if (LocaleCompare((char *) keyword,"foundry") == 0)
          {
            type_info->foundry=ConstantString(token);
            break;
          }
        if (LocaleCompare((char *) keyword,"fullname") == 0)
          {
            type_info->description=ConstantString(token);
            break;
          }
        break;
      }
      case 'G':
      case 'g':
      {
        if (LocaleCompare((char *) keyword,"glyphs") == 0)
          {
            char
              *path;

            path=ConstantString(token);
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
            if (strchr(path,'@') != (char *) NULL)
              SubstituteString(&path,"@ghostscript_font_path@",font_path);
#endif
            if (IsPathAccessible(path) == MagickFalse)
              {
                /*
                  Relative path.
                */
                path=DestroyString(path);
                GetPathComponent(filename,HeadPath,font_path);
                (void) ConcatenateMagickString(font_path,DirectorySeparator,
                  MaxTextExtent);
                (void) ConcatenateMagickString(font_path,token,MaxTextExtent);
                path=ConstantString(font_path);
                if (IsPathAccessible(path) == MagickFalse)
                  {
                    path=DestroyString(path);
                    path=ConstantString(token);
                  }
              }
            type_info->glyphs=path;
            break;
          }
        break;
      }
      case 'M':
      case 'm':
      {
        if (LocaleCompare((char *) keyword,"metrics") == 0)
          {
            char
              *path;

            path=ConstantString(token);
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
            if (strchr(path,'@') != (char *) NULL)
              SubstituteString(&path,"@ghostscript_font_path@",font_path);
#endif
            if (IsPathAccessible(path) == MagickFalse)
              {
                /*
                  Relative path.
                */
                path=DestroyString(path);
                GetPathComponent(filename,HeadPath,font_path);
                (void) ConcatenateMagickString(font_path,DirectorySeparator,
                  MaxTextExtent);
                (void) ConcatenateMagickString(font_path,token,MaxTextExtent);
                path=ConstantString(font_path);
              }
            type_info->metrics=path;
            break;
          }
        break;
      }
      case 'N':
      case 'n':
      {
        if (LocaleCompare((char *) keyword,"name") == 0)
          {
            type_info->name=ConstantString(token);
            break;
          }
        break;
      }
      case 'S':
      case 's':
      {
        if (LocaleCompare((char *) keyword,"stealth") == 0)
          {
            type_info->stealth=IsStringTrue(token);
            break;
          }
        if (LocaleCompare((char *) keyword,"stretch") == 0)
          {
            type_info->stretch=(StretchType) ParseCommandOption(
              MagickStretchOptions,MagickFalse,token);
            break;
          }
        if (LocaleCompare((char *) keyword,"style") == 0)
          {
            type_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
              MagickFalse,token);
            break;
          }
        break;
      }
      case 'W':
      case 'w':
      {
        if (LocaleCompare((char *) keyword,"weight") == 0)
          {
            type_info->weight=StringToUnsignedLong(token);
            if (LocaleCompare(token,"bold") == 0)
              type_info->weight=700;
            if (LocaleCompare(token,"normal") == 0)
              type_info->weight=400;
            break;
          }
        break;
      }
      default:
        break;
    }
  }
  token=(char *) RelinquishMagickMemory(token);
  return(status);
}
示例#28
0
MagickExport MagickBooleanType GetPathTemplate(char *path)
{
  char
    *directory,
    *value;

  ExceptionInfo
    *exception;

  MagickBooleanType
    status;

  struct stat
    attributes;

  (void) FormatLocaleString(path,MagickPathExtent,"magick-%.20gXXXXXXXXXXXX",
    (double) getpid());
  exception=AcquireExceptionInfo();
  directory=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
    exception);
  exception=DestroyExceptionInfo(exception);
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("MAGICK_TEMPORARY_PATH");
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("MAGICK_TMPDIR");
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("TMPDIR");
#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("TMP");
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("TEMP");
#endif
#if defined(__VMS)
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("MTMPDIR");
#endif
#if defined(P_tmpdir)
  if (directory == (char *) NULL)
    directory=ConstantString(P_tmpdir);
#endif
  if (directory == (char *) NULL)
    return(MagickTrue);
  value=GetPolicyValue("temporary-path");
  if (value != (char *) NULL)
    (void) CloneString(&directory,value);
  if (strlen(directory) > (MagickPathExtent-25))
    {
      directory=DestroyString(directory);
      return(MagickFalse);
    }
  status=GetPathAttributes(directory,&attributes);
  if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
    {
      directory=DestroyString(directory);
      return(MagickFalse);
    }
  if (directory[strlen(directory)-1] == *DirectorySeparator)
    (void) FormatLocaleString(path,MagickPathExtent,
      "%smagick-%.20gXXXXXXXXXXXX",directory,(double) getpid());
  else
    (void) FormatLocaleString(path,MagickPathExtent,
      "%s%smagick-%.20gXXXXXXXXXXXX",directory,DirectorySeparator,(double)
      getpid());
  directory=DestroyString(directory);
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
  {
    register char
      *p;

    /*
      Ghostscript does not like backslashes so we need to replace them. The
      forward slash also works under Windows.
    */
    for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p != '\0'; p++)
      if (*p == *DirectorySeparator)
        *p='/';
  }
#endif
  return(MagickTrue);
}
示例#29
0
static MagickBooleanType GetPathTemplate(char *path)
{
  char
    *directory;

  ExceptionInfo
    *exception;

  MagickBooleanType
    status;

  register char
    *p;

  struct stat
    attributes;

  (void) CopyMagickString(path,"magick-XXXXXXXX",MaxTextExtent);
  exception=AcquireExceptionInfo();
  directory=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
    exception);
  exception=DestroyExceptionInfo(exception);
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("MAGICK_TEMPORARY_PATH");
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("MAGICK_TMPDIR");
  if (directory == (char *) NULL)
    directory=GetPolicyValue("temporary-path");
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("TMPDIR");
#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("TMP");
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("TEMP");
#endif
#if defined(__VMS)
  if (directory == (char *) NULL)
    directory=GetEnvironmentValue("MTMPDIR");
#endif
#if defined(P_tmpdir)
  if (directory == (char *) NULL)
    directory=ConstantString(P_tmpdir);
#endif
  if (directory == (char *) NULL)
    return(MagickTrue);
  if (strlen(directory) > (MaxTextExtent-15))
    {
      directory=DestroyString(directory);
      return(MagickTrue);
    }
  status=GetPathAttributes(directory,&attributes);
  if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
    {
      directory=DestroyString(directory);
      return(MagickTrue);
    }
  if (directory[strlen(directory)-1] == *DirectorySeparator)
    (void) FormatLocaleString(path,MaxTextExtent,"%smagick-XXXXXXXX",directory);
  else
    (void) FormatLocaleString(path,MaxTextExtent,"%s%smagick-XXXXXXXX",
      directory,DirectorySeparator);
  directory=DestroyString(directory);
  if (*DirectorySeparator != '/')
    for (p=path; *p != '\0'; p++)
      if (*p == *DirectorySeparator)
        *p='/';
  return(MagickTrue);
}
示例#30
0
/**
 * Return the imagelist as a blob (a String).
 *
 * Ruby usage:
 *   - @verbatim ImageList#to_blob @endverbatim
 *
 * Notes:
 *   - Runs an info parm block if present - the user can specify the image
 *     format and depth
 *
 * @param self this object
 * @return the blob
 */
VALUE
ImageList_to_blob(VALUE self)
{
    Image *images, *image;
    Info *info;
    VALUE info_obj;
    VALUE blob_str;
    void *blob = NULL;
    size_t length = 0;
    ExceptionInfo *exception;

    info_obj = rm_info_new();
    Data_Get_Struct(info_obj, Info, info);

    // Convert the images array to an images sequence.
    images = images_from_imagelist(self);

    exception = AcquireExceptionInfo();
    (void) SetImageInfo(info, MagickTrue, exception);
    rm_check_exception(exception, images, RetainOnError);

    if (*info->magick != '\0')
    {
        Image *img;
        for (img = images; img; img = GetNextImageInList(img))
        {
            strncpy(img->magick, info->magick, sizeof(info->magick)-1);
        }
    }

    for (image = images; image; image = GetNextImageInList(image))
    {
        rm_sync_image_options(image, info);
    }

    // Unconditionally request multi-images support. The worst that
    // can happen is that there's only one image or the format
    // doesn't support multi-image files.
    info->adjoin = MagickTrue;
    blob = ImagesToBlob(info, images, &length, exception);
    if (blob && exception->severity >= ErrorException)
    {
        magick_free((void*)blob);
        blob = NULL;
        length = 0;
    }
    rm_split(images);
    CHECK_EXCEPTION()
    (void) DestroyExceptionInfo(exception);


    if (length == 0 || !blob)
    {
        return Qnil;
    }

    blob_str = rb_str_new(blob, (long)length);
    magick_free((void*)blob);

    RB_GC_GUARD(info_obj);
    RB_GC_GUARD(blob_str);

    return blob_str;
}