Esempio n. 1
0
/**
 * Load entire image into memory using fileaccess load method.
 * Faster than open+read+close.
 */
static pixmap_t *
fa_imageloader2(const char *url, const char **vpaths,
                char *errbuf, size_t errlen)
{
    uint8_t *p;
    size_t size;
    meminfo_t mi;
    pixmap_type_t fmt;
    int width = -1, height = -1, orientation = 0;

    if((p = fa_load(url, &size, vpaths, errbuf, errlen, NULL)) == NULL)
        return NULL;

    mi.data = p;
    mi.size = size;

    /* Probe format */

    if((p[6] == 'J' && p[7] == 'F' && p[8] == 'I' && p[9] == 'F') ||
            (p[6] == 'E' && p[7] == 'x' && p[8] == 'i' && p[9] == 'f')) {

        jpeginfo_t ji;

        if(jpeg_info(&ji, jpeginfo_mem_reader, &mi,
                     JPEG_INFO_DIMENSIONS | JPEG_INFO_ORIENTATION,
                     p, size, errbuf, errlen)) {
            free(p);
            return NULL;
        }

        fmt = PIXMAP_JPEG;

        width = ji.ji_width;
        height = ji.ji_height;
        orientation = ji.ji_orientation;

        jpeg_info_clear(&ji);

    } else if(!memcmp(pngsig, p, 8)) {
        fmt = PIXMAP_PNG;
    } else if(!memcmp(gif87sig, p, sizeof(gif87sig)) ||
              !memcmp(gif89sig, p, sizeof(gif89sig))) {
        fmt = PIXMAP_GIF;
    } else {
        snprintf(errbuf, errlen, "%s: unknown format", url);
        free(p);
        return NULL;
    }

    pixmap_t *pm = pixmap_alloc_coded(p, size, fmt);
    pm->pm_width = width;
    pm->pm_height = height;
    pm->pm_orientation = orientation;

    free(p);
    return pm;
}
Esempio n. 2
0
static void
fa_probe_exif(metadata_t *md, const char *url, uint8_t *pb, fa_handle_t *fh)
{
  jpeginfo_t ji;

  if(jpeg_info(&ji, jpeginfo_reader, fh, 
	       JPEG_INFO_DIMENSIONS | JPEG_INFO_ORIENTATION |
	       JPEG_INFO_METADATA,
	       pb, 256, NULL, 0))
    return;
  
  md->md_time = ji.ji_time;
  md->md_manufacturer = rstr_dup(ji.ji_manufacturer);
  md->md_equipment    = rstr_dup(ji.ji_equipment);
  jpeg_info_clear(&ji);
}
Esempio n. 3
0
/**
 * Load entire image into memory using fileaccess load method.
 * Faster than open+read+close.
 */
