mirror of
https://gitlab.gnome.org/GNOME/eog
synced 2024-10-19 14:34:42 +00:00
Adapted to new eog_image_save signature.
2003-12-21 Jens Finke <jens@triq.net> * collection/eog-collection-view.c (save_image_loading_finished): Adapted to new eog_image_save signature. * libeog/eog-file-selection.[ch] (eog_file_selection_add_filter): Attach GdkPixbufFormat to filter for further reference. (eog_file_selection_get_format): New function. * libeog/eog-image-jpeg.[ch] (get_tmp_filepath), (move_file_to_uri): New functions. (eog_image_jpeg_save), (eog_image_jpeg_save_lossless): Dump data to temporary file first and move it to final destination afterwards. * libeog/eog-image.[ch] (real_image_load): Set image status to failed if we read 0 bytes. (eog_image_save): Added GdkPixbufFormat parameter, better retrieving of target filetype. * viewer/eog-image-view.c (verb_SaveAs_cb): Get image format from file chooser. (save_uri): New function, which takes an additional GdkPixbufFormat parameter.
This commit is contained in:
parent
069c641c31
commit
7096d37abd
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
|||
2003-12-21 Jens Finke <jens@triq.net>
|
||||
|
||||
* collection/eog-collection-view.c (save_image_loading_finished):
|
||||
Adapted to new eog_image_save signature.
|
||||
|
||||
* libeog/eog-file-selection.[ch] (eog_file_selection_add_filter):
|
||||
Attach GdkPixbufFormat to filter for further reference.
|
||||
(eog_file_selection_get_format): New function.
|
||||
|
||||
* libeog/eog-image-jpeg.[ch] (get_tmp_filepath),
|
||||
(move_file_to_uri): New functions.
|
||||
(eog_image_jpeg_save),
|
||||
(eog_image_jpeg_save_lossless): Dump data to temporary file first
|
||||
and move it to final destination afterwards.
|
||||
|
||||
* libeog/eog-image.[ch] (real_image_load): Set image status to failed
|
||||
if we read 0 bytes.
|
||||
(eog_image_save): Added GdkPixbufFormat parameter, better
|
||||
retrieving of target filetype.
|
||||
|
||||
* viewer/eog-image-view.c (verb_SaveAs_cb): Get image format from
|
||||
file chooser.
|
||||
(save_uri): New function, which takes an additional
|
||||
GdkPixbufFormat parameter.
|
||||
|
||||
2003-12-19 Jens Finke <jens@triq.net>
|
||||
|
||||
* libeog/eog-image.c (eog_image_save): Update URI and clear
|
||||
|
|
|
@ -312,7 +312,7 @@ save_image_loading_finished (EogImage *image, gpointer data)
|
|||
|
||||
uri = eog_image_get_uri (image);
|
||||
|
||||
if (!eog_image_save (image, uri, &error)) {
|
||||
if (!eog_image_save (image, uri, NULL, &error)) {
|
||||
/* FIXME: indicate failed state to the user */
|
||||
}
|
||||
gnome_vfs_uri_unref (uri);
|
||||
|
|
|
@ -10,12 +10,13 @@
|
|||
#include <gtk/gtkhbox.h>
|
||||
#include <gtk/gtkstock.h>
|
||||
#include <gtk/gtkmessagedialog.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include "eog-hig-dialog.h"
|
||||
#include "eog-pixbuf-util.h"
|
||||
|
||||
static char* last_dir[] = { NULL, NULL };
|
||||
|
||||
#define FILE_FORMAT_KEY "file-format"
|
||||
|
||||
GNOME_CLASS_BOILERPLATE (EogFileSelection,
|
||||
eog_file_selection,
|
||||
GtkFileChooserDialog,
|
||||
|
@ -137,7 +138,7 @@ eog_file_selection_add_filter (GtkWidget *widget)
|
|||
gdk_pixbuf_format_get_name (format));
|
||||
gtk_file_filter_set_name (filter, filter_name);
|
||||
g_free (filter_name);
|
||||
|
||||
|
||||
mime_types = gdk_pixbuf_format_get_mime_types ((GdkPixbufFormat *) it->data);
|
||||
for (i = 0; mime_types[i] != NULL; i++) {
|
||||
gtk_file_filter_add_mime_type (filter, mime_types[i]);
|
||||
|
@ -154,6 +155,12 @@ eog_file_selection_add_filter (GtkWidget *widget)
|
|||
}
|
||||
g_strfreev (pattern);
|
||||
|
||||
/* attach GdkPixbufFormat to filter, see also
|
||||
* eog_file_selection_get_format. */
|
||||
g_object_set_data (G_OBJECT (filter),
|
||||
FILE_FORMAT_KEY,
|
||||
format);
|
||||
|
||||
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filesel), filter);
|
||||
|
||||
}
|
||||
|
@ -233,3 +240,19 @@ eog_folder_selection_new (void)
|
|||
|
||||
return filesel;
|
||||
}
|
||||
|
||||
GdkPixbufFormat*
|
||||
eog_file_selection_get_format (EogFileSelection *sel)
|
||||
{
|
||||
GtkFileFilter *filter;
|
||||
GdkPixbufFormat* format;
|
||||
|
||||
g_return_val_if_fail (EOG_IS_FILE_SELECTION (sel), NULL);
|
||||
|
||||
filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (sel));
|
||||
if (filter == NULL) return NULL;
|
||||
|
||||
format = g_object_get_data (G_OBJECT (filter), FILE_FORMAT_KEY);
|
||||
|
||||
return format;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _EOG_FILE_SELECTION_H_
|
||||
|
||||
#include <gtk/gtkfilechooserdialog.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -32,6 +33,8 @@ GtkWidget* eog_file_selection_new (GtkFileChooserAction action);
|
|||
|
||||
GtkWidget* eog_folder_selection_new (void);
|
||||
|
||||
GdkPixbufFormat* eog_file_selection_get_format (EogFileSelection *sel);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _EOG_FILE_SELECTION_H_ */
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#if HAVE_JPEG
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -46,11 +48,51 @@
|
|||
#endif
|
||||
#include "eog-image-private.h"
|
||||
|
||||
static char*
|
||||
get_tmp_filepath (void)
|
||||
{
|
||||
char *tmp_file;
|
||||
char *tmp_file_name;
|
||||
static int file_count = 0;
|
||||
|
||||
tmp_file_name = g_strdup_printf ("eog%i%i.tmp", getpid (), file_count++);
|
||||
tmp_file = g_build_filename (g_get_tmp_dir (), tmp_file_name, NULL);
|
||||
|
||||
g_free (tmp_file_name);
|
||||
|
||||
return tmp_file;
|
||||
}
|
||||
|
||||
static GnomeVFSResult
|
||||
move_file_to_uri (char *file_path, GnomeVFSURI *uri)
|
||||
{
|
||||
GnomeVFSResult result;
|
||||
GnomeVFSURI *source_uri;
|
||||
|
||||
source_uri = gnome_vfs_uri_new (file_path);
|
||||
|
||||
result = gnome_vfs_xfer_uri (source_uri,
|
||||
uri,
|
||||
GNOME_VFS_XFER_DELETE_ITEMS, /* delete source file */
|
||||
GNOME_VFS_XFER_ERROR_MODE_ABORT, /* abort on all errors */
|
||||
GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, /* we checked for existing
|
||||
file already */
|
||||
NULL, /* no progress callback */
|
||||
NULL);
|
||||
|
||||
gnome_vfs_uri_unref (source_uri);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
eog_image_jpeg_save (EogImage *image, const char *path, GError **error)
|
||||
eog_image_jpeg_save (EogImage *image, GnomeVFSURI *uri, GError **error)
|
||||
{
|
||||
EogImagePrivate *priv;
|
||||
GdkPixbuf *pixbuf;
|
||||
GnomeVFSResult vfs_result;
|
||||
char *tmp_path;
|
||||
struct jpeg_compress_struct cinfo;
|
||||
guchar *buf = NULL;
|
||||
guchar *ptr;
|
||||
|
@ -76,8 +118,9 @@ eog_image_jpeg_save (EogImage *image, const char *path, GError **error)
|
|||
if (pixbuf == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
outfile = fopen (path, "wb");
|
||||
|
||||
tmp_path = get_tmp_filepath ();
|
||||
outfile = fopen (tmp_path, "wb");
|
||||
if (outfile == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -151,19 +194,30 @@ eog_image_jpeg_save (EogImage *image, const char *path, GError **error)
|
|||
|
||||
fclose (outfile);
|
||||
|
||||
return TRUE;
|
||||
/* move temporary file to final destination */
|
||||
vfs_result = move_file_to_uri (tmp_path, uri);
|
||||
if (vfs_result != GNOME_VFS_OK) {
|
||||
g_set_error (error, EOG_IMAGE_ERROR,
|
||||
EOG_IMAGE_ERROR_VFS,
|
||||
gnome_vfs_result_to_string (vfs_result));
|
||||
}
|
||||
g_free (tmp_path);
|
||||
|
||||
return (vfs_result == GNOME_VFS_OK);
|
||||
}
|
||||
|
||||
gboolean
|
||||
eog_image_jpeg_save_lossless (EogImage *image, const char *path, GError **error)
|
||||
eog_image_jpeg_save_lossless (EogImage *image, GnomeVFSURI *uri, GError **error)
|
||||
{
|
||||
const char *img_path;
|
||||
int result;
|
||||
JXFORM_CODE trans_code = JXFORM_NONE;
|
||||
EogTransformType transformation;
|
||||
char *tmp_file;
|
||||
GnomeVFSResult vfs_result = GNOME_VFS_OK;
|
||||
|
||||
g_return_val_if_fail (EOG_IS_IMAGE (image), FALSE);
|
||||
g_return_val_if_fail (path != NULL, FALSE);
|
||||
g_return_val_if_fail (uri != NULL, FALSE);
|
||||
|
||||
img_path = gnome_vfs_uri_get_path (image->priv->uri);
|
||||
|
||||
|
@ -191,9 +245,32 @@ eog_image_jpeg_save_lossless (EogImage *image, const char *path, GError **error)
|
|||
}
|
||||
}
|
||||
|
||||
result = jpegtran ((char*) img_path, (char*) path, trans_code, error);
|
||||
/* We save the resulting jpeg file to a temporary location
|
||||
* first and move it to the final destination then. This way
|
||||
* can also overwrite a file.
|
||||
*/
|
||||
tmp_file = get_tmp_filepath ();
|
||||
g_print ("tmp_file: %s\n", tmp_file);
|
||||
|
||||
return (result == 0);
|
||||
result = jpegtran ((char*) img_path, (char*) tmp_file, trans_code, error);
|
||||
|
||||
if (result == 0) {
|
||||
/* image successfully written */
|
||||
vfs_result = move_file_to_uri (tmp_file, uri);
|
||||
if (vfs_result != GNOME_VFS_OK) {
|
||||
g_set_error (error, EOG_IMAGE_ERROR,
|
||||
EOG_IMAGE_ERROR_VFS,
|
||||
gnome_vfs_result_to_string (vfs_result));
|
||||
}
|
||||
}
|
||||
|
||||
if (g_file_test (tmp_file, G_FILE_TEST_EXISTS)) {
|
||||
gnome_vfs_unlink (tmp_file);
|
||||
}
|
||||
|
||||
g_free (tmp_file);
|
||||
|
||||
return ((result == 0) && (vfs_result == GNOME_VFS_OK));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,15 +6,16 @@
|
|||
#if HAVE_JPEG
|
||||
|
||||
#include <glib.h>
|
||||
#include <libgnomevfs/gnome-vfs.h>
|
||||
#include "eog-image.h"
|
||||
|
||||
/* This will include some specialized routines for JPEG images, to support
|
||||
saving and transformations better for this format. */
|
||||
|
||||
gboolean eog_image_jpeg_save (EogImage *image, const char *path, GError **error);
|
||||
gboolean eog_image_jpeg_save (EogImage *image, GnomeVFSURI *uri, GError **error);
|
||||
|
||||
/* This assumes that image represents a jpeg file on the local filesystem! */
|
||||
gboolean eog_image_jpeg_save_lossless (EogImage *image, const char *path, GError **error);
|
||||
gboolean eog_image_jpeg_save_lossless (EogImage *image, GnomeVFSURI *uri, GError **error);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -843,7 +843,7 @@ real_image_load (gpointer data)
|
|||
gnome_vfs_close (handle);
|
||||
gnome_vfs_file_info_unref (info);
|
||||
|
||||
if (failed) {
|
||||
if (failed || (bytes_read_total == 0)) {
|
||||
g_mutex_lock (priv->status_mutex);
|
||||
if (priv->image != NULL) {
|
||||
g_object_unref (priv->image);
|
||||
|
@ -855,6 +855,9 @@ real_image_load (gpointer data)
|
|||
if (error != NULL) {
|
||||
priv->error_message = g_strdup (error->message);
|
||||
}
|
||||
else if (bytes_read_total == 0) {
|
||||
priv->error_message = g_strdup (_("empty file"));
|
||||
}
|
||||
else {
|
||||
priv->error_message = NULL;
|
||||
}
|
||||
|
@ -1274,7 +1277,7 @@ get_save_file_type_by_suffix (const char *local_path)
|
|||
}
|
||||
|
||||
gboolean
|
||||
eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
|
||||
eog_image_save (EogImage *img, GnomeVFSURI *uri, GdkPixbufFormat *format, GError **error)
|
||||
{
|
||||
EogImagePrivate *priv;
|
||||
char *file;
|
||||
|
@ -1306,11 +1309,25 @@ eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
|
|||
_("Images can only be saved as local files."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* find file type for saving, according to filename suffix */
|
||||
|
||||
file = (char*) gnome_vfs_uri_get_path (uri); /* don't free file, it's a static string */
|
||||
|
||||
target_type = get_save_file_type_by_suffix (file);
|
||||
|
||||
/* determine type of file to write (eg. 'png') */
|
||||
if (format == NULL) {
|
||||
if (gnome_vfs_uri_equal (priv->uri, uri)) {
|
||||
/* we overwrite the same file, therefore we
|
||||
* can reuse the file type saved in the EogImage object. */
|
||||
target_type = g_strdup (priv->file_type);
|
||||
}
|
||||
else {
|
||||
/* find file type for saving, according to filename suffix */
|
||||
target_type = get_save_file_type_by_suffix (file);
|
||||
}
|
||||
}
|
||||
else {
|
||||
target_type = gdk_pixbuf_format_get_name (format);
|
||||
}
|
||||
|
||||
if (target_type == NULL) {
|
||||
g_set_error (error, GDK_PIXBUF_ERROR,
|
||||
GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
|
||||
|
@ -1321,8 +1338,8 @@ eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
|
|||
source_is_local = (priv->uri != NULL && is_local_uri (priv->uri));
|
||||
source_type = priv->file_type;
|
||||
|
||||
/* Check for some special cases, so that we use always the least intrusive method
|
||||
* for saving the image.
|
||||
/* Check for some special cases, so that we use always the
|
||||
* least intrusive method for saving the image.
|
||||
*/
|
||||
if ((g_ascii_strcasecmp (target_type, source_type) == 0) &&
|
||||
!eog_image_is_modified (img))
|
||||
|
@ -1334,11 +1351,11 @@ eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
|
|||
|
||||
vfs_result = gnome_vfs_xfer_uri (priv->uri,
|
||||
uri,
|
||||
GNOME_VFS_XFER_DEFAULT /* copy the data */,
|
||||
GNOME_VFS_XFER_ERROR_MODE_ABORT, /* abort on all errors */
|
||||
GNOME_VFS_XFER_DEFAULT /* copy the data */,
|
||||
GNOME_VFS_XFER_ERROR_MODE_ABORT, /* abort on all errors */
|
||||
GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, /* we checked for existing
|
||||
file already */
|
||||
NULL, /* no progress callback */
|
||||
NULL, /* no progress callback */
|
||||
NULL);
|
||||
result = (vfs_result == GNOME_VFS_OK);
|
||||
if (!result) {
|
||||
|
@ -1356,7 +1373,7 @@ eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
|
|||
/* If source is a local file and both are jpeg files,
|
||||
* then use lossless transformation through libjpeg.
|
||||
*/
|
||||
result = eog_image_jpeg_save_lossless (img, file, error);
|
||||
result = eog_image_jpeg_save_lossless (img, uri, error);
|
||||
|
||||
g_print ("loseless saving of %s to %s\n",
|
||||
gnome_vfs_uri_to_string (priv->uri, GNOME_VFS_URI_HIDE_NONE), file);
|
||||
|
@ -1368,7 +1385,7 @@ eog_image_save (EogImage *img, GnomeVFSURI *uri, GError **error)
|
|||
* libjpeg.
|
||||
*/
|
||||
g_print ("Save through jpeg library.\n");
|
||||
result = eog_image_jpeg_save (img, file, error);
|
||||
result = eog_image_jpeg_save (img, uri, error);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -75,6 +75,7 @@ gboolean eog_image_is_loaded (EogImage *img);
|
|||
/* saving API */
|
||||
gboolean eog_image_save (EogImage *img,
|
||||
GnomeVFSURI *uri,
|
||||
GdkPixbufFormat *format,
|
||||
GError **error);
|
||||
|
||||
/* query API */
|
||||
|
|
|
@ -117,6 +117,7 @@ enum {
|
|||
static void popup_menu_cb (gpointer data, guint action, GtkWidget *widget);
|
||||
static gint save_uri_cb (BonoboPersistFile *pf, const CORBA_char *text_uri,
|
||||
CORBA_Environment *ev, void *closure);
|
||||
static gboolean save_uri (EogImageView *view, const char *text_uri, GdkPixbufFormat *format);
|
||||
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -316,6 +317,7 @@ verb_SaveAs_cb (BonoboUIComponent *uic, gpointer user_data,
|
|||
GtkWidget *dlg;
|
||||
int response;
|
||||
gchar *filename = NULL;
|
||||
GdkPixbufFormat *format = NULL;
|
||||
|
||||
g_return_if_fail (EOG_IS_IMAGE_VIEW (user_data));
|
||||
|
||||
|
@ -330,14 +332,13 @@ verb_SaveAs_cb (BonoboUIComponent *uic, gpointer user_data,
|
|||
|
||||
if (response == GTK_RESPONSE_OK) {
|
||||
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
|
||||
format = eog_file_selection_get_format (EOG_FILE_SELECTION (dlg));
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dlg);
|
||||
|
||||
|
||||
|
||||
if (response == GTK_RESPONSE_OK) {
|
||||
save_uri_cb (NULL, filename, NULL, image_view);
|
||||
save_uri (image_view, filename, format);
|
||||
}
|
||||
|
||||
if (filename != NULL) {
|
||||
|
@ -1102,22 +1103,26 @@ static gint
|
|||
save_uri_cb (BonoboPersistFile *pf, const CORBA_char *text_uri,
|
||||
CORBA_Environment *ev, void *closure)
|
||||
{
|
||||
EogImageView *view;
|
||||
return save_uri (EOG_IMAGE_VIEW (closure), text_uri, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
save_uri (EogImageView *view, const char *text_uri, GdkPixbufFormat *format)
|
||||
{
|
||||
GnomeVFSURI *uri;
|
||||
GError *error = NULL;
|
||||
GtkWidget *dialog;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (EOG_IS_IMAGE_VIEW (closure), 1);
|
||||
g_return_val_if_fail (text_uri != NULL, 1);
|
||||
g_return_val_if_fail (EOG_IS_IMAGE_VIEW (view), FALSE);
|
||||
g_return_val_if_fail (text_uri != NULL, FALSE);
|
||||
|
||||
view = EOG_IMAGE_VIEW (closure);
|
||||
if (view->priv->image == NULL) return FALSE;
|
||||
|
||||
/* FIXME: what kind of escaping do we need here? */
|
||||
uri = gnome_vfs_uri_new (text_uri);
|
||||
|
||||
result = eog_image_save (view->priv->image, uri, &error);
|
||||
result = eog_image_save (view->priv->image, uri, format, &error);
|
||||
|
||||
if (result) {
|
||||
dialog = eog_hig_dialog_new (GTK_STOCK_DIALOG_INFO,
|
||||
|
|
Loading…
Reference in a new issue