Exemplo n.º 1
0
static char
get_loader(lopt * opt, ImlibLoader ** loader)
{
   union id3_field    *field;
   char const         *data;
   char                ext[EXT_LEN + 2];

   ext[EXT_LEN + 1] = '\0';
   ext[0] = '.';

   field = id3_frame_field(id3_tag_get_frame(opt->ctx->tag, opt->index - 1), 1);
   data = (char const *)id3_field_getlatin1(field);
   if (!data)
     {
        fprintf(stderr, "No mime type data found for image frame\n");
        return 0;
     }
   if (strncasecmp(data, "image/", 6))
     {
        if (!strcmp(data, "-->"))
          {
             *loader = NULL;
             return 1;
          }
        fprintf(stderr,
                "Picture frame with unknown mime-type \'%s\' found\n", data);
        return 0;
     }
   strncpy(ext + 1, data + 6, EXT_LEN);
   if (!(*loader = __imlib_FindBestLoaderForFile(ext, 0)))
     {
        fprintf(stderr, "No loader found for extension %s\n", ext);
        return 0;
     }
   return 1;
}
Exemplo n.º 2
0
char
load(ImlibImage * im, ImlibProgressFunction progress,
     char progress_granularity, char immediate_load)
{
   ImlibLoader        *loader;
   lopt                opt;
   int                 res;
   struct stat         st;

   assert(im);
   if (stat(im->real_file, &st) < 0)
      return 0;
   if (!get_options(&opt, im))
      return 0;

   if (!get_loader(&opt, &loader))
      goto fail_context;

   if (loader)
     {
        char               *ofile, tmp[] = "/tmp/imlib2_loader_id3-XXXXXX";
        int                 dest;

        if ((dest = mkstemp(tmp)) < 0)
          {
             fprintf(stderr, "Unable to create a temporary file\n");
             goto fail_context;
          }
        res = extract_pic(id3_tag_get_frame(opt.ctx->tag, opt.index - 1), dest);
        close(dest);

        if (!res)
          {
             unlink(tmp);
             goto fail_context;
          }

        ofile = im->real_file;
        im->real_file = strdup(tmp);
        res = loader->load(im, progress, progress_granularity, immediate_load);
        free(im->real_file);
        im->real_file = ofile;

        unlink(tmp);
     }
   else
     {
        /* The tag actually provides a image url rather than image data.
         * Practically, dunno if such a tag exists on earth :)
         * Here's the code anyway...
         */
        union id3_field    *field;
        id3_length_t        length;
        char const         *data;
        char               *url, *file, *ofile;

        field = id3_frame_field
           (id3_tag_get_frame(opt.ctx->tag, opt.index - 1), 4);
        data = (char const *)id3_field_getbinarydata(field, &length);
        if (!data || !length)
          {
             fprintf(stderr, "No link image URL present\n");
             goto fail_context;
          }
        url = (char *)malloc((length + 1) * sizeof(char));
        strncpy(url, data, length);
        url[length] = '\0';
        file = (strncmp(url, "file://", 7) ? url : url + 7);
        if (!(loader = __imlib_FindBestLoaderForFile(file, 0)))
          {
             fprintf(stderr, "No loader found for file %s\n", file);
             free(url);
             goto fail_context;
          }
        ofile = im->real_file;
        im->real_file = file;
        res = loader->load(im, progress, progress_granularity, immediate_load);
        if (!im->loader)
           __imlib_AttachTag(im, "id3-link-url", 0, url, destructor_data);
        else
           free(url);
        im->real_file = ofile;
     }

   if (!im->loader)
      write_tags(im, &opt);

#ifdef DEBUG
   if (!im->loader)
     {
        ImlibImageTag      *cur = im->tags;

        fprintf(stderr, "Tags for file %s:\n", im->file);
        while (cur)
          {
             fprintf(stderr, "\t%s: (%d) %s\n", cur->key,
                     cur->val, (char *)cur->data);
             cur = cur->next;
          }
     }
#endif

   context_delref(opt.ctx);
   return res;

 fail_context:
   context_delref(opt.ctx);
   return 0;
}
Exemplo n.º 3
0
ImlibImage         *
__imlib_LoadImage(const char *file, ImlibProgressFunction progress,
                  char progress_granularity, char immediate_load,
                  char dont_cache, ImlibLoadError * er)
{
   ImlibImage         *im;
   ImlibLoader        *best_loader;
   char                loader_ret = 0;

   if (!file)
      return NULL;
   if (file[0] == 0)
      return NULL;
   /* see if we already have the image cached */
   im = __imlib_FindCachedImage(file);
   /* if we found a cached image and we shoudl always check that it is */
   /* accurate to the disk conents if they changed since we last loaded */
   /* and that it is still a valid image */
   if ((im) && (IMAGE_IS_VALID(im)))
     {
        if (IMAGE_ALWAYS_CHECK_DISK(im))
          {
             time_t              current_modified_time;

             current_modified_time = __imlib_FileModDate(file);
             /* if the file on disk is newer than the cached one */
             if (current_modified_time > im->moddate)
               {
                  /* invalidate image */
                  SET_FLAG(im->flags, F_INVALID);
               }
             else
               {
                  /* image is ok to re-use - program is just being stupid loading */
                  /* the same data twice */
                  im->references++;
                  return im;
               }
          }
        else
          {
             im->references++;
             return im;
          }
     }
   /* either image in cache is invalid or we dont even have it in cache */
   /* so produce a new one and load an image into that */
   im = __imlib_ProduceImage();
   im->file = strdup(file);
   if (__imlib_IsRealFile(file))
     {
        im->real_file = strdup(im->file);
        im->key = NULL;
     }
   else
     {
        im->real_file = __imlib_FileRealFile(file);
        im->key = __imlib_FileKey(file);
     }
   im->moddate = __imlib_FileModDate(file);
   /* ok - just check all our loaders are up to date */
   __imlib_RescanLoaders();
   /* take a guess by extension on the best loader to use */
   best_loader = __imlib_FindBestLoaderForFile(im->real_file, 0);
   errno = 0;
   if (best_loader)
      loader_ret =
          best_loader->load(im, progress, progress_granularity, immediate_load);
   /* width is still 0 - the loader didnt manage to do anything */
   if (im->w == 0)
     {
        ImlibLoader        *l, *previous_l = NULL;

        errno = 0;
        l = loaders;
        /* run through all loaders and try load until one succeeds */
        while ((l) && (im->w == 0))
          {
             /* if its not the best loader that already failed - try load */
             if (l != best_loader)
                loader_ret =
                    l->load(im, progress, progress_granularity, immediate_load);
             /* if it failed - advance */
             if (im->w == 0)
               {
                  previous_l = l;
                  l = l->next;
               }
          }
        /* if we have a loader then its the loader that succeeded */
        /* move the successful loader to the head of the list */
        /* as long as it's not already at the head of the list */
        if ((l) && (previous_l))
          {
             im->loader = l;
             previous_l->next = l->next;
             l->next = loaders;
             loaders = l;
          }
        if (im->w > 0)
           im->loader = l;
     }
   else
      im->loader = best_loader;
   /* all loaders have been tried and they all failed. free the skeleton */
   /* image struct we had and return NULL */
   if (im->w == 0)
     {
        /* if the caller wants an error return */
        if (er)
          {
             /* set to a default fo no error */
             *er = IMLIB_LOAD_ERROR_NONE;
             /* if the errno is set */
             if (errno != 0)
               {
                  /* default to unknown error */
                  *er = IMLIB_LOAD_ERROR_UNKNOWN;
                  /* standrad fopen() type errors translated */
                  if (errno == EEXIST)
                     *er = IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST;
                  else if (errno == EISDIR)
                     *er = IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY;
                  else if (errno == EISDIR)
                     *er = IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY;
                  else if (errno == EACCES)
                     *er = IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ;
                  else if (errno == ENAMETOOLONG)
                     *er = IMLIB_LOAD_ERROR_PATH_TOO_LONG;
                  else if (errno == ENOENT)
                     *er = IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT;
                  else if (errno == ENOTDIR)
                     *er = IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY;
                  else if (errno == EFAULT)
                     *er = IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE;
                  else if (errno == ELOOP)
                     *er = IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS;
                  else if (errno == ENOMEM)
                     *er = IMLIB_LOAD_ERROR_OUT_OF_MEMORY;
                  else if (errno == EMFILE)
                     *er = IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS;
                  if (*er != IMLIB_LOAD_ERROR_UNKNOWN)
                    {
                       /* free the stuct we created */
                       __imlib_ConsumeImage(im);
                       return NULL;
                    }
               }
             errno = 0;
          }
        __imlib_ConsumeImage(im);
        return NULL;
     }

   /* the load succeeded - make sure the image is referenced then add */
   /* it to our cache if dont_cache isn't set */
   im->references = 1;
   if (loader_ret == 2)
      dont_cache = 1;
   if (!dont_cache)
      __imlib_AddImageToCache(im);
   else
      SET_FLAG(im->flags, F_UNCACHEABLE);
   return im;
}