After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 370013 - Exif orientation problems in web album generation
Exif orientation problems in web album generation
Status: RESOLVED FIXED
Product: gthumb
Classification: Other
Component: general
2.9.x
Other Linux
: High major
: ---
Assigned To: Paolo Bacchilega
Paolo Bacchilega
Depends on:
Blocks:
 
 
Reported: 2006-11-03 14:11 UTC by Michael Chudobiak
Modified: 2006-11-17 13:55 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
set orientation in exif data function (5.41 KB, patch)
2006-11-08 16:57 UTC, manuel braga
none Details | Review
Changes orientation-tag update method. (4.78 KB, patch)
2006-11-15 13:31 UTC, Michael Chudobiak
none Details | Review
Transforms "original images" to top-left in web album export (3.34 KB, patch)
2006-11-16 15:36 UTC, Michael Chudobiak
none Details | Review

Description Michael Chudobiak 2006-11-03 14:11:48 UTC
Web album images that are generated from jpegs with Exif orientation tags are not correctly shown in the albums.

There are several issues: the thumbnails and "original images" (if "Copy originals to destination" is selected) should both be transformed back to top-left before saving in the web album.

The thumbnail generator probably ignores the tag currently, and most web browsers probably ignore it as well, so everything needs to be "top left" (the default).

- Mike
Comment 1 Jef Driesen 2006-11-04 15:09:41 UTC
Thumbnails look good here (they match with the thumbnails in gthumb). Only the original images are the not autorotated here.
Comment 2 Michael Chudobiak 2006-11-04 15:34:33 UTC
Actually, I think we have bigger troubles... the image re-sizing code doesn't handle the exif tags properly. We'll have to check all of the image modification tools...

Boosting severity. We have to fix this stuff before we can have a new release.

- Mike
Comment 3 Michael Chudobiak 2006-11-04 17:06:19 UTC
I think _gdk_pixbuf_save_as_jpeg in libgthumb/pixbuf-utils.c needs to call write_orientation_field (filename, GTH_TRANSFORM_NONE).

- Mike
Comment 4 Michael Chudobiak 2006-11-04 19:16:36 UTC
Hmm... I'm not having much luck unraveling this.

Anyway, the easiest way to demonstrate the problem is simply to use "File > Save As" on a jpeg with an orientation tag that is not equal to "top left".

- Mike
Comment 5 Michael Chudobiak 2006-11-04 22:15:59 UTC
I've committed a fix, by adding:

write_orientation_field (dest_filename, GTH_TRANSFORM_NONE);

after each:

jpeg_data_save_file

in src/catalog-web-exporter.c, src/gth-browser.c, and src/gth-viewer.c.

I think that fixes things. Please test.


- Mike
Comment 6 Jef Driesen 2006-11-06 13:55:37 UTC
The fix seems to work fine here. However, it is not implemented really efficient. You used the write_orientation_field function, which does rewrite the jpeg file. I think it is possible to modify the exif data before saving the jpeg.
Comment 7 Michael Chudobiak 2006-11-06 14:07:33 UTC
I realize that, but it works well for the first iteration.

I'll be taking another look at it sometime anyway, because the "save_jpeg_data" routine (where the write_orientation_field was added) is defined in both gth-browser.c and gth-viewer.c - pointless duplication of code.

I think read/write_orientation_field routines should be moved into libgthumb/gth-exif-utils.c, and 

save_jpeg_data (GthBrowser *browser, const char *filename)
save_jpeg_data (GthViewer  *viewer, const char *filename)

should be moved there as well, and be redefined as:

save_jpeg_tags_and_reset_orientation (const char *filename, ExifData *exifdata, IptcData *iptcdata)

or something like that. Pending some spare time...


- Mike


Comment 8 manuel braga 2006-11-07 23:53:40 UTC
Maybe it could be created a new function set_orientation_in_exif_data with the
content of the "for statement" from write_orientation_field.

Is some doing something?

Comment 9 Michael Chudobiak 2006-11-08 13:39:42 UTC
Manuel,

Yes, I think that is a good idea. Can you go ahead and make new save_jpeg_tags_and_reset_orientation and set_orientation_in_exif_dat functions in libgthumb/gth-exif-utils.c? 

- Mike
Comment 10 manuel braga 2006-11-08 16:57:49 UTC
Created attachment 76215 [details] [review]
set orientation in exif data function

