From bc5011e4e511f21ec10c6a16ae20d18ab473207f Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Tue, 13 Nov 2001 03:31:47 +0000 Subject: [PATCH] added some safety checks. 2001-11-13 Sven Neumann * app/base/temp-buf.c: added some safety checks. * app/widgets/Makefile.am * app/widgets/widgets-types.h * app/widgets/gimpimagefilepreview.[ch]: a new class implementing special GimpPreview methods for GimpImagefile. * app/core/gimpimagefile.c: added code to load thumbnails according to the proposed Thumbnail Managing Standard (see http://triq.net/~pearl/thumbnail-spec/). Pretty much untested. * app/widgets/gimpcontainerview-utils.c: plugged a memleak. * app/widgets/gimpimagepreview.c: simplified. * app/widgets/gimppreview.c: tell it about GimpImagefilePreview. --- ChangeLog | 19 ++ app/base/temp-buf.c | 36 +-- app/core/gimpimagefile.c | 298 +++++++++++++++++++++---- app/dialogs/dialogs-constructors.c | 2 +- app/gui/dialogs-constructors.c | 2 +- app/widgets/Makefile.am | 2 + app/widgets/gimpcontainerview-utils.c | 23 +- app/widgets/gimpimagefilepreview.c | 157 +++++++++++++ app/widgets/gimpimagefilepreview.h | 58 +++++ app/widgets/gimpimagepreview.c | 8 +- app/widgets/gimppreview.c | 19 +- app/widgets/gimppreviewrenderer.c | 19 +- app/widgets/gimppreviewrendererimage.c | 8 +- app/widgets/gimpview.c | 19 +- app/widgets/gimpviewrenderer.c | 19 +- app/widgets/gimpviewrendererimage.c | 8 +- app/widgets/widgets-types.h | 1 + 17 files changed, 564 insertions(+), 134 deletions(-) create mode 100644 app/widgets/gimpimagefilepreview.c create mode 100644 app/widgets/gimpimagefilepreview.h diff --git a/ChangeLog b/ChangeLog index 73b79d8b58..1b8a5a0faf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2001-11-13 Sven Neumann + + * app/base/temp-buf.c: added some safety checks. + + * app/widgets/Makefile.am + * app/widgets/widgets-types.h + * app/widgets/gimpimagefilepreview.[ch]: a new class implementing + special GimpPreview methods for GimpImagefile. + + * app/core/gimpimagefile.c: added code to load thumbnails according + to the proposed Thumbnail Managing Standard + (see http://triq.net/~pearl/thumbnail-spec/). Pretty much untested. + + * app/widgets/gimpcontainerview-utils.c: plugged a memleak. + + * app/widgets/gimpimagepreview.c: simplified. + + * app/widgets/gimppreview.c: tell it about GimpImagefilePreview. + 2001-11-13 Michael Natterer * app/core/Makefile.am: need to spell EXTRA_DIST correctly now diff --git a/app/base/temp-buf.c b/app/base/temp-buf.c index e44bbe043c..7f06eb85e5 100644 --- a/app/base/temp-buf.c +++ b/app/base/temp-buf.c @@ -129,6 +129,8 @@ temp_buf_new (gint width, guchar *data; TempBuf *temp; + g_return_val_if_fail (width > 0 && height > 0, NULL); + temp = g_new (TempBuf, 1); temp->width = width; @@ -200,17 +202,14 @@ temp_buf_new_check (gint width, GimpCheckType check_type, GimpCheckSize check_size) { - TempBuf *newbuf = NULL; - guchar *data = 0; - guchar check_shift = 0; - guchar fg_color = 0; - guchar bg_color = 0; - gint j, i = 0; + TempBuf *newbuf; + guchar *data; + guchar check_shift = 0; + guchar fg_color = 0; + guchar bg_color = 0; + gint i, j; - if (check_type < LIGHT_CHECKS || check_type > BLACK_ONLY) - g_error ("invalid check_type argument to temp_buf_check: %d", check_type); - if (check_size < SMALL_CHECKS || check_size > LARGE_CHECKS) - g_error ("invalid check_size argument to temp_buf_check: %d", check_size); + g_return_val_if_fail (width > 0 && height > 0, NULL); switch (check_size) { @@ -222,6 +221,7 @@ temp_buf_new_check (gint width, break; case LARGE_CHECKS: check_shift = 6; + break; } switch (check_type) @@ -254,7 +254,7 @@ temp_buf_new_check (gint width, newbuf = temp_buf_new (width, height, 3, 0, 0, NULL); data = temp_buf_data (newbuf); - for (j = 1; i <= height; j++) + for (i = 0, j = 1; i <= height; j++) { for (i = 1; i <= width; i++) { @@ -273,11 +273,7 @@ temp_buf_copy (TempBuf *src, TempBuf *new; glong length; - if (!src) - { - g_message ("trying to copy a temp buf which is NULL."); - return dest; - } + g_return_val_if_fail (src != NULL, NULL); if (!dest) { @@ -320,6 +316,9 @@ temp_buf_resize (TempBuf *buf, { gint size; + g_return_val_if_fail (buf != NULL, NULL); + g_return_val_if_fail (width > 0 && height > 0, NULL); + /* calculate the requested size */ size = width * height * bytes; @@ -363,6 +362,9 @@ temp_buf_scale (TempBuf *src, guchar *dest_data; TempBuf *dest; + g_return_val_if_fail (src != NULL, NULL); + g_return_val_if_fail (new_width > 0 && new_height > 0, NULL); + dest = temp_buf_new (new_width, new_height, src->bytes, @@ -469,6 +471,8 @@ temp_buf_copy_area (TempBuf *src, void temp_buf_free (TempBuf *temp_buf) { + g_return_if_fail (temp_buf != NULL); + if (temp_buf->data) g_free (temp_buf->data); diff --git a/app/core/gimpimagefile.c b/app/core/gimpimagefile.c index 8bac6698d1..e8714006c9 100644 --- a/app/core/gimpimagefile.c +++ b/app/core/gimpimagefile.c @@ -37,18 +37,44 @@ #include "gimpimagefile.h" +#include "libgimp/gimpintl.h" -static void gimp_imagefile_class_init (GimpImagefileClass *klass); -static void gimp_imagefile_init (GimpImagefile *imagefile); -static void gimp_imagefile_finalize (GObject *object); -static TempBuf * gimp_imagefile_get_new_preview (GimpViewable *viewable, - gint width, - gint height); -static guchar * readXVThumb (const gchar *filename, - gint *width, - gint *height, - gchar **imginfo); +typedef struct +{ + const gchar *dirname; + gint size; +} ThumbnailSize; + +static const ThumbnailSize thumb_sizes[] = +{ + { "48x48", 48 }, + { "64x64", 64 }, + { "96x96", 96 }, + { "128x128", 128 }, + { "144x144", 144 }, + { "160x160", 160 }, + { "192x192", 192 }, +}; + + +static void gimp_imagefile_class_init (GimpImagefileClass *klass); +static void gimp_imagefile_init (GimpImagefile *imagefile); +static TempBuf * gimp_imagefile_get_new_preview (GimpViewable *viewable, + gint width, + gint height); + +static TempBuf * gimp_imagefile_read_png_thumb (GimpImagefile *imagefile, + gint size); +static gchar * gimp_imagefile_png_thumb_name (const gchar *dirname, + const gchar *basename, + gint size); + +static TempBuf * gimp_imagefile_read_xv_thumb (GimpImagefile *imagefile); +static guchar * readXVThumb (const gchar *filename, + gint *width, + gint *height, + gchar **imginfo); static GimpViewableClass *parent_class = NULL; @@ -85,38 +111,23 @@ gimp_imagefile_get_type (void) static void gimp_imagefile_class_init (GimpImagefileClass *klass) { - GObjectClass *object_class; GimpViewableClass *viewable_class; - object_class = G_OBJECT_CLASS (klass); - viewable_class = GIMP_VIEWABLE_CLASS (klass); - parent_class = g_type_class_peek_parent (klass); - viewable_class->get_new_preview = gimp_imagefile_get_new_preview; + viewable_class = GIMP_VIEWABLE_CLASS (klass); - object_class->finalize = gimp_imagefile_finalize; + viewable_class->get_new_preview = gimp_imagefile_get_new_preview; } static void gimp_imagefile_init (GimpImagefile *imagefile) { - imagefile->width = -1; - imagefile->height = -1; + imagefile->width = 0; + imagefile->height = 0; imagefile->size = -1; } -static void -gimp_imagefile_finalize (GObject *object) -{ - GimpImagefile *imagefile; - - imagefile = GIMP_IMAGEFILE (object); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); -} - GimpImagefile * gimp_imagefile_new (const gchar *filename) { @@ -131,32 +142,213 @@ gimp_imagefile_new (const gchar *filename) return imagefile; } +static void +gimp_imagefile_set_info (GimpImagefile *imagefile, + gint width, + gint height, + gint size) +{ + gboolean changed; + + changed = (imagefile->width != width || imagefile->height != height || + imagefile->size != size); + + imagefile->width = width; + imagefile->height = height; + imagefile->size = size; + + /* emit a name changed signal so the container view updates */ + if (changed) + gimp_object_name_changed (GIMP_OBJECT (imagefile)); +} + +static void +gimp_imagefile_set_info_from_pixbuf (GimpImagefile *imagefile, + GdkPixbuf *pixbuf) +{ + const gchar *option; + gint img_width; + gint img_height; + gint img_size; + + option = gdk_pixbuf_get_option (pixbuf, "tEXt::OriginalWidth"); + if (!option || sscanf (option, "%d", &img_width) != 1) + img_width = 0; + + option = gdk_pixbuf_get_option (pixbuf, "tEXt::OriginalHeight"); + if (!option || sscanf (option, "%d", &img_height) != 1) + img_height = 0; + + option = gdk_pixbuf_get_option (pixbuf, "tEXt::OriginalSize"); + if (!option || sscanf (option, "%d", &img_size) != 1) + img_size = -1; + + gimp_imagefile_set_info (imagefile, img_width, img_height, img_size); +} + static TempBuf * gimp_imagefile_get_new_preview (GimpViewable *viewable, gint width, gint height) { GimpImagefile *imagefile; + TempBuf *temp_buf; + + imagefile = GIMP_IMAGEFILE (viewable); + + g_return_val_if_fail (GIMP_OBJECT (imagefile)->name != NULL, NULL); + + temp_buf = gimp_imagefile_read_png_thumb (imagefile, MAX (width, height)); + + if (!temp_buf) + temp_buf = gimp_imagefile_read_xv_thumb (imagefile); + + return temp_buf; +} + + +/* PNG thumbnail reading routines according to the + Thumbnail Managing Standard http://triq.net/~pearl/thumbnail-spec/ */ + +static TempBuf * +gimp_imagefile_read_png_thumb (GimpImagefile *imagefile, + gint size) +{ + TempBuf *temp_buf; + GdkPixbuf *pixbuf; + gchar *basename; + gchar *dirname; + gchar *fullname; + gchar *thumbname; + gint width; + gint height; + gint bytes; + gint y; + guchar *src; + guchar *dest; + GError *error; + + fullname = g_strconcat (GIMP_OBJECT (imagefile)->name, ".png", NULL); + + dirname = g_path_get_dirname (GIMP_OBJECT (imagefile)->name); + basename = g_path_get_basename (fullname); + + thumbname = gimp_imagefile_png_thumb_name (dirname, + basename, + size); + g_free (dirname); + g_free (basename); + + if (!thumbname) + thumbname = gimp_imagefile_png_thumb_name (g_get_home_dir(), + fullname, + size); + + g_free (fullname); + + if (!thumbname) + return NULL; + + pixbuf = gdk_pixbuf_new_from_file (thumbname, &error); + + if (!pixbuf) + { + g_message (_("Couldn't open thumbnail file '%s'\n%s"), + thumbname, error->message); + g_free (thumbname); + g_error_free (error); + return NULL; + } + + g_free (thumbname); + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + bytes = gdk_pixbuf_get_n_channels (pixbuf); + + temp_buf = temp_buf_new (width, height, bytes, 0, 0, NULL); + + dest = temp_buf_data (temp_buf); + src = gdk_pixbuf_get_pixels (pixbuf); + + for (y = 0; y < height; y++) + { + memcpy (dest, src, width * bytes); + dest += width * bytes; + src += gdk_pixbuf_get_rowstride (pixbuf); + } + + gimp_imagefile_set_info_from_pixbuf (imagefile, pixbuf); + + g_object_unref (pixbuf); + + return temp_buf; +} + +static gchar * +gimp_imagefile_png_thumb_name (const gchar *dirname, + const gchar *basename, + gint size) +{ + gchar *thumbname; + gint i, n; + + n = G_N_ELEMENTS (thumb_sizes); + + for (i = 0; i < n && thumb_sizes[i].size < size; i++) + /* nothing */; + + n = i; + + for (i = n; i < G_N_ELEMENTS (thumb_sizes); i++) + { + thumbname = g_build_filename (dirname, + ".thumbnails", + thumb_sizes[i].dirname, + basename, NULL); + + if (g_file_test (thumbname, G_FILE_TEST_EXISTS)) + return thumbname; + + g_free (thumbname); + } + + for (i = n - 1; i >= 0; i--) + { + thumbname = g_build_filename (dirname, + ".thumbnails", + thumb_sizes[i].dirname, + basename, NULL); + + if (g_file_test (thumbname, G_FILE_TEST_EXISTS)) + return thumbname; + + g_free (thumbname); + } + + return NULL; +} + +/* xvpics thumbnail reading routines for backward compatibility */ + +static TempBuf * +gimp_imagefile_read_xv_thumb (GimpImagefile *imagefile) +{ gchar *basename; gchar *dirname; gchar *thumbname; struct stat file_stat; struct stat thumb_stat; - gint thumb_width; - gint thumb_height; + gint width; + gint height; gint x, y; gboolean thumb_may_be_outdated = FALSE; TempBuf *temp_buf; guchar *raw_thumb; guchar *src; guchar *dest; - guchar white[3] = { 0xff, 0xff, 0xff }; gchar *image_info = NULL; - imagefile = GIMP_IMAGEFILE (viewable); - - g_return_val_if_fail (GIMP_OBJECT (imagefile)->name != NULL, NULL); - dirname = g_path_get_dirname (GIMP_OBJECT (imagefile)->name); basename = g_path_get_basename (GIMP_OBJECT (imagefile)->name); @@ -177,41 +369,53 @@ gimp_imagefile_get_new_preview (GimpViewable *viewable, } } - raw_thumb = readXVThumb (thumbname, - &thumb_width, &thumb_height, &image_info); + raw_thumb = readXVThumb (thumbname, &width, &height, &image_info); g_free (thumbname); - /* FIXME: use image info */ - g_free (image_info); - if (!raw_thumb) return NULL; - /* FIXME: scale if necessary */ - temp_buf = temp_buf_new (width, height, 3, 0, 0, white); + if (image_info) + { + gint img_width; + gint img_height; + + if (sscanf (image_info, "%dx%d", &img_width, &img_height) != 2) + { + img_width = 0; + img_height = 0; + } + gimp_imagefile_set_info (imagefile, img_width, img_height, -1); + + g_free (image_info); + } + + temp_buf = temp_buf_new (width, height, 3, 0, 0, NULL); src = raw_thumb; dest = temp_buf_data (temp_buf); - for (y = 0; y < MIN (height, thumb_height); y++) + for (y = 0; y < height; y++) { - for (x = 0; x < MIN (width, thumb_width); x++) + for (x = 0; x < width; x++) { dest[x*3] = ((src[x]>>5)*255)/7; dest[x*3+1] = (((src[x]>>2)&7)*255)/7; dest[x*3+2] = ((src[x]&3)*255)/3; } - src += thumb_width; + src += width; dest += width * 3; } + g_free (raw_thumb); return temp_buf; } + /* The readXVThumb function source may be re-used under the XFree86-style license. */ -guchar * +static guchar * readXVThumb (const gchar *fnam, gint *w, gint *h, diff --git a/app/dialogs/dialogs-constructors.c b/app/dialogs/dialogs-constructors.c index 835bb19f34..7d099b2564 100644 --- a/app/dialogs/dialogs-constructors.c +++ b/app/dialogs/dialogs-constructors.c @@ -747,7 +747,7 @@ dialogs_document_history_new (GimpDialogFactory *factory, view = gimp_document_view_new (GIMP_VIEW_TYPE_LIST, context->gimp->documents, context, - 32, + 48, 5, 3, documents_show_context_menu); diff --git a/app/gui/dialogs-constructors.c b/app/gui/dialogs-constructors.c index 835bb19f34..7d099b2564 100644 --- a/app/gui/dialogs-constructors.c +++ b/app/gui/dialogs-constructors.c @@ -747,7 +747,7 @@ dialogs_document_history_new (GimpDialogFactory *factory, view = gimp_document_view_new (GIMP_VIEW_TYPE_LIST, context->gimp->documents, context, - 32, + 48, 5, 3, documents_show_context_menu); diff --git a/app/widgets/Makefile.am b/app/widgets/Makefile.am index eefec54b43..41b38492a7 100644 --- a/app/widgets/Makefile.am +++ b/app/widgets/Makefile.am @@ -66,6 +66,8 @@ libappwidgets_a_SOURCES = @STRIP_BEGIN@ \ gimphistogramview.h \ gimpimagedock.c \ gimpimagedock.h \ + gimpimagefilepreview.c \ + gimpimagefilepreview.h \ gimpimagepreview.c \ gimpimagepreview.h \ gimplayerlistitem.c \ diff --git a/app/widgets/gimpcontainerview-utils.c b/app/widgets/gimpcontainerview-utils.c index fd4721521d..c58c6f2160 100644 --- a/app/widgets/gimpcontainerview-utils.c +++ b/app/widgets/gimpcontainerview-utils.c @@ -337,26 +337,25 @@ gimp_container_view_imagefile_name_func (GtkWidget *widget, if (imagefile) { - gchar *basename; + gchar *name; - basename = g_path_get_basename (GIMP_OBJECT (imagefile)->name); + name = g_path_get_basename (GIMP_OBJECT (imagefile)->name); if (tooltip) *tooltip = g_strdup (GIMP_OBJECT (imagefile)->name); if (imagefile->width > 0 && imagefile->height > 0) { - return g_strdup_printf ("%s (%d x %d)", - basename, - imagefile->width, - imagefile->height); - } - else - { - return g_strdup (basename); - } + gchar *tmp = name; - g_free (basename); + name = g_strdup_printf ("%s (%d x %d)", + tmp, + imagefile->width, + imagefile->height); + g_free (tmp); + } + + return name; } } diff --git a/app/widgets/gimpimagefilepreview.c b/app/widgets/gimpimagefilepreview.c new file mode 100644 index 0000000000..d2a46c6abb --- /dev/null +++ b/app/widgets/gimpimagefilepreview.c @@ -0,0 +1,157 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpImagefilePreview Widget + * Copyright (C) 2001 Michael Natterer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "widgets-types.h" + +#include "base/temp-buf.h" + +#include "core/gimpimagefile.h" + +#include "gimpimagefilepreview.h" + + +static void gimp_imagefile_preview_class_init (GimpImagefilePreviewClass *klass); + +static void gimp_imagefile_preview_render (GimpPreview *preview); +static gboolean gimp_imagefile_preview_needs_popup (GimpPreview *preview); + + +static GimpPreviewClass *parent_class = NULL; + + +GType +gimp_imagefile_preview_get_type (void) +{ + static GType preview_type = 0; + + if (! preview_type) + { + static const GTypeInfo preview_info = + { + sizeof (GimpImagefilePreviewClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) gimp_imagefile_preview_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GimpImagefilePreview), + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + + preview_type = g_type_register_static (GIMP_TYPE_PREVIEW, + "GimpImagefilePreview", + &preview_info, 0); + } + + return preview_type; +} + +static void +gimp_imagefile_preview_class_init (GimpImagefilePreviewClass *klass) +{ + GimpPreviewClass *preview_class; + + preview_class = GIMP_PREVIEW_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + preview_class->render = gimp_imagefile_preview_render; + preview_class->needs_popup = gimp_imagefile_preview_needs_popup; +} + +static void +gimp_imagefile_preview_render (GimpPreview *preview) +{ + GimpImagefile *imagefile; + TempBuf *render_buf; + TempBuf *temp_buf; + + imagefile = GIMP_IMAGEFILE (preview->viewable); + + g_return_if_fail (preview->width > 0 && preview->height > 0); + + render_buf = gimp_viewable_get_new_preview (preview->viewable, + preview->width, + preview->height); + + if (!render_buf) + return; /* FIXME: render an empty image icon */ + + if (render_buf->width > preview->width || + render_buf->height > preview->height) + { + gdouble ratio; + gint width; + gint height; + + if (render_buf->width >= render_buf->height) + ratio = (gdouble) preview->width / (gdouble) render_buf->width; + else + ratio = (gdouble) preview->height / (gdouble) render_buf->height; + + width = RINT (ratio * render_buf->width); + height = RINT (ratio * render_buf->height); + + temp_buf = render_buf; + render_buf = temp_buf_scale (temp_buf, width, height); + temp_buf_free (temp_buf); + } + + if (render_buf->width != preview->width || + render_buf->height != preview->height) + { + gint x, y; + guchar white[4] = { 255, 255, 255, 255 }; + + x = (preview->width - render_buf->width) / 2; + y = (preview->height - render_buf->height) / 2; + + temp_buf = temp_buf_new (preview->width, preview->height, + render_buf->bytes, + 0, 0, + white); + + temp_buf_copy_area (render_buf, temp_buf, + 0, 0, + render_buf->width, + render_buf->height, + x, y); + + temp_buf_free (render_buf); + + render_buf = temp_buf; + } + + gimp_preview_render_and_flush (preview, render_buf, -1); + + temp_buf_free (render_buf); +} + +static gboolean +gimp_imagefile_preview_needs_popup (GimpPreview *preview) +{ + return FALSE; +} diff --git a/app/widgets/gimpimagefilepreview.h b/app/widgets/gimpimagefilepreview.h new file mode 100644 index 0000000000..35a92f4c9d --- /dev/null +++ b/app/widgets/gimpimagefilepreview.h @@ -0,0 +1,58 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpImagefilePreview Widget + * Copyright (C) 2001 Michael Natterer + * Sven Neumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_IMAGEFILE_PREVIEW_H__ +#define __GIMP_IMAGEFILE_PREVIEW_H__ + + +#include "gimppreview.h" + + +G_BEGIN_DECLS + +#define GIMP_TYPE_IMAGEFILE_PREVIEW (gimp_imagefile_preview_get_type ()) +#define GIMP_IMAGEFILE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_IMAGEFILE_PREVIEW, GimpImagefilePreview)) +#define GIMP_IMAGEFILE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_IMAGEFILE_PREVIEW, GimpImagefilePreviewClass)) +#define GIMP_IS_IMAGEFILE_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_IMAGEFILE_PREVIEW)) +#define GIMP_IS_IMAGEFILE_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_IMAGEFILE_PREVIEW)) +#define GIMP_IMAGEFILE_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_IMAGEFILE_PREVIEW, GimpImagefilePreviewClass)) + + +typedef struct _GimpImagefilePreviewClass GimpImagefilePreviewClass; + +struct _GimpImagefilePreview +{ + GimpPreview parent_instance; +}; + +struct _GimpImagefilePreviewClass +{ + GimpPreviewClass parent_class; +}; + + +GType gimp_imagefile_preview_get_type (void) G_GNUC_CONST; + + +G_END_DECLS + +#endif /* __GIMP_IMAGEFILE_PREVIEW_H__ */ diff --git a/app/widgets/gimpimagepreview.c b/app/widgets/gimpimagepreview.c index e70282db13..c2060d6d55 100644 --- a/app/widgets/gimpimagepreview.c +++ b/app/widgets/gimpimagepreview.c @@ -184,13 +184,7 @@ gimp_image_preview_render (GimpPreview *preview) temp_buf_free (render_buf); - gimp_preview_render_and_flush (preview, - temp_buf, - GIMP_IMAGE_PREVIEW (preview)->channel); - - temp_buf_free (temp_buf); - - return; + render_buf = temp_buf; } gimp_preview_render_and_flush (preview, diff --git a/app/widgets/gimppreview.c b/app/widgets/gimppreview.c index f6ec6a50ce..4cfb43be45 100644 --- a/app/widgets/gimppreview.c +++ b/app/widgets/gimppreview.c @@ -39,6 +39,7 @@ #include "core/gimpdrawable.h" #include "core/gimpgradient.h" #include "core/gimpimage.h" +#include "core/gimpimagefile.h" #include "core/gimpmarshal.h" #include "core/gimppalette.h" #include "core/gimppattern.h" @@ -52,6 +53,7 @@ #include "gimpdrawablepreview.h" #include "gimpgradientpreview.h" #include "gimpimagepreview.h" +#include "gimpimagefilepreview.h" #include "gimppalettepreview.h" #include "gimppatternpreview.h" #include "gimppreview.h" @@ -304,6 +306,10 @@ gimp_preview_new_by_type (GimpViewable *viewable) { preview = g_object_new (GIMP_TYPE_TOOL_INFO_PREVIEW, NULL); } + else if (GIMP_IS_IMAGEFILE (viewable)) + { + preview = g_object_new (GIMP_TYPE_IMAGEFILE_PREVIEW, NULL); + } else { preview = g_object_new (GIMP_TYPE_PREVIEW, NULL); @@ -902,14 +908,7 @@ gimp_preview_calc_size (GimpPreview *preview, if (! preview->dot_for_dot && xresolution != yresolution) { - if (xresolution < yresolution) - { - yratio *= xresolution / yresolution; - } - else - { - yratio *= yresolution / xresolution; - } + yratio *= xresolution / yresolution; } width = RINT (xratio * (gdouble) aspect_width); @@ -920,7 +919,9 @@ gimp_preview_calc_size (GimpPreview *preview, *return_width = width; *return_height = height; - *scaling_up = (xratio > 1.0) || (yratio > 1.0); + + if (scaling_up) + *scaling_up = (xratio > 1.0) || (yratio > 1.0); } void diff --git a/app/widgets/gimppreviewrenderer.c b/app/widgets/gimppreviewrenderer.c index f6ec6a50ce..4cfb43be45 100644 --- a/app/widgets/gimppreviewrenderer.c +++ b/app/widgets/gimppreviewrenderer.c @@ -39,6 +39,7 @@ #include "core/gimpdrawable.h" #include "core/gimpgradient.h" #include "core/gimpimage.h" +#include "core/gimpimagefile.h" #include "core/gimpmarshal.h" #include "core/gimppalette.h" #include "core/gimppattern.h" @@ -52,6 +53,7 @@ #include "gimpdrawablepreview.h" #include "gimpgradientpreview.h" #include "gimpimagepreview.h" +#include "gimpimagefilepreview.h" #include "gimppalettepreview.h" #include "gimppatternpreview.h" #include "gimppreview.h" @@ -304,6 +306,10 @@ gimp_preview_new_by_type (GimpViewable *viewable) { preview = g_object_new (GIMP_TYPE_TOOL_INFO_PREVIEW, NULL); } + else if (GIMP_IS_IMAGEFILE (viewable)) + { + preview = g_object_new (GIMP_TYPE_IMAGEFILE_PREVIEW, NULL); + } else { preview = g_object_new (GIMP_TYPE_PREVIEW, NULL); @@ -902,14 +908,7 @@ gimp_preview_calc_size (GimpPreview *preview, if (! preview->dot_for_dot && xresolution != yresolution) { - if (xresolution < yresolution) - { - yratio *= xresolution / yresolution; - } - else - { - yratio *= yresolution / xresolution; - } + yratio *= xresolution / yresolution; } width = RINT (xratio * (gdouble) aspect_width); @@ -920,7 +919,9 @@ gimp_preview_calc_size (GimpPreview *preview, *return_width = width; *return_height = height; - *scaling_up = (xratio > 1.0) || (yratio > 1.0); + + if (scaling_up) + *scaling_up = (xratio > 1.0) || (yratio > 1.0); } void diff --git a/app/widgets/gimppreviewrendererimage.c b/app/widgets/gimppreviewrendererimage.c index e70282db13..c2060d6d55 100644 --- a/app/widgets/gimppreviewrendererimage.c +++ b/app/widgets/gimppreviewrendererimage.c @@ -184,13 +184,7 @@ gimp_image_preview_render (GimpPreview *preview) temp_buf_free (render_buf); - gimp_preview_render_and_flush (preview, - temp_buf, - GIMP_IMAGE_PREVIEW (preview)->channel); - - temp_buf_free (temp_buf); - - return; + render_buf = temp_buf; } gimp_preview_render_and_flush (preview, diff --git a/app/widgets/gimpview.c b/app/widgets/gimpview.c index f6ec6a50ce..4cfb43be45 100644 --- a/app/widgets/gimpview.c +++ b/app/widgets/gimpview.c @@ -39,6 +39,7 @@ #include "core/gimpdrawable.h" #include "core/gimpgradient.h" #include "core/gimpimage.h" +#include "core/gimpimagefile.h" #include "core/gimpmarshal.h" #include "core/gimppalette.h" #include "core/gimppattern.h" @@ -52,6 +53,7 @@ #include "gimpdrawablepreview.h" #include "gimpgradientpreview.h" #include "gimpimagepreview.h" +#include "gimpimagefilepreview.h" #include "gimppalettepreview.h" #include "gimppatternpreview.h" #include "gimppreview.h" @@ -304,6 +306,10 @@ gimp_preview_new_by_type (GimpViewable *viewable) { preview = g_object_new (GIMP_TYPE_TOOL_INFO_PREVIEW, NULL); } + else if (GIMP_IS_IMAGEFILE (viewable)) + { + preview = g_object_new (GIMP_TYPE_IMAGEFILE_PREVIEW, NULL); + } else { preview = g_object_new (GIMP_TYPE_PREVIEW, NULL); @@ -902,14 +908,7 @@ gimp_preview_calc_size (GimpPreview *preview, if (! preview->dot_for_dot && xresolution != yresolution) { - if (xresolution < yresolution) - { - yratio *= xresolution / yresolution; - } - else - { - yratio *= yresolution / xresolution; - } + yratio *= xresolution / yresolution; } width = RINT (xratio * (gdouble) aspect_width); @@ -920,7 +919,9 @@ gimp_preview_calc_size (GimpPreview *preview, *return_width = width; *return_height = height; - *scaling_up = (xratio > 1.0) || (yratio > 1.0); + + if (scaling_up) + *scaling_up = (xratio > 1.0) || (yratio > 1.0); } void diff --git a/app/widgets/gimpviewrenderer.c b/app/widgets/gimpviewrenderer.c index f6ec6a50ce..4cfb43be45 100644 --- a/app/widgets/gimpviewrenderer.c +++ b/app/widgets/gimpviewrenderer.c @@ -39,6 +39,7 @@ #include "core/gimpdrawable.h" #include "core/gimpgradient.h" #include "core/gimpimage.h" +#include "core/gimpimagefile.h" #include "core/gimpmarshal.h" #include "core/gimppalette.h" #include "core/gimppattern.h" @@ -52,6 +53,7 @@ #include "gimpdrawablepreview.h" #include "gimpgradientpreview.h" #include "gimpimagepreview.h" +#include "gimpimagefilepreview.h" #include "gimppalettepreview.h" #include "gimppatternpreview.h" #include "gimppreview.h" @@ -304,6 +306,10 @@ gimp_preview_new_by_type (GimpViewable *viewable) { preview = g_object_new (GIMP_TYPE_TOOL_INFO_PREVIEW, NULL); } + else if (GIMP_IS_IMAGEFILE (viewable)) + { + preview = g_object_new (GIMP_TYPE_IMAGEFILE_PREVIEW, NULL); + } else { preview = g_object_new (GIMP_TYPE_PREVIEW, NULL); @@ -902,14 +908,7 @@ gimp_preview_calc_size (GimpPreview *preview, if (! preview->dot_for_dot && xresolution != yresolution) { - if (xresolution < yresolution) - { - yratio *= xresolution / yresolution; - } - else - { - yratio *= yresolution / xresolution; - } + yratio *= xresolution / yresolution; } width = RINT (xratio * (gdouble) aspect_width); @@ -920,7 +919,9 @@ gimp_preview_calc_size (GimpPreview *preview, *return_width = width; *return_height = height; - *scaling_up = (xratio > 1.0) || (yratio > 1.0); + + if (scaling_up) + *scaling_up = (xratio > 1.0) || (yratio > 1.0); } void diff --git a/app/widgets/gimpviewrendererimage.c b/app/widgets/gimpviewrendererimage.c index e70282db13..c2060d6d55 100644 --- a/app/widgets/gimpviewrendererimage.c +++ b/app/widgets/gimpviewrendererimage.c @@ -184,13 +184,7 @@ gimp_image_preview_render (GimpPreview *preview) temp_buf_free (render_buf); - gimp_preview_render_and_flush (preview, - temp_buf, - GIMP_IMAGE_PREVIEW (preview)->channel); - - temp_buf_free (temp_buf); - - return; + render_buf = temp_buf; } gimp_preview_render_and_flush (preview, diff --git a/app/widgets/widgets-types.h b/app/widgets/widgets-types.h index d33c4a37a8..9ac1f4ade5 100644 --- a/app/widgets/widgets-types.h +++ b/app/widgets/widgets-types.h @@ -115,6 +115,7 @@ typedef struct _GimpDialogFactory GimpDialogFactory; typedef struct _GimpPreview GimpPreview; typedef struct _GimpImagePreview GimpImagePreview; typedef struct _GimpDrawablePreview GimpDrawablePreview; +typedef struct _GimpImagefilePreview GimpImagefilePreview; typedef struct _GimpBrushPreview GimpBrushPreview; typedef struct _GimpNavigationPreview GimpNavigationPreview; typedef struct _GimpPatternPreview GimpPatternPreview;