Exemplo n.º 1
0
// load a full-res thumbnail:
int dt_imageio_large_thumbnail(const char *filename, uint8_t **buffer, int32_t *width, int32_t *height, int32_t *orientation)
{
  int ret = 0;
  int res = 1;
  // raw image thumbnail
  libraw_data_t *raw = libraw_init(0);
  libraw_processed_image_t *image = NULL;
  ret = libraw_open_file(raw, filename);
  if(ret) goto libraw_fail;
  ret = libraw_unpack_thumb(raw);
  if(ret) goto libraw_fail;
  ret = libraw_adjust_sizes_info_only(raw);
  if(ret) goto libraw_fail;

  image = libraw_dcraw_make_mem_thumb(raw, &ret);
  if(!image || ret) goto libraw_fail;
  *orientation = raw->sizes.flip;
  if(image->type == LIBRAW_IMAGE_JPEG)
  {
    dt_imageio_jpeg_t jpg;
    if(dt_imageio_jpeg_decompress_header(image->data, image->data_size, &jpg)) goto libraw_fail;
    *buffer = (uint8_t *)malloc((size_t)sizeof(uint8_t)*jpg.width*jpg.height*4);
    if(!*buffer) goto libraw_fail;
    *width = jpg.width;
    *height = jpg.height;
    if(dt_imageio_jpeg_decompress(&jpg, *buffer))
    {
      free(*buffer);
      *buffer = 0;
      goto libraw_fail;
    }
    res = 0;
  }

  // clean up raw stuff.
  libraw_recycle(raw);
  libraw_close(raw);
  free(image);
  if(0)
  {
libraw_fail:
    // fprintf(stderr,"[imageio] %s: %s\n", filename, libraw_strerror(ret));
    libraw_close(raw);
    res = 1;
  }
  return res;
}
Exemplo n.º 2
0
jbyteArray Java_org_libraw_LibRaw_getThumbFromBuffer(JNIEnv* env, jclass clazz, jbyteArray bufferBytes) {
	libraw_data_t * data;
	jbyte* buffer;
	jsize len;
	jbyteArray ret;
	libraw_processed_image_t * image;
	
	data = libraw_init(0);
	len = (*env)->GetArrayLength(env, bufferBytes);
	buffer = (*env)->GetByteArrayElements(env, bufferBytes, NULL);
	libraw_open_buffer(data, (void *) buffer, (size_t) len);
	libraw_unpack_thumb(data);
	image = libraw_dcraw_make_mem_thumb(data, 0);
	ret = (*env)->NewByteArray(env, image->data_size);
	(*env)->SetByteArrayRegion(env, ret, 0, image->data_size, (jbyte *) image->data);
	(*env)->ReleaseByteArrayElements(env, bufferBytes, buffer, 0);
	return ret;
}
Exemplo n.º 3
0
// TODO: use orientation to correctly rotate the image.
// maybe this should be (partly) in common/imageio.[c|h]?
static void _lib_import_update_preview(GtkFileChooser *file_chooser, gpointer data)
{
  GtkWidget *preview;
  char *filename;
  GdkPixbuf *pixbuf = NULL;
  gboolean have_preview = FALSE;

  preview = GTK_WIDGET(data);
  filename = gtk_file_chooser_get_preview_filename(file_chooser);

  if(!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) goto no_preview_fallback;
  // don't create dng thumbnails to avoid crashes in libtiff when these are hdr:
  char *c = filename + strlen(filename);
  while(c > filename && *c != '.') c--;
  if(!strcasecmp(c, ".dng")) goto no_preview_fallback;

  pixbuf = gdk_pixbuf_new_from_file_at_size(filename, 128, 128, NULL);
  have_preview = (pixbuf != NULL);
  if(!have_preview)
  {
    // raw image thumbnail
    int ret;
    libraw_data_t *raw = libraw_init(0);
    libraw_processed_image_t *image = NULL;
    ret = libraw_open_file(raw, filename);
    if(ret) goto libraw_fail;
    ret = libraw_unpack_thumb(raw);
    if(ret) goto libraw_fail;
    ret = libraw_adjust_sizes_info_only(raw);
    if(ret) goto libraw_fail;

    image = libraw_dcraw_make_mem_thumb(raw, &ret);
    if(!image || ret) goto libraw_fail;
//     const int orientation = raw->sizes.flip;

    GdkPixbuf *tmp;
    GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
    have_preview = gdk_pixbuf_loader_write(loader, image->data, image->data_size, NULL);
    tmp = gdk_pixbuf_loader_get_pixbuf(loader);
    gdk_pixbuf_loader_close(loader, NULL);
    float ratio;
    if(image->type == LIBRAW_IMAGE_JPEG)
    {
      // jpeg
      dt_imageio_jpeg_t jpg;
      if(dt_imageio_jpeg_decompress_header(image->data, image->data_size, &jpg)) goto libraw_fail;
      ratio = 1.0*jpg.height/jpg.width;
    }
    else
    {
      // bmp -- totally untested
      ratio = 1.0*image->height/image->width;
    }
    int width = 128, height = 128*ratio;
    pixbuf = gdk_pixbuf_scale_simple(tmp, width, height, GDK_INTERP_BILINEAR);

    if(loader)
      g_object_unref(loader);

    // clean up raw stuff.
    libraw_recycle(raw);
    libraw_close(raw);
    free(image);
    if(0)
    {
libraw_fail:
      // fprintf(stderr,"[imageio] %s: %s\n", filename, libraw_strerror(ret));
      libraw_close(raw);
      have_preview = FALSE;
    }
  }
  if(!have_preview)
  {
no_preview_fallback:
    pixbuf = gdk_pixbuf_new_from_inline(-1, dt_logo_128x128, FALSE, NULL);
    have_preview = TRUE;
  }
  if(have_preview)
    gtk_image_set_from_pixbuf(GTK_IMAGE(preview), pixbuf);
  if(pixbuf)
    g_object_unref(pixbuf);
  g_free(filename);

  gtk_file_chooser_set_preview_widget_active(file_chooser, have_preview);
}
Exemplo n.º 4
0
static void
_init_8(
  uint8_t                *buf,
  uint32_t               *width,
  uint32_t               *height,
  const uint32_t          imgid,
  const dt_mipmap_size_t  size)
{
  const uint32_t wd = *width, ht = *height;
  char filename[DT_MAX_PATH_LEN] = {0};

  /* do not even try to process file if it isnt available */
  dt_image_full_path(imgid, filename, DT_MAX_PATH_LEN);
  if (strlen(filename) == 0 || !g_file_test(filename, G_FILE_TEST_EXISTS))
  {
    *width = *height = 0;
    return;
  }

  const int altered = dt_image_altered(imgid);
  int res = 1;

  const dt_image_t *cimg = dt_image_cache_read_get(darktable.image_cache, imgid);
  const int orientation = dt_image_orientation(cimg);
  // the orientation for this camera is not read correctly from exiv2, so we need
  // to go the full libraw path (as the thumbnail will be flipped the wrong way round)
  const int incompatible = !strncmp(cimg->exif_maker, "Phase One", 9);
  dt_image_cache_read_release(darktable.image_cache, cimg);


  // first try exif thumbnail, that's smaller and thus faster to load:
  if(!altered && !dt_conf_get_bool("never_use_embedded_thumb") &&
     !dt_exif_thumbnail(filename, buf, wd, ht, orientation, width, height))
  {
    res = 0;
  }
  else if(!altered && !dt_conf_get_bool("never_use_embedded_thumb") && !incompatible)
  {
    // try to load the embedded thumbnail in raw
    int ret;
    memset(filename, 0, DT_MAX_PATH_LEN);
    dt_image_full_path(imgid, filename, DT_MAX_PATH_LEN);

    const char *c = filename + strlen(filename);
    while(*c != '.' && c > filename) c--;
    if(!strcasecmp(c, ".jpg"))
    {
      // try to load jpg
      dt_imageio_jpeg_t jpg;
      if(!dt_imageio_jpeg_read_header(filename, &jpg))
      {
        uint8_t *tmp = (uint8_t *)malloc(sizeof(uint8_t)*jpg.width*jpg.height*4);
        if(!dt_imageio_jpeg_read(&jpg, tmp))
        {
          // scale to fit
          dt_iop_flip_and_zoom_8(tmp, jpg.width, jpg.height, buf, wd, ht, orientation, width, height);
          res = 0;
        }
        free(tmp);
      }
    }
    else
    {
      // raw image thumbnail
      libraw_data_t *raw = libraw_init(0);
      libraw_processed_image_t *image = NULL;
      ret = libraw_open_file(raw, filename);
      if(ret) goto libraw_fail;
      ret = libraw_unpack_thumb(raw);
      if(ret) goto libraw_fail;
      ret = libraw_adjust_sizes_info_only(raw);
      if(ret) goto libraw_fail;

      image = libraw_dcraw_make_mem_thumb(raw, &ret);
      if(!image || ret) goto libraw_fail;
      const int orientation = raw->sizes.flip;
      if(image->type == LIBRAW_IMAGE_JPEG)
      {
        // JPEG: decode (directly rescaled to mip4)
        dt_imageio_jpeg_t jpg;
        if(dt_imageio_jpeg_decompress_header(image->data, image->data_size, &jpg)) goto libraw_fail;
        uint8_t *tmp = (uint8_t *)malloc(sizeof(uint8_t)*jpg.width*jpg.height*4);
        if(dt_imageio_jpeg_decompress(&jpg, tmp))
        {
          free(tmp);
          goto libraw_fail;
        }
        // scale to fit
        dt_iop_flip_and_zoom_8(tmp, jpg.width, jpg.height, buf, wd, ht, orientation, width, height);

        free(tmp);
        res = 0;
      }

      // clean up raw stuff.
      libraw_recycle(raw);
      libraw_close(raw);
      free(image);
      if(0)
      {
libraw_fail:
        // fprintf(stderr,"[imageio] %s: %s\n", filename, libraw_strerror(ret));
        libraw_close(raw);
        res = 1;
      }
    }
  }

  if(res)
  {
    // try the real thing: rawspeed + pixelpipe
    dt_imageio_module_format_t format;
    _dummy_data_t dat;
    format.bpp = _bpp;
    format.write_image = _write_image;
    format.levels = _levels;
    dat.head.max_width  = wd;
    dat.head.max_height = ht;
    dat.buf = buf;
    // export with flags: ignore exif (don't load from disk), don't swap byte order, don't do hq processing, and signal we want thumbnail export
    res = dt_imageio_export_with_flags(imgid, "unused", &format, (dt_imageio_module_data_t *)&dat, 1, 1, 0, 1, NULL);
    if(!res)
    {
      // might be smaller, or have a different aspect than what we got as input.
      *width  = dat.head.width;
      *height = dat.head.height;
    }
  }

  // fprintf(stderr, "[mipmap init 8] export image %u finished (sizes %d %d => %d %d)!\n", imgid, wd, ht, dat.head.width, dat.head.height);

  // any errors?
  if(res)
  {
    // fprintf(stderr, "[mipmap_cache] could not process thumbnail!\n");
    *width = *height = 0;
    return;
  }

  // TODO: various speed optimizations:
  // TODO: also init all smaller mips!
  // TODO: use mipf, but:
  // TODO: if output is cropped, don't use mipf!
}
Exemplo n.º 5
0
static GthImage *
_cairo_image_surface_create_from_raw (GInputStream  *istream,
                                      GthFileData   *file_data,
                                      int            requested_size,
                                      int           *original_width,
                                      int           *original_height,
                                      gpointer       user_data,
                                      GCancellable  *cancellable,
                                      GError       **error)
{
    libraw_data_t *raw_data;
    int            result;
    void          *buffer = NULL;
    size_t         size;
    GthImage      *image = NULL;

    raw_data = libraw_init (LIBRAW_OPIONS_NO_MEMERR_CALLBACK | LIBRAW_OPIONS_NO_DATAERR_CALLBACK);
    if (raw_data == NULL) {
        _libraw_set_gerror (error, errno);
        goto fatal_error;
    }

    libraw_set_progress_handler (raw_data, _libraw_progress_cb, cancellable);

    if (! _g_input_stream_read_all (istream, &buffer, &size, cancellable, error))
        goto fatal_error;

    raw_data->params.output_tiff = FALSE;
    raw_data->params.use_camera_wb = TRUE;
    raw_data->params.use_rawspeed = TRUE;
    raw_data->params.highlight = FALSE;
    raw_data->params.use_camera_matrix = TRUE;
    raw_data->params.output_color = RAW_OUTPUT_COLOR_SRGB;
    raw_data->params.output_bps = 8;
    raw_data->params.half_size = (requested_size > 0);

    result = libraw_open_buffer (raw_data, buffer, size);
    if (LIBRAW_FATAL_ERROR (result)) {
        _libraw_set_gerror (error, result);
        goto fatal_error;
    }

    /*  */

#if RAW_USE_EMBEDDED_THUMBNAIL

    if (requested_size > 0) {

        /* read the thumbnail */

        result = libraw_unpack_thumb (raw_data);
        if (result != LIBRAW_SUCCESS) {
            _libraw_set_gerror (error, result);
            goto fatal_error;
        }

        switch (raw_data->thumbnail.tformat) {
        case LIBRAW_THUMBNAIL_JPEG:
            image = _libraw_read_jpeg_data (raw_data->thumbnail.thumb,
                                            raw_data->thumbnail.tlength,
                                            requested_size,
                                            cancellable,
                                            error);
            break;
        case LIBRAW_THUMBNAIL_BITMAP:
            image = _libraw_read_bitmap_data (raw_data->thumbnail.twidth,
                                              raw_data->thumbnail.theight,
                                              raw_data->thumbnail.tcolors,
                                              8,
                                              (guchar *) raw_data->thumbnail.thumb,
                                              raw_data->thumbnail.tlength);
            break;
        default:
            g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Unsupported data format");
            break;
        }

        if ((image != NULL) && (_libraw_get_tranform (raw_data) != GTH_TRANSFORM_NONE)) {
            cairo_surface_t *surface;
            cairo_surface_t *rotated;

            surface = gth_image_get_cairo_surface (image);
            rotated = _cairo_image_surface_transform (surface, _libraw_get_tranform (raw_data));
            gth_image_set_cairo_surface (image, rotated);

            cairo_surface_destroy (rotated);
            cairo_surface_destroy (surface);
        }
    }
    else

#endif

    {
        /* read the image */

        libraw_processed_image_t *processed_image;

        result = libraw_unpack (raw_data);
        if (result != LIBRAW_SUCCESS) {
            _libraw_set_gerror (error, result);
            goto fatal_error;
        }

        result = libraw_dcraw_process (raw_data);
        if (result != LIBRAW_SUCCESS) {
            _libraw_set_gerror (error, result);
            goto fatal_error;
        }

        processed_image = libraw_dcraw_make_mem_image (raw_data, &result);
        if (result != LIBRAW_SUCCESS) {
            _libraw_set_gerror (error, result);
            goto fatal_error;
        }

        switch (processed_image->type) {
        case LIBRAW_IMAGE_JPEG:
            image = _libraw_read_jpeg_data (processed_image->data,
                                            processed_image->data_size,
                                            -1,
                                            cancellable,
                                            error);
            break;
        case LIBRAW_IMAGE_BITMAP:
            image = _libraw_read_bitmap_data (processed_image->width,
                                              processed_image->height,
                                              processed_image->colors,
                                              processed_image->bits,
                                              processed_image->data,
                                              processed_image->data_size);
            break;
        default:
            g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Unsupported data format");
            break;
        }

        libraw_dcraw_clear_mem (processed_image);
    }

    /* get the original size */

    if ((original_width != NULL) && (original_height != NULL)) {
        result = libraw_adjust_sizes_info_only (raw_data);
        if (result != LIBRAW_SUCCESS) {
            _libraw_set_gerror (error, result);
            goto fatal_error;
        }

        *original_width = raw_data->sizes.iwidth;
        *original_height = raw_data->sizes.iheight;
    }

fatal_error:

    if (raw_data != NULL)
        libraw_close (raw_data);
    g_free (buffer);

    return image;
}