Commit b2cd97b9 authored by Paolo Bacchilega's avatar Paolo Bacchilega Committed by Paolo Bacchilega
Browse files

new files

2005-11-18  Paolo Bacchilega  <paobac@cvs.gnome.org>

	* src/rotation-utils.c:
	* src/rotation-utils.h: new files

	* src/dlg-photo-importer.c:
	* src/dlg-jpegtran.c:
	* src/Makefile.am:
	* libgthumb/preferences.h:
	* data/glade/gthumb_camera.glade:
	* data/gthumb.schemas.in:

	Adjust photo orientation on import.  Patch by Andriy Kulchytskyy.
parent bac95b41
2005-11-18 Paolo Bacchilega <paobac@cvs.gnome.org>
* src/rotation-utils.c:
* src/rotation-utils.h: new files
* src/dlg-photo-importer.c:
* src/dlg-jpegtran.c:
* src/Makefile.am:
* libgthumb/preferences.h:
* data/glade/gthumb_camera.glade:
* data/gthumb.schemas.in:
Adjust photo orientation on import. Patch by Andriy Kulchytskyy.
2005-11-15 Paolo Bacchilega <paobac@cvs.gnome.org>
* src/gth-browser.c (save_jpeg_data): check whether the image is jpeg
......
......@@ -18,6 +18,7 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
......@@ -433,6 +434,7 @@
<property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
<property name="local_only">True</property>
<property name="show_hidden">False</property>
<property name="do_overwrite_confirmation">False</property>
<property name="width_chars">-1</property>
</widget>
<packing>
......@@ -666,6 +668,7 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
......
......@@ -1786,6 +1786,19 @@
</locale>
</schema>
<schema>
<key>/schemas/apps/gthumb/dialogs/photo_importer/adjust_orientation</key>
<applyto>/apps/gthumb/dialogs/photo_importer/adjust_orientation</applyto>
<owner>gthumb</owner>
<type>bool</type>
<default>TRUE</default>
<locale name="C">
<short></short>
<long>
</long>
</locale>
</schema>
<!-- Crop Dialog -->
<schema>
......
......@@ -192,6 +192,7 @@
#define PREF_PHOTO_IMPORT_FILM "/apps/gthumb/dialogs/photo_importer/film"
#define PREF_PHOTO_IMPORT_DELETE "/apps/gthumb/dialogs/photo_importer/delete_from_camera"
#define PREF_PHOTO_IMPORT_KEEP_FILENAMES "/apps/gthumb/dialogs/photo_importer/keep_original_filenames"
#define PREF_PHOTO_IMPORT_ADJUST_ORIENTATION "/apps/gthumb/dialogs/photo_importer/adjust_orientation"
#define PREF_PHOTO_IMPORT_MODEL "/apps/gthumb/dialogs/photo_importer/model"
#define PREF_PHOTO_IMPORT_PORT "/apps/gthumb/dialogs/photo_importer/port"
......
2005-11-18 Paolo Bacchilega <paobac@cvs.gnome.org>
* POTFILES.in: added missing files.
2005-11-14 Theppitak Karoonboonyanan <thep@linux.thai.net>
* th.po: Updated Thai translation.
......
......@@ -219,3 +219,7 @@ src/gtkcellrendererthreestates.h
src/lex.albumtheme.c
src/main.c
src/main.h
src/rotation-utils.c
src/rotation-utils.h
src/totem-scrsaver.c
src/totem-scrsaver.h
......@@ -131,7 +131,9 @@ gthumb_SOURCES = \
main.c \
main.h \
totem-scrsaver.c \
totem-scrsaver.h
totem-scrsaver.h \
rotation-utils.c \
rotation-utils.h
gthumb_LDADD = \
$(EXIF_LIBS) \
......@@ -184,7 +186,7 @@ libwebexporter_la_LDFLAGS = $(MODULE_LIBTOOL_FLAGS)
libphotoimporter_la_SOURCES = dlg-photo-importer.c dlg-photo-importer.h
libphotoimporter_la_LDFLAGS = $(MODULE_LIBTOOL_FLAGS)
libphotoimporter_la_LIBADD = $(top_builddir)/src/jpegutils/libgthumb-jpegutils.la
EXTRA_DIST = \
GNOME_GThumb.idl \
......
......@@ -53,6 +53,7 @@
#include "pixbuf-utils.h"
#include "gthumb-stock.h"
#include "gth-exif-utils.h"
#include "rotation-utils.h"
#define ROTATE_GLADE_FILE "gthumb_tools.glade"
......@@ -72,14 +73,13 @@ typedef struct {
GtkWidget *j_preview_image;
GtkWidget *j_from_exif_checkbutton;
GthTransform rot_type; /* 0, 90 ,180, 270 */
GthTransform tran_type; /* mirror, flip */
gboolean from_exif_data;
GList *file_list;
GList *files_changed_list;
GList *current_image;
ImageLoader *loader;
GdkPixbuf *original_preview;
RotationData *rot_data;
} DialogData;
......@@ -98,6 +98,7 @@ dialog_data_free (DialogData *data)
g_object_unref (data->loader);
if (data->gui != NULL)
g_object_unref (data->gui);
g_free (data->rot_data);
g_free (data);
}
......@@ -149,60 +150,6 @@ _gdk_pixbuf_scale_keep_aspect_ratio (GdkPixbuf *pixbuf,
}
static void
update_rotation_from_exif_data (DialogData *data,
GList *current_image)
{
#ifdef HAVE_LIBEXIF
FileData *fd = current_image->data;
GthExifOrientation orientation = get_exif_tag_short (fd->path, EXIF_TAG_ORIENTATION);
#endif /* HAVE_LIBEXIF */
data->rot_type = GTH_TRANSFORM_ROTATE_0;
data->tran_type = GTH_TRANSFORM_NONE;
#ifdef HAVE_LIBEXIF
switch (orientation) {
case GTH_EXIF_ORIENTATION_TOP_LEFT:
data->rot_type = GTH_TRANSFORM_ROTATE_0;
data->tran_type = GTH_TRANSFORM_NONE;
break;
case GTH_EXIF_ORIENTATION_TOP_RIGHT:
data->rot_type = GTH_TRANSFORM_ROTATE_0;
data->tran_type = GTH_TRANSFORM_MIRROR;
break;
case GTH_EXIF_ORIENTATION_BOTTOM_RIGHT:
data->rot_type = GTH_TRANSFORM_ROTATE_180;
data->tran_type = GTH_TRANSFORM_NONE;
break;
case GTH_EXIF_ORIENTATION_BOTTOM_LEFT:
data->rot_type = GTH_TRANSFORM_ROTATE_180;
data->tran_type = GTH_TRANSFORM_MIRROR;
break;
case GTH_EXIF_ORIENTATION_LEFT_TOP:
data->rot_type = GTH_TRANSFORM_ROTATE_90;
data->tran_type = GTH_TRANSFORM_MIRROR;
break;
case GTH_EXIF_ORIENTATION_RIGHT_TOP:
data->rot_type = GTH_TRANSFORM_ROTATE_90;
data->tran_type = GTH_TRANSFORM_NONE;
break;
case GTH_EXIF_ORIENTATION_RIGHT_BOTTOM:
data->rot_type = GTH_TRANSFORM_ROTATE_90;
data->tran_type = GTH_TRANSFORM_FLIP;
break;
case GTH_EXIF_ORIENTATION_LEFT_BOTTOM:
data->rot_type = GTH_TRANSFORM_ROTATE_270;
data->tran_type = GTH_TRANSFORM_NONE;
break;
default:
data->rot_type = GTH_TRANSFORM_ROTATE_0;
data->tran_type = GTH_TRANSFORM_NONE;
break;
}
#endif /* HAVE_LIBEXIF */
}
static void
update_from_exif_data (DialogData *data)
......@@ -217,14 +164,13 @@ update_from_exif_data (DialogData *data)
if (! from_exif)
return;
update_rotation_from_exif_data (data, data->current_image);
update_rotation_from_exif_data (data->current_image->data, data->rot_data);
src_pixbuf = data->original_preview;
if (src_pixbuf == NULL)
return;
switch (data->rot_type) {
switch (data->rot_data->rot_type) {
case GTH_TRANSFORM_ROTATE_90:
dest_pixbuf = _gdk_pixbuf_copy_rotate_90 (src_pixbuf, FALSE);
break;
......@@ -242,7 +188,7 @@ update_from_exif_data (DialogData *data)
src_pixbuf = dest_pixbuf;
switch (data->tran_type) {
switch (data->rot_data->tran_type) {
case GTH_TRANSFORM_MIRROR:
dest_pixbuf = _gdk_pixbuf_copy_mirror (src_pixbuf, TRUE, FALSE);
break;
......@@ -312,8 +258,8 @@ load_current_image (DialogData *data)
image_loader_set_path (data->loader, fd->path);
image_loader_start (data->loader);
data->rot_type = GTH_TRANSFORM_ROTATE_0;
data->tran_type = GTH_TRANSFORM_NONE;
data->rot_data->rot_type = GTH_TRANSFORM_ROTATE_0;
data->rot_data->tran_type = GTH_TRANSFORM_NONE;
}
......@@ -335,190 +281,6 @@ load_next_image (DialogData *data)
}
#ifdef HAVE_LIBEXIF
static gboolean
swap_fields (ExifContent *content,
ExifTag tag1,
ExifTag tag2)
{
ExifEntry *entry1;
ExifEntry *entry2;
unsigned char *data;
unsigned int size;
entry1 = exif_content_get_entry (content, tag1);
if (entry1 == NULL)
return FALSE;
entry2 = exif_content_get_entry (content, tag2);
if (entry2 == NULL)
return FALSE;
data = entry1->data;
size = entry1->size;
entry1->data = entry2->data;
entry1->size = entry2->size;
entry2->data = data;
entry2->size = size;
return TRUE;
}
static ExifShort
get_next_value_rotation_90 (int value)
{
static ExifShort new_value [8] = {8, 7, 6, 5, 2, 1, 4, 3};
return new_value[value - 1];
}
static ExifShort
get_next_value_mirror (int value)
{
static ExifShort new_value [8] = {2, 1, 4, 3, 8, 7, 6, 5};
return new_value[value - 1];
}
static ExifShort
get_next_value_flip (int value)
{
static ExifShort new_value [8] = {4, 3, 2, 1, 6, 5, 8, 7};
return new_value[value - 1];
}
static void
swap_xy_exif_fields (const char *filename,
DialogData *data)
{
JPEGData *jdata;
ExifData *edata;
unsigned int i;
jdata = jpeg_data_new_from_file (filename);
if (jdata == NULL)
return;
edata = jpeg_data_get_exif_data (jdata);
if (edata == NULL) {
jpeg_data_unref (jdata);
return;
}
for (i = 0; i < EXIF_IFD_COUNT; i++) {
ExifContent *content = edata->ifd[i];
if ((content == NULL) || (content->count == 0))
continue;
swap_fields (content,
EXIF_TAG_RELATED_IMAGE_WIDTH,
EXIF_TAG_RELATED_IMAGE_LENGTH);
swap_fields (content,
EXIF_TAG_IMAGE_WIDTH,
EXIF_TAG_IMAGE_LENGTH);
swap_fields (content,
EXIF_TAG_PIXEL_X_DIMENSION,
EXIF_TAG_PIXEL_Y_DIMENSION);
swap_fields (content,
EXIF_TAG_X_RESOLUTION,
EXIF_TAG_Y_RESOLUTION);
swap_fields (content,
EXIF_TAG_FOCAL_PLANE_X_RESOLUTION,
EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION);
}
jpeg_data_save_file (jdata, filename);
exif_data_unref (edata);
jpeg_data_unref (jdata);
}
static void
update_orientation_field (const char *filename,
DialogData *data)
{
JPEGData *jdata;
ExifData *edata;
unsigned int i;
gboolean orientation_changed = FALSE;
jdata = jpeg_data_new_from_file (filename);
if (jdata == NULL)
return;
edata = jpeg_data_get_exif_data (jdata);
if (edata == NULL) {
jpeg_data_unref (jdata);
return;
}
for (i = 0; i < EXIF_IFD_COUNT; i++) {
ExifContent *content = edata->ifd[i];
ExifEntry *entry;
if ((content == NULL) || (content->count == 0))
continue;
entry = exif_content_get_entry (content, EXIF_TAG_ORIENTATION);
if (!orientation_changed && (entry != NULL)) {
ExifByteOrder byte_order;
ExifShort value;
byte_order = exif_data_get_byte_order (edata);
value = exif_get_short (entry->data, byte_order);
switch (data->rot_type) {
case GTH_TRANSFORM_ROTATE_90:
value = get_next_value_rotation_90 (value);
break;
case GTH_TRANSFORM_ROTATE_180:
value = get_next_value_rotation_90 (value);
value = get_next_value_rotation_90 (value);
break;
case GTH_TRANSFORM_ROTATE_270:
value = get_next_value_rotation_90 (value);
value = get_next_value_rotation_90 (value);
value = get_next_value_rotation_90 (value);
break;
default:
break;
}
switch (data->tran_type) {
case GTH_TRANSFORM_MIRROR:
value = get_next_value_mirror (value);
break;
case GTH_TRANSFORM_FLIP:
value = get_next_value_flip (value);
break;
default:
break;
}
exif_set_short (entry->data, byte_order, value);
orientation_changed = TRUE;
}
}
jpeg_data_save_file (jdata, filename);
exif_data_unref (edata);
jpeg_data_unref (jdata);
}
#endif
static void
notify_file_changed (DialogData *data,
const char *filename,
......@@ -533,246 +295,6 @@ notify_file_changed (DialogData *data,
}
static void
apply_tranformation_jpeg (DialogData *data,
GList *current_image,
gboolean notify_soon)
{
FileData *fd = current_image->data;
int rot_type = data->rot_type;
int tran_type = data->tran_type;
char *line;
char *tmp1, *tmp2;
static int count = 0;
GError *err = NULL;
GtkWindow *parent = GTK_WINDOW (data->dialog);
#ifdef HAVE_LIBJPEG
JXFORM_CODE transf;
#else
char *command;
#endif
char *e1, *e2;
if ((rot_type == GTH_TRANSFORM_ROTATE_0) && (tran_type == GTH_TRANSFORM_NONE))
return;
if (rot_type == GTH_TRANSFORM_ROTATE_0)
tmp1 = g_strdup (fd->path);
else {
tmp1 = g_strdup_printf ("%s/gthumb.%d.%d",
g_get_tmp_dir (),
getpid (),
count++);
#ifdef HAVE_LIBJPEG
switch (rot_type) {
case GTH_TRANSFORM_ROTATE_90:
transf = JXFORM_ROT_90;
break;
case GTH_TRANSFORM_ROTATE_180:
transf = JXFORM_ROT_180;
break;
case GTH_TRANSFORM_ROTATE_270:
transf = JXFORM_ROT_270;
break;
default:
transf = JXFORM_NONE;
break;
}
if (jpegtran (fd->path, tmp1, transf, &err) != 0) {
g_free (tmp1);
if (err != NULL)
_gtk_error_dialog_from_gerror_run (parent, &err);
return;
}
#else
switch (rot_type) {
case GTH_TRANSFORM_ROTATE_90:
command = "-rotate 90";
break;
case GTH_TRANSFORM_ROTATE_180:
command = "-rotate 180";
break;
case GTH_TRANSFORM_ROTATE_270:
command = "-rotate 270";
break;
default:
break;
}
e1 = shell_escape (tmp1);
e2 = shell_escape (fd->path);
line = g_strdup_printf ("jpegtran -copy all %s -outfile %s %s",
command, e1, e2);
g_spawn_command_line_sync (line, NULL, NULL, NULL, &err);
g_free (e1);
g_free (e2);
g_free (line);
if (err != NULL) {
g_free (tmp1);
_gtk_error_dialog_from_gerror_run (parent, &err);
return;
}
#endif
}
if (tran_type == GTH_TRANSFORM_NONE)
tmp2 = g_strdup (tmp1);
else {
tmp2 = g_strdup_printf ("%s/gthumb.%d.%d",
g_get_tmp_dir (),
getpid (),
count++);
#ifdef HAVE_LIBJPEG
switch (tran_type) {
case GTH_TRANSFORM_MIRROR:
transf = JXFORM_FLIP_H;
break;
case GTH_TRANSFORM_FLIP:
transf = JXFORM_FLIP_V;
break;
default:
transf = JXFORM_NONE;
break;
}
if (jpegtran (tmp1, tmp2, transf, &err) != 0) {
g_free (tmp1);
if (err != NULL)
_gtk_error_dialog_from_gerror_run (parent, &err);
return;
}
#else
switch (tran_type) {
case GTH_TRANSFORM_MIRROR:
command = "-flip horizontal";
break;
case GTH_TRANSFORM_FLIP:
command = "-flip vertical";
break;
default:
return;
}
e1 = shell_escape (tmp2);
e2 = shell_escape (tmp1);
line = g_strdup_printf ("jpegtran -copy all %s -outfile %s %s",
command, e1, e2);
g_spawn_command_line_sync (line, NULL, NULL, NULL, &err);
g_free (e1);
g_free (e2);
g_free (line);
if (err != NULL) {
g_free (tmp1);
g_free (tmp2);
_gtk_error_dialog_from_gerror_run (parent, &err);
return;
}
#endif
}
e1 = shell_escape (tmp2);
e2 = shell_escape (fd->path);
line = g_strdup_printf ("mv -f %s %s", e1, e2);
g_spawn_command_line_sync (line, NULL, NULL, NULL, &err);
if (err != NULL) {
_gtk_error_dialog_from_gerror_run (parent, &err);
} else {
#ifdef HAVE_LIBEXIF
if ((rot_type == GTH_TRANSFORM_ROTATE_90) || (rot_type == GTH_TRANSFORM_ROTATE_270))
swap_xy_exif_fields (fd->path, data);
update_orientation_field (fd->path, data);
#endif
notify_file_changed (data, fd->path, notify_soon);
}
g_free (e1);
g_free (e2);
g_free (line);
g_free (tmp1);
g_free (tmp2);
}
static void
apply_transformation_generic (DialogData *data,
GList *current_image,
gboolean notify_soon)
{
FileData *fd = current_image->data;
int rot_type = data->rot_type;
int tran_type = data->tran_type;
GdkPixbuf *pixbuf1, *pixbuf2;
const char *mime_type;
if ((rot_type == GTH_TRANSFORM_ROTATE_0) && (tran_type == GTH_TRANSFORM_NONE))
return;
pixbuf1 = gdk_pixbuf_new_from_file (fd->path, NULL);
if (pixbuf1 == NULL)
return;
switch (rot_type) {
case GTH_TRANSFORM_ROTATE_90:
pixbuf2 = _gdk_pixbuf_copy_rotate_90 (pixbuf1, FALSE);
break;
case GTH_TRANSFORM_ROTATE_180:
pixbuf2 = _gdk_pixbuf_copy_mirror (pixbuf1, TRUE, TRUE);
break;
case GTH_TRANSFORM_ROTATE_270:
pixbuf2 = _gdk_pixbuf_copy_rotate_90 (pixbuf1, TRUE);
break;