added an option to write image orientation to the metadata
authorVladimir Nadvornik <nadvornik@suse.cz>
Sun, 26 Apr 2009 09:01:35 +0000 (09:01 +0000)
committerVladimir Nadvornik <nadvornik@suse.cz>
Sun, 26 Apr 2009 09:01:35 +0000 (09:01 +0000)
src/bar.c
src/exif.c
src/image.c
src/metadata.c
src/metadata.h
src/options.c
src/options.h
src/preferences.c
src/rcfile.c
src/thumb.c
src/thumb_standard.c

index 85eec6d..9144c9b 100644 (file)
--- a/src/bar.c
+++ b/src/bar.c
@@ -95,7 +95,7 @@ static const gchar default_config_exif[] =
 "                <entry key = 'formatted.ColorProfile' if_set = 'true' editable = 'false' />"
 "                <entry key = 'formatted.SubjectDistance' if_set = 'true' editable = 'false' />"
 "                <entry key = 'formatted.Resolution' if_set = 'true' editable = 'false' />"
-"                <entry key = 'Exif.Image.Orientation' if_set = 'true' editable = 'false' />"
+"                <entry key = '" ORIENTATION_KEY "' if_set = 'true' editable = 'false' />"
 "            </pane_exif>"
 "        </bar>"
 "    </layout>"
index 2788b81..fdb099a 100644 (file)
@@ -1605,6 +1605,9 @@ GList *exif_get_metadata(ExifData *exif, const gchar *key, MetadataFormat format
        
        if (!key) return NULL;
        
+       /* convert xmp key to exif key */
+       if (strcmp(key, ORIENTATION_KEY) == 0) key = "Exif.Image.Orientation";
+       
        if (format == METADATA_FORMATTED)
                {
                gchar *text;
index 2761bd2..71de933 100644 (file)
@@ -401,10 +401,18 @@ void image_alter_orientation(ImageWindow *imd, AlterType type)
                        break;
                }
 
-       if (type != ALTER_NONE)
+       if (imd->orientation != imd->image_fd->exif_orientation ? imd->image_fd->exif_orientation : 1)
                {
-               if (imd->image_fd->user_orientation == 0) file_data_ref(imd->image_fd);
-               imd->image_fd->user_orientation = imd->orientation;
+               if (!options->metadata.write_orientation)
+                       {
+                       /* user_orientation does not work together with options->metadata.write_orientation,
+                          use either one or the other.
+                          we must however handle switching metadata.write_orientation on and off, therefore
+                          we just disable referencing new fd's, not unreferencing the old ones
+                       */
+                       if (imd->image_fd->user_orientation == 0) file_data_ref(imd->image_fd);
+                       imd->image_fd->user_orientation = imd->orientation;
+                       }
                }
        else
                {
@@ -412,6 +420,18 @@ void image_alter_orientation(ImageWindow *imd, AlterType type)
                imd->image_fd->user_orientation = 0;
                }
 
+       if (options->metadata.write_orientation)
+               {
+               if (type == ALTER_NONE)
+                       {
+                       metadata_write_revert(imd->image_fd, ORIENTATION_KEY);
+                       }
+               else
+                       {
+                       metadata_write_int(imd->image_fd, ORIENTATION_KEY, imd->orientation);
+                       }
+               }
+
        pixbuf_renderer_set_orientation((PixbufRenderer *)imd->pr, imd->orientation);
 }
 
@@ -1079,7 +1099,7 @@ void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom, gboo
                        }
                else if (options->image.exif_rotate_enable)
                        {
-                       imd->orientation = metadata_read_int(imd->image_fd, "Exif.Image.Orientation", EXIF_ORIENTATION_TOP_LEFT);
+                       imd->orientation = metadata_read_int(imd->image_fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
                        imd->image_fd->exif_orientation = imd->orientation;
                        }
                }
index 15543d6..b331b2b 100644 (file)
@@ -189,6 +189,24 @@ static gboolean metadata_check_key(const gchar *keys[], const gchar *key)
        return FALSE;
 }
 