static pixmap_t *
fa_imageloader2(const char *url, const char **vpaths,
		char *errbuf, size_t errlen, int *cache_control,
                cancellable_t *c)
{
  buf_t *buf;
  jpeg_meminfo_t mi;
  pixmap_type_t fmt;
  int width = -1, height = -1, orientation = 0;

  buf = fa_load(url,
                 FA_LOAD_VPATHS(vpaths),
                 FA_LOAD_ERRBUF(errbuf, errlen),
                 FA_LOAD_CACHE_CONTROL(cache_control),
                 FA_LOAD_CANCELLABLE(c),
                 NULL);
  if(buf == NULL || buf == NOT_MODIFIED)
    return (pixmap_t *)buf;

  const uint8_t *p = buf_c8(buf);
  mi.data = p;
  mi.size = buf->b_size;

  if(buf->b_size < 16)
    goto bad;

  /* Probe format */

  if((p[6] == 'J' && p[7] == 'F' && p[8] == 'I' && p[9] == 'F') ||
     (p[6] == 'E' && p[7] == 'x' && p[8] == 'i' && p[9] == 'f')) {
      
    jpeginfo_t ji;
    
    if(jpeg_info(&ji, jpeginfo_mem_reader, &mi, 
		 JPEG_INFO_DIMENSIONS | JPEG_INFO_ORIENTATION,
		 p, buf->b_size, errbuf, errlen)) {
      buf_release(buf);
      return NULL;
    }

    fmt = PIXMAP_JPEG;

    width = ji.ji_width;
    height = ji.ji_height;
    orientation = ji.ji_orientation;

    jpeg_info_clear(&ji);

  } else if(!memcmp(pngsig, p, 8)) {
    fmt = PIXMAP_PNG;
  } else if(!memcmp(gif87sig, p, sizeof(gif87sig)) ||
	    !memcmp(gif89sig, p, sizeof(gif89sig))) {
    fmt = PIXMAP_GIF;
  } else if(!memcmp(svgsig1, p, sizeof(svgsig1)) ||
	    !memcmp(svgsig2, p, sizeof(svgsig2))) {
    fmt = PIXMAP_SVG;
  } else {
  bad:
    snprintf(errbuf, errlen, "Unknown format");
    buf_release(buf);
    return NULL;
  }

  pixmap_t *pm = pixmap_alloc_coded(p, buf->b_size, fmt);
  if(pm != NULL) {
    pm->pm_width = width;
    pm->pm_height = height;
    pm->pm_orientation = orientation;
  } else {
    snprintf(errbuf, errlen, "Out of memory");
  }
  buf_release(buf);
  return pm;
}
Esempio n. 4
0
pixmap_t *
fa_imageloader(const char *url, const struct image_meta *im,
	       const char **vpaths, char *errbuf, size_t errlen,
	       int *cache_control, cancellable_t *c)
{
  uint8_t p[16];
  int r;
  int width = -1, height = -1, orientation = 0;
  fa_handle_t *fh;
  pixmap_t *pm;
  pixmap_type_t fmt;

#if ENABLE_LIBAV
  if(strchr(url, '#'))
    return fa_image_from_video(url, im, errbuf, errlen, cache_control, c);
#endif

  if(!im->im_want_thumb)
    return fa_imageloader2(url, vpaths, errbuf, errlen, cache_control, c);

  fa_open_extra_t foe = {
    .foe_c = c
  };

  if((fh = fa_open_vpaths(url, vpaths, errbuf, errlen,
			  FA_BUFFERED_SMALL, &foe)) == NULL)
    return NULL;

  if(ONLY_CACHED(cache_control)) {
    snprintf(errbuf, errlen, "Not cached");
    return NULL;
  }

  if(fa_read(fh, p, sizeof(p)) != sizeof(p)) {
    snprintf(errbuf, errlen, "File too short");
    fa_close(fh);
    return NULL;
  }

  /* Probe format */

  if((p[6] == 'J' && p[7] == 'F' && p[8] == 'I' && p[9] == 'F') ||
     (p[6] == 'E' && p[7] == 'x' && p[8] == 'i' && p[9] == 'f')) {
      
    jpeginfo_t ji;
    
    if(jpeg_info(&ji, jpeginfo_reader, fh,
		 JPEG_INFO_DIMENSIONS |
		 JPEG_INFO_ORIENTATION |
		 (im->im_want_thumb ? JPEG_INFO_THUMBNAIL : 0),
		 p, sizeof(p), errbuf, errlen)) {
      fa_close(fh);
      return NULL;
    }

    if(im->im_want_thumb && ji.ji_thumbnail) {
      pixmap_t *pm = pixmap_dup(ji.ji_thumbnail);
      fa_close(fh);
      jpeg_info_clear(&ji);
      return pm;
    }

    fmt = PIXMAP_JPEG;

    width = ji.ji_width;
    height = ji.ji_height;
    orientation = ji.ji_orientation;

    jpeg_info_clear(&ji);

  } else if(!memcmp(pngsig, p, 8)) {
    fmt = PIXMAP_PNG;
  } else if(!memcmp(gif87sig, p, sizeof(gif87sig)) ||
	    !memcmp(gif89sig, p, sizeof(gif89sig))) {
    fmt = PIXMAP_GIF;
  } else if(!memcmp(svgsig1, p, sizeof(svgsig1)) ||
	    !memcmp(svgsig2, p, sizeof(svgsig2))) {
    fmt = PIXMAP_SVG;
  } else {
    snprintf(errbuf, errlen, "Unknown format");
    fa_close(fh);
    return NULL;
  }

  int64_t s = fa_fsize(fh);
  if(s < 0) {
    snprintf(errbuf, errlen, "Can't read from non-seekable file");
    fa_close(fh);
    return NULL;
  }

  pm = pixmap_alloc_coded(NULL, s, fmt);

  if(pm == NULL) {
    snprintf(errbuf, errlen, "Out of memory");
    fa_close(fh);
    return NULL;
  }

  pm->pm_width = width;
  pm->pm_height = height;
  pm->pm_orientation = orientation;
  fa_seek(fh, SEEK_SET, 0);
  r = fa_read(fh, pm->pm_data, pm->pm_size);
  fa_close(fh);

  if(r != pm->pm_size) {
    pixmap_release(pm);
    snprintf(errbuf, errlen, "Read error");
    return NULL;
  }
  return pm;
}
Esempio n. 5
0
static image_t *
fa_imageloader_buf(buf_t *buf, char *errbuf, size_t errlen)
{
  jpeg_meminfo_t mi;
  image_coded_type_t fmt;
  int width = -1, height = -1, orientation = 0, progressive = 0, planes = 0;

  const uint8_t *p = buf_c8(buf);
  mi.data = p;
  mi.size = buf->b_size;

  if(buf->b_size < 16)
    goto bad;

  /* Probe format */

  if(p[0] == 0xff && p[1] == 0xd8 && p[2] == 0xff) {

    jpeginfo_t ji;

    if(jpeg_info(&ji, jpeginfo_mem_reader, &mi,
		 JPEG_INFO_DIMENSIONS | JPEG_INFO_ORIENTATION,
		 p, buf->b_size, errbuf, errlen)) {
      return NULL;
    }

    fmt = IMAGE_JPEG;

    width       = ji.ji_width;
    height      = ji.ji_height;
    orientation = ji.ji_orientation;
    progressive = ji.ji_progressive;
    planes      = ji.ji_components;
    jpeg_info_clear(&ji);

  } else if(!memcmp(pngsig, p, 8)) {
    fmt = IMAGE_PNG;
  } else if(!memcmp(gif87sig, p, sizeof(gif87sig)) ||
	    !memcmp(gif89sig, p, sizeof(gif89sig))) {
    fmt = IMAGE_GIF;
  } else if(p[0] == 'B' && p[1] == 'M') {
    fmt = IMAGE_BMP;
  } else if(!memcmp(svgsig1, p, sizeof(svgsig1)) ||
	    !memcmp(svgsig2, p, sizeof(svgsig2))) {
    fmt = IMAGE_SVG;
  } else {
  bad:
    snprintf(errbuf, errlen, "Unknown format");
    return NULL;
  }

  image_t *img = image_coded_create_from_buf(buf, fmt);
  if(img != NULL) {
    img->im_width = width;
    img->im_height = height;
    img->im_orientation = orientation;
    img->im_color_planes = planes;
    if(progressive)
      img->im_flags |= IMAGE_PROGRESSIVE;
  } else {
    snprintf(errbuf, errlen, "Out of memory");
  }
  return img;
}
Esempio n. 6
0
image_t *
fa_imageloader(const char *url, const struct image_meta *im,
	       const char **vpaths, char *errbuf, size_t errlen,
	       int *cache_control, cancellable_t *c)
{
  uint8_t p[16];
  int r;
  int width = -1, height = -1, orientation = 0;
  fa_handle_t *fh;
  image_t *img;
  image_coded_type_t fmt;

#if ENABLE_LIBAV
  if(strchr(url, '#'))
    return fa_image_from_video(url, im, errbuf, errlen, cache_control, c);
#endif

  if(!im->im_want_thumb)
    return fa_imageloader2(url, vpaths, errbuf, errlen, cache_control, c);

  fa_open_extra_t foe = {
    .foe_cancellable = c
  };

  if((fh = fa_open_vpaths(url, vpaths, errbuf, errlen,
			  FA_BUFFERED_SMALL, &foe)) == NULL)
    return NULL;

  if(ONLY_CACHED(cache_control)) {
    snprintf(errbuf, errlen, "Not cached");
    return NULL;
  }

  if(fa_read(fh, p, sizeof(p)) != sizeof(p)) {
    snprintf(errbuf, errlen, "File too short");
    fa_close(fh);
    return NULL;
  }

  /* Probe format */

  if(p[0] == 0xff && p[1] == 0xd8 && p[2] == 0xff) {
      
    jpeginfo_t ji;
    
    if(jpeg_info(&ji, jpeginfo_reader, fh,
		 JPEG_INFO_DIMENSIONS |
		 JPEG_INFO_ORIENTATION |
		 (im->im_want_thumb ? JPEG_INFO_THUMBNAIL : 0),
		 p, sizeof(p), errbuf, errlen)) {
      fa_close(fh);
      return NULL;
    }

    if(im->im_want_thumb && ji.ji_thumbnail) {
      image_t *im = image_retain(ji.ji_thumbnail);
      fa_close(fh);
      jpeg_info_clear(&ji);
      im->im_flags |= IMAGE_ADAPTED;
      return im;
    }

    fmt = IMAGE_JPEG;

    width = ji.ji_width;
    height = ji.ji_height;
    orientation = ji.ji_orientation;

    jpeg_info_clear(&ji);

  } else if(!memcmp(pngsig, p, 8)) {
    fmt = IMAGE_PNG;
  } else if(!memcmp(gif87sig, p, sizeof(gif87sig)) ||
	    !memcmp(gif89sig, p, sizeof(gif89sig))) {
    fmt = IMAGE_GIF;
  } else if(p[0] == 'B' && p[1] == 'M') {
    fmt = IMAGE_BMP;
  } else if(!memcmp(svgsig1, p, sizeof(svgsig1)) ||
	    !memcmp(svgsig2, p, sizeof(svgsig2))) {
    fmt = IMAGE_SVG;
  } else {
    snprintf(errbuf, errlen, "Unknown format");
    fa_close(fh);
    return NULL;
  }

  int64_t s = fa_fsize(fh);
  if(s < 0) {
    snprintf(errbuf, errlen, "Can't read from non-seekable file");
    fa_close(fh);
    return NULL;
  }

  void *ptr;
  img = image_coded_alloc(&ptr, s, fmt);

  if(img == NULL) {
    snprintf(errbuf, errlen, "Out of memory");
    fa_close(fh);
    return NULL;
  }

  img->im_width = width;
  img->im_height = height;
  img->im_orientation = orientation;
  fa_seek(fh, SEEK_SET, 0);
  r = fa_read(fh, ptr, s);
  fa_close(fh);

  if(r != s) {
    image_release(img);
    snprintf(errbuf, errlen, "Read error");
    return NULL;
  }
  return img;
}
Esempio n. 7
0
/**
 * Load entire image into memory using fileaccess load method.
 * Faster than open+read+close.
 */
