Beispiel #1
0
static void
rotate_cb (GtkWidget *w, gint type)
{
  GdkPixbuf *new_pb = NULL;
  GdkPixbuf *pb = gtk_image_get_pixbuf (GTK_IMAGE (picture));

  if (!pb)
    {
      g_printerr ("picture: can't get pixbuf\n");
      return;
    }

  switch (type)
    {
    case ROTATE_LEFT:
      new_pb = gdk_pixbuf_rotate_simple (pb, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
      break;
    case ROTATE_RIGHT:
      new_pb = gdk_pixbuf_rotate_simple (pb, GDK_PIXBUF_ROTATE_CLOCKWISE);
      break;
    case ROTATE_FLIP_VERT:
      new_pb = gdk_pixbuf_flip (pb, FALSE);
      break;
    case ROTATE_FLIP_HOR:
      new_pb = gdk_pixbuf_flip (pb, TRUE);
      break;
    }

  if (new_pb)
    {
      gtk_image_set_from_pixbuf (GTK_IMAGE (picture), new_pb);
      g_object_unref (pb);
    }
}
Beispiel #2
0
/*
 * Returns a transformed image.
 */
GdkPixbuf *
_gdk_pixbuf_transform (GdkPixbuf    *src,
		       GthTransform  transform)
{
	GdkPixbuf *temp = NULL, *dest = NULL;

	if (src == NULL)
		return NULL;

	switch (transform) {
	case GTH_TRANSFORM_NONE:
		dest = src;
		g_object_ref (dest);
		break;
	case GTH_TRANSFORM_FLIP_H:
		dest = gdk_pixbuf_flip (src, TRUE);
		break;
	case GTH_TRANSFORM_ROTATE_180:
		dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
		break;
	case GTH_TRANSFORM_FLIP_V:
		dest = gdk_pixbuf_flip (src, FALSE);
		break;
	case GTH_TRANSFORM_TRANSPOSE:
		temp = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE);
		dest = gdk_pixbuf_flip (temp, TRUE);
		g_object_unref (temp);
		break;
	case GTH_TRANSFORM_ROTATE_90:
		dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE);
		break;
	case GTH_TRANSFORM_TRANSVERSE:
		temp = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE);
		dest = gdk_pixbuf_flip (temp, FALSE);
		g_object_unref (temp);
		break;
	case GTH_TRANSFORM_ROTATE_270:
		dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
		break;
	default:
		dest = src;
		g_object_ref (dest);
		break;
	}

	return dest;
}
Beispiel #3
0
static void set_image(GtkImage *canvas, char *file_name) {
  // TODO error handling
  GdkPixbuf *raw_pb = gdk_pixbuf_new_from_file(file_name, NULL);
  GdkPixbuf *rotated_pb = gdk_pixbuf_rotate_simple(raw_pb, 90);
  g_object_unref(G_OBJECT(raw_pb));

  gtk_image_set_from_pixbuf(canvas, rotated_pb);
}
Beispiel #4
0
void carmen_graphics_write_data_as_png(unsigned char *data, 
				       char *user_filename, int w, int h)
{
  GdkPixbuf *image, *rotated_image;

  image = gdk_pixbuf_new_from_data((guchar *)data, GDK_COLORSPACE_RGB,
				    FALSE, 8, h, w, h*3, pixbuf_destroyed, 
				    NULL);

  rotated_image = gdk_pixbuf_rotate_simple
    (image, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
  g_object_unref(image);  

  write_pixbuf_as_png(rotated_image, user_filename);
  g_object_unref(rotated_image);
}
Beispiel #5
0
void wibuti_widget_set_icon(WibutiWidget *self, GdkPixbuf *icon) { // TODO: fix memory leak
    if (self->use_icon) {
        if (icon == NULL) {
            gtk_image_clear(self->image_icon);
            self->icon = NULL;
        } else {
            GdkPixbuf *icon_tmp1 = gdk_pixbuf_scale_simple(icon, ICON_WIDTH, ICON_HEIGHT, GDK_INTERP_BILINEAR);
            self->icon = icon_tmp1;
            if (!self->is_active) {
                gdk_pixbuf_saturate_and_pixelate(icon_tmp1, icon_tmp1, 0, FALSE);
            }
            GdkPixbuf *icon_tmp2 = gdk_pixbuf_rotate_simple(icon_tmp1, self->angle);
            gtk_image_set_from_pixbuf(self->image_icon, icon_tmp2);
            g_object_unref(icon_tmp2);
        }
    }
}
Beispiel #6
0
/* ----------------------------------------------------
 * p_replace_pixbuf_by_flipped_pixbuf
 * ----------------------------------------------------
 */
static void
p_replace_pixbuf_by_flipped_pixbuf(GapPView *pv_ptr, gint32 flip_to_perform)
{
  GdkPixbuf *flipped_pixbuf;
  gboolean   horizontal;

  if(pv_ptr->pixbuf == NULL)
  {
    printf("ERROR cant flip pv_ptr->pixbuf becaus it is NULL\n");
    return;
  }
  
  flipped_pixbuf = NULL;
  switch(flip_to_perform)
  {
    case GAP_STB_FLIP_HOR:
      horizontal = TRUE;
      flipped_pixbuf = gdk_pixbuf_flip(pv_ptr->pixbuf
                                      ,horizontal
                                      );
      break;
    case GAP_STB_FLIP_VER:
      horizontal = FALSE;
      flipped_pixbuf = gdk_pixbuf_flip(pv_ptr->pixbuf
                                      ,horizontal
                                      );
      break;
    case GAP_STB_FLIP_BOTH:
      flipped_pixbuf = gdk_pixbuf_rotate_simple (pv_ptr->pixbuf
                                                ,GDK_PIXBUF_ROTATE_UPSIDEDOWN
                                                );
      break;
    default:
      break;
  }
  if(flipped_pixbuf)
  {
    /* free old (refresh) pixbuf if there is one
     * and replace by fliped variant
     */
    g_object_unref(pv_ptr->pixbuf);
    pv_ptr->pixbuf = flipped_pixbuf;
  }

}  /* end p_replace_pixbuf_by_flipped_pixbuf */
static GdkPixmap *generate_pixmap(unsigned char* image_data,
				  carmen_map_config_p config,
				  double zoom)
{
  GdkPixbuf *image, *rotated_image, *final_image;

  if (image_data == NULL) {
    carmen_warn("carmen_graphics_generate_pixmap was passed bad arguments.\n");
    return NULL;
  }

  image = gdk_pixbuf_new_from_data((guchar *)image_data, GDK_COLORSPACE_RGB,
				   FALSE, 8,  config->y_size, config->x_size,
				   config->y_size*3, pixbuf_destroyed, NULL);

  rotated_image = gdk_pixbuf_rotate_simple(image, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
  g_object_unref(image);

  final_image = gdk_pixbuf_scale_simple(rotated_image, config->x_size*zoom,
					config->y_size*zoom, GDK_INTERP_TILES);

  g_object_unref(rotated_image);

  if (map_pixmap)
    gdk_pixmap_unref(map_pixmap);
  map_pixmap = NULL;

  map_pixmap = gdk_pixmap_new(drawing_area->window, config->x_size*zoom,
			      config->y_size*zoom, -1);

  gdk_draw_pixbuf(map_pixmap,
		  drawing_area->style->fg_gc[GTK_WIDGET_STATE (drawing_area)],
		  final_image, 0, 0,
		  0, 0, -1, -1,
		  GDK_RGB_DITHER_NONE, 0, 0);

  g_object_unref(final_image);

  return map_pixmap;
}
Beispiel #8
0
GdkPixmap * 
carmen_graphics_generate_pixmap(GtkWidget* drawing_area, 
				unsigned char* data,
				carmen_map_config_p config, 
				double zoom) 
{
  GdkPixbuf *image, *rotated_image, *final_image;
  GdkPixmap *pixmap;
  int x_render_size, y_render_size;

  if (drawing_area == NULL || data == NULL) {
    carmen_warn("carmen_graphics_generate_pixmap was passed bad arguments.\n");
    return NULL;
  }

  image = gdk_pixbuf_new_from_data((guchar *)data, GDK_COLORSPACE_RGB,
				    FALSE, 8, config->y_size, config->x_size, 
				    config->y_size*3, pixbuf_destroyed, NULL);
  rotated_image = gdk_pixbuf_rotate_simple
    (image, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
  g_object_unref(image);

  x_render_size = zoom*config->x_size;
  y_render_size = zoom*config->y_size;

  final_image = gdk_pixbuf_scale_simple(rotated_image, x_render_size, 
					y_render_size, GDK_INTERP_BILINEAR);
  pixmap = gdk_pixmap_new
      (drawing_area->window, x_render_size, y_render_size, -1);

  gdk_draw_pixbuf(pixmap, drawing_area->style->fg_gc
		  [GTK_WIDGET_STATE (drawing_area)],
		  final_image, 0, 0, 0, 0, -1, -1, 
		  GDK_RGB_DITHER_NONE, 0, 0);

  g_object_unref(rotated_image);  
  g_object_unref(final_image);  

  return pixmap;
}
static struct graphics_image_priv *
image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h, struct point *hot, int rotation)
{
	GdkPixbuf *pixbuf;
	struct graphics_image_priv *ret;
	const char *option;
	
	if (!strcmp(name,"buffer:")) {
		struct graphics_image_buffer *buffer=(struct graphics_image_buffer *)name;
		GdkPixbufLoader *loader=gdk_pixbuf_loader_new();
		if (!loader)
			return NULL;
		if (*w != -1 || *h != -1)
			gdk_pixbuf_loader_set_size(loader, *w, *h);
		gdk_pixbuf_loader_write(loader, buffer->start, buffer->len, NULL);
		gdk_pixbuf_loader_close(loader, NULL);
		pixbuf=gdk_pixbuf_loader_get_pixbuf(loader);
		g_object_ref(pixbuf);
		g_object_unref(loader);
	} else {
		if (*w == -1 && *h == -1)
			pixbuf=gdk_pixbuf_new_from_file(name, NULL);
		else
			pixbuf=gdk_pixbuf_new_from_file_at_size(name, *w, *h, NULL);
	}

	if (!pixbuf)
		return NULL;

	if (rotation) {
		GdkPixbuf *tmp;
		switch (rotation) {
		case 90:
			rotation=270;
			break;
		case 180:
			break;
		case 270:
			rotation=90;
			break;
		default:
			return NULL;
		}

		tmp=gdk_pixbuf_rotate_simple(pixbuf, rotation);

		if (!tmp) {
			g_object_unref(pixbuf);
			return NULL;
		}

		g_object_unref(pixbuf);
		pixbuf=tmp;
	}

	ret=g_new0(struct graphics_image_priv, 1);
	ret->pixbuf=pixbuf;
	ret->w=gdk_pixbuf_get_width(pixbuf);
	ret->h=gdk_pixbuf_get_height(pixbuf);
	*w=ret->w;
	*h=ret->h;
	if (hot) {
		option=gdk_pixbuf_get_option(pixbuf, "x_hot");
		if (option)
			hot->x=atoi(option);
		else
			hot->x=ret->w/2-1;
		option=gdk_pixbuf_get_option(pixbuf, "y_hot");
		if (option)
			hot->y=atoi(option);
		else
			hot->y=ret->h/2-1;
	}
	return ret;
}
Beispiel #10
0
// 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, no_preview_fallback = FALSE;

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

  if(!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
  {
    no_preview_fallback = TRUE;
  }
  else
  {
    // 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")) no_preview_fallback = TRUE;
  }

  // unfortunately we can not use following, because frequently it uses wrong orientation
  // pixbuf = gdk_pixbuf_new_from_file_at_size(filename, 128, 128, NULL);

  have_preview = (pixbuf != NULL);
  if(!have_preview && !no_preview_fallback)
  {
    uint8_t *buffer = NULL;
    size_t size;
    char *mime_type = NULL;
    if(!dt_exif_get_thumbnail(filename, &buffer, &size, &mime_type))
    {
      // Scale the image to the correct size
      GdkPixbuf *tmp;
      GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
      if (!gdk_pixbuf_loader_write(loader, buffer, size, NULL)) goto cleanup;
      if (!(tmp = gdk_pixbuf_loader_get_pixbuf(loader))) goto cleanup;
      float ratio = 1.0 * gdk_pixbuf_get_height(tmp) / gdk_pixbuf_get_width(tmp);
      int width = 128, height = 128 * ratio;
      pixbuf = gdk_pixbuf_scale_simple(tmp, width, height, GDK_INTERP_BILINEAR);

      have_preview = TRUE;

    cleanup:
      gdk_pixbuf_loader_close(loader, NULL);
      free(mime_type);
      free(buffer);
      g_object_unref(loader); // This should clean up tmp as well
    }
  }
  if(have_preview && !no_preview_fallback)
  {
    // get image orientation
    dt_image_t img = { 0 };
    (void)dt_exif_read(&img, filename);

    // Rotate the image to the correct orientation
    GdkPixbuf *tmp = pixbuf;

    if(img.orientation == ORIENTATION_ROTATE_CCW_90_DEG)
    {
      tmp = gdk_pixbuf_rotate_simple(pixbuf, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
    }
    else if(img.orientation == ORIENTATION_ROTATE_CW_90_DEG)
    {
      tmp = gdk_pixbuf_rotate_simple(pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
    }
    else if(img.orientation == ORIENTATION_ROTATE_180_DEG)
    {
      tmp = gdk_pixbuf_rotate_simple(pixbuf, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
    }

    if(pixbuf != tmp)
    {
      g_object_unref(pixbuf);
      pixbuf = tmp;
    }
  }
  if(no_preview_fallback || !have_preview)
  {
    guint8 *image_buffer = NULL;

    /* load the dt logo as a brackground */
    char filename[PATH_MAX] = { 0 };
    char datadir[PATH_MAX] = { 0 };
    char *logo;
    dt_logo_season_t season = get_logo_season();
    if(season != DT_LOGO_SEASON_NONE)
      logo = g_strdup_printf("%%s/pixmaps/idbutton-%d.svg", (int)season);
    else
      logo = g_strdup("%s/pixmaps/idbutton.svg");

    dt_loc_get_datadir(datadir, sizeof(datadir));
    snprintf(filename, sizeof(filename), logo, datadir);
    g_free(logo);
    RsvgHandle *svg = rsvg_handle_new_from_file(filename, NULL);
    if(svg)
    {
      cairo_surface_t *surface;
      cairo_t *cr;

      RsvgDimensionData dimension;
      rsvg_handle_get_dimensions(svg, &dimension);

      float svg_size = MAX(dimension.width, dimension.height);
      float final_size = 128;
      float factor = final_size / svg_size;
      float final_width = dimension.width * factor * darktable.gui->ppd,
            final_height = dimension.height * factor * darktable.gui->ppd;
      int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, final_width);

      image_buffer = (guint8 *)calloc(stride * final_height, sizeof(guint8));
      surface = dt_cairo_image_surface_create_for_data(image_buffer, CAIRO_FORMAT_ARGB32, final_width,
                                                       final_height, stride);
      if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
      {
        free(image_buffer);
        image_buffer = NULL;
      }
      else
      {
        cr = cairo_create(surface);
        cairo_scale(cr, factor, factor);
        rsvg_handle_render_cairo(svg, cr);
        cairo_surface_flush(surface);
        pixbuf = gdk_pixbuf_get_from_surface(surface, 0, 0, final_width / darktable.gui->ppd,
                                             final_height / darktable.gui->ppd);
      }
      g_object_unref(svg);
    }

    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);
}
Beispiel #11
0
/**
 * gdk_pixbuf_apply_embedded_orientation:
 * @src: A #GdkPixbuf.
 *
 * Takes an existing pixbuf and checks for the presence of an
 * associated "orientation" option, which may be provided by the 
 * jpeg loader (which reads the exif orientation tag) or the 
 * tiff loader (which reads the tiff orientation tag, and
 * compensates it for the partial transforms performed by 
 * libtiff). If an orientation option/tag is present, the
 * appropriate transform will be performed so that the pixbuf
 * is oriented correctly.
 *
 * Return value: (transfer full): A newly-created pixbuf, or a reference to the
 * input pixbuf (with an increased reference count).
 *
 * Since: 2.12
 **/
GdkPixbuf *
gdk_pixbuf_apply_embedded_orientation (GdkPixbuf *src)
{
  	const gchar *orientation_string;
	int          transform = 0;
	GdkPixbuf   *temp;
	GdkPixbuf   *dest;

	g_return_val_if_fail (GDK_IS_PIXBUF (src), NULL);

	/* Read the orientation option associated with the pixbuf */
	orientation_string = gdk_pixbuf_get_option (src, "orientation");	

	if (orientation_string) {
		/* If an orientation option was found, convert the 
		   orientation string into an integer. */
		transform = (int) g_ascii_strtoll (orientation_string, NULL, 10);
	}

	/* Apply the actual transforms, which involve rotations and flips. 
	   The meaning of orientation values 1-8 and the required transforms
	   are defined by the TIFF and EXIF (for JPEGs) standards. */
        switch (transform) {
        case 1:
                dest = src;
                g_object_ref (dest);
                break;
        case 2:
                dest = gdk_pixbuf_flip (src, TRUE);
                break;
        case 3:
                dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
                break;
        case 4:
                dest = gdk_pixbuf_flip (src, FALSE);
                break;
        case 5:
                temp = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE);
                dest = gdk_pixbuf_flip (temp, TRUE);
                g_object_unref (temp);
                break;
        case 6:
                dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE);
                break;
        case 7:
                temp = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE);
                dest = gdk_pixbuf_flip (temp, FALSE);
                g_object_unref (temp);
                break;
        case 8:
                dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
                break;
        default:
		/* if no orientation tag was present */
                dest = src;
                g_object_ref (dest);
                break;
        }

        return dest;
}
Beispiel #12
0
static GObject* rotate_image(GObject* image, int degree)
{
	return (GObject*)gdk_pixbuf_rotate_simple(GDK_PIXBUF(image), (GdkPixbufRotation)degree);
}
Beispiel #13
0
// Updates the images according to preferences and the window situation
// Warning! This function is called very often, so it should only do the most necessary things!
void updateTitle(WTApplet *wtapplet) {
	WnckWindow *controlledwindow;
	gchar *title_text, *title_color, *title_font;
	GdkPixbuf *icon_pixbuf;
	
	if (wtapplet->prefs->only_maximized) {
		controlledwindow = wtapplet->umaxedwindow;
	} else {
		controlledwindow = wtapplet->activewindow;
	}

	if (controlledwindow == NULL)
		return;
	
	if (controlledwindow == wtapplet->rootwindow) {
		// we're on desktop
		if (wtapplet->prefs->hide_on_unmaximized) {
			// hide everything
			icon_pixbuf = NULL;
			title_text = "";
		} else {
			// display "custom" icon/title (TODO: customization via preferences?)
			icon_pixbuf = gtk_widget_render_icon(GTK_WIDGET(wtapplet),GTK_STOCK_HOME,GTK_ICON_SIZE_MENU,NULL); // This has to be unrefed!
			title_text = ("Desktop");
		}
	} else {
		icon_pixbuf = wnck_window_get_icon(controlledwindow); // This only returns a pointer - it SHOULDN'T be unrefed!
		title_text = (gchar*)wnck_window_get_name(controlledwindow);
	}
	
	// TODO: we need the default font to somehow be the same in both modes
	if (wtapplet->prefs->custom_style) {
		// custom style
		if (controlledwindow == wtapplet->activewindow) {
			// window focused
			title_color = wtapplet->prefs->title_active_color;
			title_font = wtapplet->prefs->title_active_font;
		} else {
			// window unfocused
			title_color = wtapplet->prefs->title_inactive_color;
			title_font = wtapplet->prefs->title_inactive_font;	
		}
	} else {
		// automatic (non-custom) style
		if (controlledwindow == wtapplet->activewindow) {
			// window focused				
			title_color = wtapplet->panel_color_fg;
			title_font = "";
		} else {
			// window unfocused
			title_color = "#808080"; // inactive title color. best fits for any panel regardless of color
			title_font = "";
		}		
	}

	// Set tooltips
	if (wtapplet->prefs->show_tooltips) {
		gtk_widget_set_tooltip_text (GTK_WIDGET(wtapplet->icon), title_text);
		gtk_widget_set_tooltip_text (GTK_WIDGET(wtapplet->title), title_text);
	}

	title_text = g_markup_printf_escaped("<span font=\"%s\" color=\"%s\">%s</span>", title_font, title_color, title_text);
	// Apply markup to label widget
	gtk_label_set_markup(GTK_LABEL(wtapplet->title), title_text);
	g_free(title_text);

	if (icon_pixbuf == NULL) {
		gtk_image_clear(wtapplet->icon);
	} else {
		// We're updating window info (Careful! We've had pixbuf memory leaks here)
		GdkPixbuf *ipb1 = gdk_pixbuf_scale_simple(icon_pixbuf, ICON_WIDTH, ICON_HEIGHT, GDK_INTERP_BILINEAR);
		if (controlledwindow == wtapplet->rootwindow) g_object_unref(icon_pixbuf); //this is stupid beyond belief, thanks to the retarded GTK framework
		GdkPixbuf *ipb2 = gdk_pixbuf_rotate_simple(ipb1, wtapplet->angle);
		g_object_unref(ipb1);	// Unref ipb1 to get it cleared from memory (we still need ipb2)

		// Saturate icon when window is not focused
		if (controlledwindow != wtapplet->activewindow) 
			gdk_pixbuf_saturate_and_pixelate(ipb2, ipb2, 0, FALSE);
		
		// Apply pixbuf to icon widget
		gtk_image_set_from_pixbuf(wtapplet->icon, ipb2);
		g_object_unref(ipb2);   // Unref ipb2 to get it cleared from memory			
	}
}
Beispiel #14
0
static gboolean bar_pane_gps_marker_keypress_cb(GtkWidget *widget, ClutterButtonEvent *bevent, gpointer data)
{
	//PaneGPSData *pgd = data;
	FileData *fd;
	ClutterActor *marker;
	ClutterColor marker_colour = { MARKER_COLOUR };
	ClutterColor text_colour = { TEXT_COLOUR };
	ClutterColor thumb_colour = { THUMB_COLOUR };
	gchar *current_text;
	ClutterActor *actor;
	ClutterActor *current_image;
	GString *text;
	gint height, width, rotate;
	gchar *altitude = NULL;
	ThumbLoader *tl;

	if (bevent->button == MOUSE_BUTTON_LEFT)
		{
		marker = CLUTTER_ACTOR(widget);
		fd = g_object_get_data(G_OBJECT(marker), "file_fd");

		/* If the marker is showing a thumbnail, delete it
		 */
		current_image = champlain_marker_get_image(CHAMPLAIN_MARKER(marker));
		if (current_image != NULL)
			{
			clutter_actor_destroy(CLUTTER_ACTOR(current_image));
		 	champlain_marker_set_image(CHAMPLAIN_MARKER(marker), NULL);
			}
			
		current_text = g_strdup(champlain_marker_get_text(CHAMPLAIN_MARKER(marker)));

		/* If the marker is showing only the text character, replace it with a
		 * thumbnail and date and altitude
		 */
		if (g_strcmp0(current_text, "i") == 0)
			{
			/* If a thumbail has already been generated, use that. If not try the pixbuf of the full image.
			 * If not, call the thumb_loader to generate a thumbnail and update the marker later in the
			 * thumb_loader callback
			 */
			 if (fd->thumb_pixbuf != NULL)
				{
				actor = clutter_texture_new();
				gtk_clutter_texture_set_from_pixbuf(CLUTTER_TEXTURE(actor), fd->thumb_pixbuf, NULL);
				champlain_marker_set_image(CHAMPLAIN_MARKER(marker), actor);
				}
			else if (fd->pixbuf != NULL)
				{
				actor = clutter_texture_new();
				width = gdk_pixbuf_get_width (fd->pixbuf);
				height = gdk_pixbuf_get_height (fd->pixbuf);
				switch (fd->exif_orientation)
					{
					case 8:
						rotate = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
						break;
					case 3:
						rotate = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
						break;
					case 6:
						rotate = GDK_PIXBUF_ROTATE_CLOCKWISE;
						break;
					default:
						rotate = GDK_PIXBUF_ROTATE_NONE;
					}
										
					gtk_clutter_texture_set_from_pixbuf(CLUTTER_TEXTURE(actor),
										gdk_pixbuf_rotate_simple(gdk_pixbuf_scale_simple(fd->pixbuf, THUMB_SIZE, height * THUMB_SIZE / width,
										GDK_INTERP_NEAREST), rotate), NULL);
					champlain_marker_set_image(CHAMPLAIN_MARKER(marker), actor);
				}
			else
				{
				tl = thumb_loader_new(THUMB_SIZE, THUMB_SIZE);
				thumb_loader_set_callbacks(tl,
											bar_pane_gps_thumb_done_cb,
											bar_pane_gps_thumb_error_cb,
											NULL,
											marker);
				thumb_loader_start(tl, fd);
				}
				
			text = g_string_new(fd->name);
			g_string_append(text, "\n");
			g_string_append(text, text_from_time(fd->date));
			g_string_append(text, "\n");
			altitude = metadata_read_string(fd, "formatted.GPSAltitude", METADATA_FORMATTED);
			if (altitude != NULL)
				{
				g_string_append(text, altitude);
				}

			champlain_marker_set_text(CHAMPLAIN_MARKER(marker), text->str);
			champlain_marker_set_color(CHAMPLAIN_MARKER(marker), &thumb_colour);
			champlain_marker_set_text_color(CHAMPLAIN_MARKER(marker), &text_colour);
			champlain_marker_set_font_name(CHAMPLAIN_MARKER(marker), "sans 8");

			g_free(altitude);
			g_string_free(text, TRUE);
			}
		/* otherwise, revert to the hidden text marker
		 */
		else
			{
			champlain_marker_set_text(CHAMPLAIN_MARKER(marker), "i");
			champlain_marker_set_color(CHAMPLAIN_MARKER(marker), &marker_colour);
			champlain_marker_set_text_color(CHAMPLAIN_MARKER(marker), &marker_colour);
			champlain_marker_set_font_name(CHAMPLAIN_MARKER(marker), "courier 5");
			}

		g_free(current_text);
		
		return TRUE;
		}
	return TRUE;
}
GdkPixbuf *
xplayer_gst_playbin_get_frame (GstElement *play)
{
  GstStructure *s;
  GstSample *sample = NULL;
  GdkPixbuf *pixbuf = NULL;
  GstCaps *to_caps, *sample_caps;
  gint outwidth = 0;
  gint outheight = 0;
  GstMemory *memory;
  GstMapInfo info;
  GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;

  g_return_val_if_fail (play != NULL, NULL);
  g_return_val_if_fail (GST_IS_ELEMENT (play), NULL);

  /* our desired output format (RGB24) */
  to_caps = gst_caps_new_simple ("video/x-raw",
      "format", G_TYPE_STRING, "RGB",
      /* Note: we don't ask for a specific width/height here, so that
       * videoscale can adjust dimensions from a non-1/1 pixel aspect
       * ratio to a 1/1 pixel-aspect-ratio. We also don't ask for a
       * specific framerate, because the input framerate won't
       * necessarily match the output framerate if there's a deinterlacer
       * in the pipeline. */
      "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
      NULL);

  /* get frame */
  g_signal_emit_by_name (play, "convert-sample", to_caps, &sample);
  gst_caps_unref (to_caps);

  if (!sample) {
    GST_DEBUG ("Could not take screenshot: %s",
        "failed to retrieve or convert video frame");
    g_warning ("Could not take screenshot: %s",
        "failed to retrieve or convert video frame");
    return NULL;
  }

  sample_caps = gst_sample_get_caps (sample);
  if (!sample_caps) {
    GST_DEBUG ("Could not take screenshot: %s", "no caps on output buffer");
    g_warning ("Could not take screenshot: %s", "no caps on output buffer");
    return NULL;
  }

  GST_DEBUG ("frame caps: %" GST_PTR_FORMAT, sample_caps);

  s = gst_caps_get_structure (sample_caps, 0);
  gst_structure_get_int (s, "width", &outwidth);
  gst_structure_get_int (s, "height", &outheight);
  if (outwidth <= 0 || outheight <= 0)
    goto done;

  memory = gst_buffer_get_memory (gst_sample_get_buffer (sample), 0);
  gst_memory_map (memory, &info, GST_MAP_READ);

  /* create pixbuf from that - use our own destroy function */
  pixbuf = gdk_pixbuf_new_from_data (info.data,
      GDK_COLORSPACE_RGB, FALSE, 8, outwidth, outheight,
      GST_ROUND_UP_4 (outwidth * 3), destroy_pixbuf, sample);

  gst_memory_unmap (memory, &info);

done:
  if (!pixbuf) {
    GST_DEBUG ("Could not take screenshot: %s", "could not create pixbuf");
    g_warning ("Could not take screenshot: %s", "could not create pixbuf");
    gst_sample_unref (sample);
  }

  /* Did we check whether we need to rotate the video? */
  if (g_object_get_data (G_OBJECT (play), "orientation-checked") == NULL) {
    GstTagList *tags = NULL;

    g_signal_emit_by_name (G_OBJECT (play), "get-video-tags", 0, &tags);
    if (tags) {
      char *orientation_str;
      gboolean ret;

      ret = gst_tag_list_get_string_index (tags, GST_TAG_IMAGE_ORIENTATION, 0, &orientation_str);
      if (!ret || !orientation_str)
        rotation = GDK_PIXBUF_ROTATE_NONE;
      else if (g_str_equal (orientation_str, "rotate-90"))
        rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
      else if (g_str_equal (orientation_str, "rotate-180"))
        rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
      else if (g_str_equal (orientation_str, "rotate-270"))
        rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;

      gst_tag_list_unref (tags);
    }

    g_object_set_data (G_OBJECT (play), "orientation-checked", GINT_TO_POINTER(1));
    g_object_set_data (G_OBJECT (play), "orientation", GINT_TO_POINTER(rotation));
  }

  rotation = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (play), "orientation"));
  if (rotation != GDK_PIXBUF_ROTATE_NONE) {
    GdkPixbuf *rotated;

    rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
    if (rotated) {
      g_object_unref (pixbuf);
      pixbuf = rotated;
    }
  }

  return pixbuf;
}
Beispiel #16
0
static GdkPixbuf* reorient_with_exif( producer_pixbuf self, int image_idx, GdkPixbuf *pixbuf )
{
#ifdef USE_EXIF
	mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( &self->parent );
	ExifData *d = exif_data_new_from_file( mlt_properties_get_value( self->filenames, image_idx ) );
	ExifEntry *entry;
	int exif_orientation = 0;

	/* get orientation and rotate image accordingly if necessary */
	if (d)
	{
		if ( ( entry = exif_content_get_entry ( d->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION ) ) )
			exif_orientation = exif_get_short (entry->data, exif_data_get_byte_order (d));

		/* Free the EXIF data */
		exif_data_unref(d);
	}

	// Remember EXIF value, might be useful for someone
	mlt_properties_set_int( producer_props, "_exif_orientation" , exif_orientation );

	if ( exif_orientation > 1 )
	{
		GdkPixbuf *processed = NULL;
		GdkPixbufRotation matrix = GDK_PIXBUF_ROTATE_NONE;

		// Rotate image according to exif data
		switch ( exif_orientation ) {
		  case 2:
			  processed = gdk_pixbuf_flip ( pixbuf, TRUE );
			  break;
		  case 3:
			  matrix = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
			  processed = pixbuf;
			  break;
		  case 4:
			  processed = gdk_pixbuf_flip ( pixbuf, FALSE );
			  break;
		  case 5:
			  matrix = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
			  processed = gdk_pixbuf_flip ( pixbuf, TRUE );
			  break;
		  case 6:
			  matrix = GDK_PIXBUF_ROTATE_CLOCKWISE;
			  processed = pixbuf;
			  break;
		  case 7:
			  matrix = GDK_PIXBUF_ROTATE_CLOCKWISE;
			  processed = gdk_pixbuf_flip ( pixbuf, TRUE );
			  break;
		  case 8:
			  matrix = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
			  processed = pixbuf;
			  break;
		}
		if ( processed )
		{
			pixbuf = gdk_pixbuf_rotate_simple( processed, matrix );
			g_object_unref( processed );
		}
	}
#endif
	return pixbuf;
}