+gboolean metadata_write_revert(FileData *fd, const gchar *key)
+{
+       if (!fd->modified_xmp) return FALSE;
+       
+       g_hash_table_remove(fd->modified_xmp, key);
+       
+       if (g_hash_table_size(fd->modified_xmp) == 0)
+               {
+               metadata_write_queue_remove(fd);
+               }
+       else
+               {
+               /* reread the metadata to restore the original value */
+               file_data_increment_version(fd);
+               file_data_send_notification(fd, NOTIFY_REREAD);
+               }
+}
+
 gboolean metadata_write_list(FileData *fd, const gchar *key, const GList *values)
 {
        if (!fd->modified_xmp)
@@ -231,6 +249,13 @@ gboolean metadata_write_string(FileData *fd, const gchar *key, const char *value
        return ret;
 }
 
+gboolean metadata_write_int(FileData *fd, const gchar *key, guint64 value)
+{
+       gchar string[50];
+       
+       g_snprintf(string, sizeof(string), "%ld", value);
+       return metadata_write_string(fd, key, string);
+}
 
 /*
  *-------------------------------------------------------------------
index ea13ee5..a657de7 100644 (file)
@@ -16,6 +16,7 @@
 
 #define COMMENT_KEY "Xmp.dc.description"
 #define KEYWORD_KEY "Xmp.dc.subject"
+#define ORIENTATION_KEY "Xmp.tiff.Orientation"
 
 gboolean metadata_write_queue_remove(FileData *fd);
 gboolean metadata_write_queue_remove_list(GList *list);
@@ -24,8 +25,10 @@ gboolean metadata_write_queue_confirm(FileUtilDoneFunc done_func, gpointer done_
 
 gint metadata_queue_length(void);
 
+gboolean metadata_write_revert(FileData *fd, const gchar *key);
 gboolean metadata_write_list(FileData *fd, const gchar *key, const GList *values);
 gboolean metadata_write_string(FileData *fd, const gchar *key, const char *value);
+gboolean metadata_write_int(FileData *fd, const gchar *key, guint64 value);
 
 GList *metadata_read_list(FileData *fd, const gchar *key, MetadataFormat format);
 gchar *metadata_read_string(FileData *fd, const gchar *key, MetadataFormat format);
index bbdd033..4d34ca2 100644 (file)
@@ -104,6 +104,7 @@ ConfOptions *init_options(ConfOptions *options)
        options->metadata.confirm_on_image_change = FALSE;
        options->metadata.confirm_on_dir_change = TRUE;
        options->metadata.tags_case_sensitive = FALSE;
+       options->metadata.write_orientation = TRUE;
        
        options->show_icon_names = TRUE;
 
index 54a54a7..a692bf0 100644 (file)
@@ -178,6 +178,7 @@ struct _ConfOptions
                gboolean confirm_on_image_change;
                gboolean confirm_on_dir_change;
                gboolean tags_case_sensitive;
+               gboolean write_orientation;
        } metadata;
 
 };
index 02045a0..ff8d59c 100644 (file)
@@ -325,6 +325,7 @@ static void config_window_apply(void)
        options->metadata.confirm_on_image_change = c_options->metadata.confirm_on_image_change;
        options->metadata.confirm_on_dir_change = c_options->metadata.confirm_on_dir_change;
        options->metadata.tags_case_sensitive = c_options->metadata.tags_case_sensitive;
+       options->metadata.write_orientation = c_options->metadata.write_orientation;
 
 #ifdef DEBUG
        set_debug_level(debug_c);
@@ -1369,6 +1370,9 @@ static void config_tab_metadata(GtkWidget *notebook)
 
        pref_checkbox_new_int(group, _("Allow keywords to differ only in case"),
                              options->metadata.tags_case_sensitive, &c_options->metadata.tags_case_sensitive);
+
+       pref_checkbox_new_int(group, _("Write altered image orientation to the metadata"),
+                             options->metadata.write_orientation, &c_options->metadata.write_orientation);
 }
 
 /* metadata tab */
index b8b3593..ad489ea 100644 (file)
@@ -438,6 +438,7 @@ static void write_global_attributes(GString *outstr, gint indent)
        WRITE_NL(); WRITE_BOOL(*options, metadata.confirm_on_image_change);
        WRITE_NL(); WRITE_BOOL(*options, metadata.confirm_on_dir_change);
        WRITE_NL(); WRITE_BOOL(*options, metadata.tags_case_sensitive);
+       WRITE_NL(); WRITE_BOOL(*options, metadata.write_orientation);
 
 }
 
@@ -697,6 +698,7 @@ static gboolean load_global_params(const gchar **attribute_names, const gchar **
                if (READ_BOOL(*options, metadata.confirm_on_image_change)) continue;
                if (READ_BOOL(*options, metadata.confirm_on_dir_change)) continue;
                if (READ_BOOL(*options, metadata.tags_case_sensitive)) continue;
+               if (READ_BOOL(*options, metadata.write_orientation)) continue;
 
                log_printf("unknown attribute %s = %s\n", option, value);
                }
index 0331e9a..970a712 100644 (file)
@@ -142,7 +142,7 @@ static void thumb_loader_done_cb(ImageLoader *il, gpointer data)
                {
                if (!tl->fd->exif_orientation)
                        {
-                       tl->fd->exif_orientation = metadata_read_int(tl->fd, "Exif.Image.Orientation", EXIF_ORIENTATION_TOP_LEFT);
+                       tl->fd->exif_orientation = metadata_read_int(tl->fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
                        }
                
                if (tl->fd->exif_orientation != EXIF_ORIENTATION_TOP_LEFT)
index 0d49f06..9449e9c 100644 (file)
@@ -388,7 +388,7 @@ static GdkPixbuf *thumb_loader_std_finish(ThumbLoaderStd *tl, GdkPixbuf *pixbuf,
                {
                if (!tl->fd->exif_orientation)
                        {
-                       tl->fd->exif_orientation = metadata_read_int(tl->fd, "Exif.Image.Orientation", EXIF_ORIENTATION_TOP_LEFT);
+                       tl->fd->exif_orientation = metadata_read_int(tl->fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
                        }
                
                if (tl->fd->exif_orientation != EXIF_ORIENTATION_TOP_LEFT)