static pixmap_t *
fa_imageloader2(const char *url, const char **vpaths,
		char *errbuf, size_t errlen, int *cache_control,
		fa_load_cb_t *cb, void *opaque)
{
  uint8_t *p;
  size_t size;
  jpeg_meminfo_t mi;
  pixmap_type_t fmt;
  int width = -1, height = -1, orientation = 0;

  p = fa_load(url, &size, vpaths, errbuf, errlen, cache_control, 0, cb, opaque);
  if(p == NULL || p == NOT_MODIFIED)
    return (pixmap_t *)p;

  mi.data = p;
  mi.size = size;

  if(size < 16)
    goto bad;

  /* Probe format */

  if((p[6] == 'J' && p[7] == 'F' && p[8] == 'I' && p[9] == 'F') ||
     (p[6] == 'E' && p[7] == 'x' && p[8] == 'i' && p[9] == 'f')) {
      
    jpeginfo_t ji;
    
    if(jpeg_info(&ji, jpeginfo_mem_reader, &mi, 
		 JPEG_INFO_DIMENSIONS | JPEG_INFO_ORIENTATION,
		 p, size, errbuf, errlen)) {
      free(p);
      return NULL;
    }

    fmt = PIXMAP_JPEG;

    width = ji.ji_width;
    height = ji.ji_height;
    orientation = ji.ji_orientation;

    jpeg_info_clear(&ji);

  } else if(!memcmp(pngsig, p, 8)) {
    fmt = PIXMAP_PNG;
  } else if(!memcmp(gif87sig, p, sizeof(gif87sig)) ||
	    !memcmp(gif89sig, p, sizeof(gif89sig))) {
    fmt = PIXMAP_GIF;
  } else if(!memcmp(svgsig1, p, sizeof(svgsig1)) ||
	    !memcmp(svgsig2, p, sizeof(svgsig2))) {
    fmt = PIXMAP_SVG;
  } else {
  bad:
    snprintf(errbuf, errlen, "Unknown format");
    free(p);
    return NULL;
  }

  pixmap_t *pm = pixmap_alloc_coded(p, size, fmt);
  if(pm != NULL) {
    pm->pm_width = width;
    pm->pm_height = height;
    pm->pm_orientation = orientation;
  } else {
    snprintf(errbuf, errlen, "Out of memory");
  }
  free(p);
  return pm;
}
Esempio n. 8
0
pixmap_t *
fa_imageloader(const char *url, const struct image_meta *im,
	       const char **vpaths, char *errbuf, size_t errlen)
{
  uint8_t p[16];
  int r;
  enum CodecID codec;
  int width = -1, height = -1, orientation = 0;
  AVIOContext *avio;
  pixmap_t *pm;

  if(strchr(url, '#')) {
    pm = fa_image_from_video(url, im);
    if(pm == NULL)
      snprintf(errbuf, errlen, "%s: Unable to extract image", url);
    return pm;
  }

  if(!im->want_thumb)
    return fa_imageloader2(url, vpaths, errbuf, errlen);

  if((avio = fa_libav_open_vpaths(url, 32768, vpaths)) == NULL) {
    snprintf(errbuf, errlen, "%s: Unable to open file", url);
    return NULL;
  }

  if(avio_read(avio, p, sizeof(p)) != sizeof(p)) {
    snprintf(errbuf, errlen, "%s: file too short", url);
    fa_libav_close(avio);
    return NULL;
  }

  /* Probe format */

  if((p[6] == 'J' && p[7] == 'F' && p[8] == 'I' && p[9] == 'F') ||
     (p[6] == 'E' && p[7] == 'x' && p[8] == 'i' && p[9] == 'f')) {
      
    jpeginfo_t ji;
    
    if(jpeg_info(&ji, jpeginfo_reader, avio,
		 JPEG_INFO_DIMENSIONS |
		 JPEG_INFO_ORIENTATION |
		 (im->want_thumb ? JPEG_INFO_THUMBNAIL : 0),
		 p, sizeof(p), errbuf, errlen)) {
      fa_libav_close(avio);
      return NULL;
    }

    if(im->want_thumb && ji.ji_thumbnail) {
      pixmap_t *pm = pixmap_dup(ji.ji_thumbnail);
      fa_libav_close(avio);
      jpeg_info_clear(&ji);
      return pm;
    }

    codec = CODEC_ID_MJPEG;

    width = ji.ji_width;
    height = ji.ji_height;
    orientation = ji.ji_orientation;

    jpeg_info_clear(&ji);

  } else if(!memcmp(pngsig, p, 8)) {
    codec = CODEC_ID_PNG;
  } else if(!memcmp(gif87sig, p, sizeof(gif87sig)) ||
	    !memcmp(gif89sig, p, sizeof(gif89sig))) {
    codec = CODEC_ID_GIF;
  } else {
    snprintf(errbuf, errlen, "%s: unknown format", url);
    fa_libav_close(avio);
    return NULL;
  }

  size_t s = avio_size(avio);
  if(s < 0) {
    snprintf(errbuf, errlen, "%s: Can't read from non-seekable file", url);
    fa_libav_close(avio);
    return NULL;
  }

  pm = pixmap_alloc_coded(NULL, s, codec);

  if(pm == NULL) {
    snprintf(errbuf, errlen, "%s: no memory", url);
    fa_libav_close(avio);
    return NULL;
  }

  pm->pm_width = width;
  pm->pm_height = height;
  pm->pm_orientation = orientation;
  avio_seek(avio, SEEK_SET, 0);
  r = avio_read(avio, pm->pm_data, pm->pm_size);
  fa_libav_close(avio);

  if(r != pm->pm_size) {
    pixmap_release(pm);
    snprintf(errbuf, errlen, "%s: read error", url);
    return NULL;
  }
  return pm;
}