I didn't remove the duplicated code, the reason was that the iptc library is optional.

Maybe is better to leave this for later.
Comment 11 Michael Chudobiak 2006-11-08 18:21:18 UTC
Thanks Manuel! I've committed the patch. I don't understand what you mean about the iptc library. Why does that stop us from removing the duplicated routines?

Also... there is still another issue to figure out. If you select "copy original images", but do not resize the images, then gthumb just copies the file directly.

This normally OK, except that most browsers (like Firefox 2.0) do not support the exif orientation tag, so it isn't oriented correctly on the browser if it has an orientation tag.

I think we need to read the original exif orientation tag, and then use:

apply_transformation_jpeg (window, path, data->transform, FALSE);

step for each file in this case. 

Jef, what do you think? Should this be optional (a UI pref?) or mandatory?


- Mike
Comment 12 Michael Chudobiak 2006-11-09 13:58:06 UTC
Manuel,

can you create a patch that modifies export__copy_image in src/catalog-web-exporter.c, so that for each item in dest_list, it will read the orientation tag, and then apply the physical transform required to reset the tag to top-left?

That is, something like

transform = read_orientation_field (const char *path);
apply_transformation_jpeg (window, path, transform, FALSE);
                           ^^^^^^
                           Problem?

- Mike



Comment 13 Jef Driesen 2006-11-09 16:23:42 UTC
(In reply to comment #11)
> I don't understand what you mean about
> the iptc library. Why does that stop us from removing the duplicated routines?

Since the library is optional, you can't have a function with a IptcData parameter, at least not without some #ifdef's.

> Also... there is still another issue to figure out. If you select "copy
> original images", but do not resize the images, then gthumb just copies the
> file directly.
> 
> This normally OK, except that most browsers (like Firefox 2.0) do not support
> the exif orientation tag, so it isn't oriented correctly on the browser if it
> has an orientation tag.
> 
> I think we need to read the original exif orientation tag, and then use:
> 
> apply_transformation_jpeg (window, path, data->transform, FALSE);
> 
> step for each file in this case.

That sounds good to me, because the exif orientation tag is not the only tag that needs to be updated (image dimensions, thumbnail). The transformation code does that already (partially).

BTW, in the current code, the exif data from the GthBrowser/GthViewer structure is modified. I think that will cause suprising side effects when modifying the image a second time (but I didn't check that). Using the transform function does not have this (potential) problem.

> Jef, what do you think? Should this be optional (a UI pref?) or mandatory?

I think mandatory is the best option for exporting images to a webalbum.
Comment 14 Michael Chudobiak 2006-11-09 16:43:54 UTC
(In reply to comment #13)
> Since the library is optional, you can't have a function with a IptcData
> parameter, at least not without some #ifdef's.

Sorry, I figured that out right after posting...

> That sounds good to me, because the exif orientation tag is not the only tag
> that needs to be updated (image dimensions, thumbnail). The transformation code
> does that already (partially).

Well, the image dimensions don't change in this case (this is only an issue when resizing is not selected). Just the orientation and thumbnail should change, I guess. (If the image is resized, a different routine is used and the image is saved from the pixbuf, rather than copying the original file.)

> BTW, in the current code, the exif data from the GthBrowser/GthViewer structure
> is modified. I think that will cause suprising side effects when modifying the
> image a second time (but I didn't check that). Using the transform function
> does not have this (potential) problem.

Hmm... I think you are right. There is some oddness after you modify an image (without saving yet) and then use tools>rotate. I have to study that...

> > Jef, what do you think? Should this be optional (a UI pref?) or mandatory?
> 
> I think mandatory is the best option for exporting images to a webalbum.

Yes, agreed.

- Mike
Comment 15 Michael Chudobiak 2006-11-09 17:00:33 UTC
> > is modified. I think that will cause suprising side effects when modifying the
> > image a second time (but I didn't check that). Using the transform function
> > does not have this (potential) problem.
> 
> Hmm... I think you are right. There is some oddness after you modify an image
> (without saving yet) and then use tools>rotate. I have to study that...

Actually... I think the current code is safe if you successively use different "Image" menu tools (which operate on the pixbuf in memory, which the image loader has transformed to top-left format), but things get confusing if you call Tools>Rotation without saving first, because the screen will show an unsaved pixbuf, but the rotation tool will operate on the original saved file. Maybe we need to add a check for unsaved pixbufs before using the lossless rotation tool?

- Mike
Comment 16 Rennie deGraaf 2006-11-09 17:06:31 UTC
(In reply to comment #13)
> (In reply to comment #11)
>
> > Also... there is still another issue to figure out. If you select "copy
> > original images", but do not resize the images, then gthumb just copies the
> > file directly.
> > 
> > This normally OK, except that most browsers (like Firefox 2.0) do not support
> > the exif orientation tag, so it isn't oriented correctly on the browser if it
> > has an orientation tag.
> > 
> > I think we need to read the original exif orientation tag, and then use:
> > 
> > apply_transformation_jpeg (window, path, data->transform, FALSE);
> > 
> > step for each file in this case.
> 
> That sounds good to me, because the exif orientation tag is not the only tag
> that needs to be updated (image dimensions, thumbnail). The transformation code
> does that already (partially).
> 
> BTW, in the current code, the exif data from the GthBrowser/GthViewer structure
> is modified. I think that will cause suprising side effects when modifying the
> image a second time (but I didn't check that). Using the transform function
> does not have this (potential) problem.
> 
> > Jef, what do you think? Should this be optional (a UI pref?) or mandatory?
> 
> I think mandatory is the best option for exporting images to a webalbum.

I agree.  If there's a pref for this at all, make it a hidden one.  We don't need to clutter up the export dialog with a setting for this.

Rennie
Comment 17 Michael Chudobiak 2006-11-09 18:11:55 UTC
Hmm...

1) I think we need to modify:

gth_window_activate_action_tools_jpeg_rotate
gth_window_activate_action_tools_jpeg_rotate_right
gth_window_activate_action_tools_jpeg_rotate_left

to include something like

        if (gth_window_get_image_modified (window)) {
                GthViewer *viewer = (GthViewer*) window;
                ask_whether_to_save (viewer, load_image__image_saved_cb);
        }                                    ^^^ not sure about this

or something similar, to catch unexpected pixbuf/file differences. 


2) The export__copy_image function needs something like:

transform = read_orientation_field (const char *path);
apply_transformation_jpeg (window, path, transform, FALSE);

Manuel, can you come up with a patch for #1 and #2?

3) Jef: do you want the set_orientation_in_exif_data changes reverted? If so, maybe upload a patch to show what you think is safest... you have a better grip on this stuff than me.


This stuff is never-ending...


- Mike
Comment 18 manuel braga 2006-11-09 18:29:45 UTC
(In reply to comment #13)
> BTW, in the current code, the exif data from the GthBrowser/GthViewer structure
> is modified. I think that will cause suprising side effects when modifying the
> image a second time (but I didn't check that). Using the transform function
> does not have this (potential) problem.

It looks that is a problem.
To make a copy of the exif data first could solve.


(In reply to comment #17)
> Manuel, can you come up with a patch for #1 and #2?

I don't want to break anything, again.
This is being confuse to me, i need to see what is going on.

Comment 19 Michael Chudobiak 2006-11-09 19:13:35 UTC
> I don't want to break anything, again.
> This is being confuse to me, i need to see what is going on.

Manuel,

Don't worry - I don't think you broke anything! I don't think the current approach actually causes any problems, although it might in the future. (The tool>rotation issue would be a problem either way). But if we can think of a safer approach, it's probably worth doing.

And yes - the exif tag stuff is confusing - you missed the fun of bug 343867 :-)

- Mike



Comment 20 Jef Driesen 2006-11-09 19:55:53 UTC
(In reply to comment #14)
> > That sounds good to me, because the exif orientation tag is not the only tag
> > that needs to be updated (image dimensions, thumbnail). The transformation code
> > does that already (partially).
> 
> Well, the image dimensions don't change in this case (this is only an issue
> when resizing is not selected). Just the orientation and thumbnail should
> change, I guess. (If the image is resized, a different routine is used and the
> image is saved from the pixbuf, rather than copying the original file.)

I was not referring to adjusting the dimensions in the sense of resizing, but to swapping horizontal and vertical tags for certain transformations. And there are also some other tags that we could update (see also bug 343867 comment 77).

We should centralize that functionality in one place only, otherwise maintaining it will be a nightmare.

(In reply to comment #17)
> 1) I think we need to modify:
> 
> gth_window_activate_action_tools_jpeg_rotate
> gth_window_activate_action_tools_jpeg_rotate_right
> gth_window_activate_action_tools_jpeg_rotate_left
> 
> to include something like
> 
>         if (gth_window_get_image_modified (window)) {
>                 GthViewer *viewer = (GthViewer*) window;
>                 ask_whether_to_save (viewer, load_image__image_saved_cb);
>         }                                    ^^^ not sure about this
> 
> or something similar, to catch unexpected pixbuf/file differences. 

That applies to all functions under the Tools menu. Because as far as I know, they all operate on files, rather than the active pixbuf.

> 
> 2) The export__copy_image function needs something like:
> 
> transform = read_orientation_field (const char *path);
> apply_transformation_jpeg (window, path, transform, FALSE);

That looks good, except for the fact that apply_transformation_jpeg can only overwrite a file, not copy. The underlying jpegtran can be used to perform a simple copy (with JXFORM_NONE) AND adjusting the exif tags at the same time (when my patch is finished). I don't know if there is a drawback compared to using the jpeg_data_* functions (which we are using now in many places).

> 3) Jef: do you want the set_orientation_in_exif_data changes reverted? If so,
> maybe upload a patch to show what you think is safest... you have a better grip
> on this stuff than me.

It doesn't matter for the moment.
Comment 21 Michael Chudobiak 2006-11-15 13:31:28 UTC
Created attachment 76635 [details] [review]
Changes orientation-tag update method.

To address Jef's concerns about possibly unintended consequences of modifying the orientation tags of pixbufs in memory, I have partly reverted an earlier patch.

Now, the "File>Save As" functions use the "safer" file-based write_orientation_field function to reset the orientation tag. This is less efficient, but it does not mess with the in-memory exif data associated with the pixbuf. This wasn't a current source of problems, but it might cause unexpected issues in the future, because the data is persistent.

The web exporter still uses the new memory-based set_orientation_in_exif_data function, because the exif data that it modifies is not persistent. The elimination of a file save is very helpful in speeding up album generation, too.

There are still some outstanding issues here (see comment 17):

1) The export__copy_image function needs a reset tag step.
2) The Tool functions should force a save/cancel if there are unsaved pixbufs selected.

- Mike
Comment 22 Michael Chudobiak 2006-11-15 15:52:31 UTC
(In reply to comment #20)
> > 2) The export__copy_image function needs something like:
> > 
> > transform = read_orientation_field (const char *path);
> > apply_transformation_jpeg (window, path, transform, FALSE);
> 
> That looks good, except for the fact that apply_transformation_jpeg can only
> overwrite a file, not copy. The underlying jpegtran can be used to perform a
> simple copy (with JXFORM_NONE) AND adjusting the exif tags at the same time
> (when my patch is finished). I don't know if there is a drawback compared to
> using the jpeg_data_* functions (which we are using now in many places).

Jef,

Can you take a look at export__copy_image and offer a patch to it to add the transform-to-top-left step?

It's beyond my skill - the existing export__copy_image function in src/catalog-web-exporter.c is asynchronous, and uses progress callbacks. We could use the underlying jpegtran to copy as you suggest, but there would be no progress dialogs (I guess).

- Mike
Comment 23 Michael Chudobiak 2006-11-16 14:15:52 UTC
Never mind the above plea for help. I'm figuring it out...

- Mike
Comment 24 Michael Chudobiak 2006-11-16 15:36:12 UTC
Created attachment 76706 [details] [review]
Transforms "original images" to top-left in web album export

OK, here is my patch to transform copied original images back to top-left.

The original export__copy_image function used an asynchronous copy-list function (gnome_vfs_async_xfer). I don't understand why a list function was used. I changed it to a single-item non-async function (so I could be sure when the new file was ready for transformation), gnome_vfs_xfer_uri.

Jef (and anyone else), I'd appreciate any feedback on the patch. I'm sure it could be more elegant, but my programming skills aren't that dazzling. It seems to work, anyway.

- Mike
Comment 25 Michael Chudobiak 2006-11-17 13:55:51 UTC
I've committed a slightly modified version of this patch.

I'm opening a new bug 376308 for the save-before-tool-usage issue.

Closing this as fixed.


- Mike