Bug 146381 - Image rotation splits the image with a small strip appearing on the wrong side.
Summary: Image rotation splits the image with a small strip appearing on the wrong side.
Status: RESOLVED FIXED
Alias: None
Product: digikam
Classification: Applications
Component: Plugin-Bqm-Rotate (show other bugs)
Version: unspecified
Platform: unspecified Linux
: NOR normal
Target Milestone: ---
Assignee: Digikam Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-06-05 07:34 UTC by David John Mills
Modified: 2022-01-19 03:16 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In: 7.6.0


Attachments
img_7951-orig.jpg (1.39 MB, image/jpeg)
2007-06-14 10:27 UTC, David John Mills
Details
img_7951-thumb.jpg (11.71 KB, image/jpeg)
2007-06-14 10:27 UTC, David John Mills
Details
img_7951-rotated.jpg (14.63 KB, image/jpeg)
2007-06-14 10:27 UTC, David John Mills
Details

Note You need to log in before you can comment on or make changes to this bug.
Description David John Mills 2007-06-05 07:34:40 UTC
Version:           0.9.1 (using KDE 3.5.5 "release 45.4" , openSUSE 10.2)
Compiler:          Target: i586-suse-linux
OS:                Linux (i686) release 2.6.18.8-0.3-default

For each of my images I create a thumbnail copy using a combination of djpeg and cjpeg.  When I attempt to rotate these using digikam a thin strip of the image ends up on the wrong side of the image.
Comment 1 caulier.gilles 2007-06-05 07:37:23 UTC
David, 

Witch Exiv2 release you use ?

Witch camera you use ?

Gilles caulier
Comment 2 Arnd Baecker 2007-06-14 07:53:15 UTC
David,

in addition to Gilles question: could you provide an example image
(original and the thumb you create), either as attachment, 
or put it on a webspace so that we could fetch it.
Also the precise sequence of commands you use to create the thumb
would be helpful to debug this problem.

Many thanks in advance,

Arnd
Comment 3 David John Mills 2007-06-14 10:27:23 UTC
Here's an image.  *-orig is the original.  *-thumb is the thumbnail created 
with the command

djpeg -scale 1/8 img_7951.jpg | cjpeg > thumbs/img_7951.jpg

and *-rotated is the result of rotating this thumbnail using digiKam.

Do you need any more info?

David.


On Thursday 14 June 2007 14:53, Arnd Baecker wrote:
[bugs.kde.org quoted mail]
07:53 -------
> David,
> 
> in addition to Gilles question: could you provide an example image
> (original and the thumb you create), either as attachment, 
> or put it on a webspace so that we could fetch it.
> Also the precise sequence of commands you use to create the thumb
> would be helpful to debug this problem.
> 
> Many thanks in advance,
> 
> Arnd
> 



Created an attachment (id=20853)
img_7951-orig.jpg

Created an attachment (id=20854)
img_7951-thumb.jpg

Created an attachment (id=20855)
img_7951-rotated.jpg
Comment 4 Arnd Baecker 2007-06-14 15:39:17 UTC
Hi,

I can reproduce the problem in the album view: 
rotating img_7951-thumb.jpg  reproduces img_7951-rotated.jpg 

Note, that this does not happen within the image-editor.
Also note, that the same effect is obtained via:
jpegtran -rotate 90 img_7951-thumb.jpg > img_7951-thumb_jpegtran_rotated.jpg
(Some bug in the underylying libraries?)

So this looks like an issue related with the JPEGLossLess kipi plugin.


Comment 5 caulier.gilles 2007-06-14 15:45:09 UTC
Arnd,

Internally, JPEGLossLess kipi-plugin use jpegtrans implementation (it's a copy of source code).

If you can reproduce this problem with jpegtrans directly, well it's a bug in jpegtrans...

Nota : in digiKam core, we use exactly the same implementation to perform jpeg rotation loss less (from jpegtrans) when files are downloaded from camera. Code is in libs/jpegutils

Gilles
Comment 6 Arnd Baecker 2007-06-14 17:26:35 UTC
Is jpegran actively mantained? I only found http://jpegclub.org/

The same problem also occurs with 
exiftran -9 img_7951-thumb.jpg -o img_7951-thumb_rot_exiftran.jpg

Both exiftran and jpegtran depend on libjpeg62 ....

So what should be done about this bug? 
Comment 7 Martin Rehn 2008-07-21 09:02:25 UTC
I can reproduce this bug with Gwenview 1.4.2. I assume that Gwenview is using the same code for its rotation operation?

In my case, any image straight off a Sony DSC-V1 camera suffers from this problem. These pictures are 2592x1944 pixels. When I rotate to the right, in the rotated picture the eight rightmost pixels are taken from the left of the rotated picture. It looks very bad.

Command-line jpegtran shows the same behaviour. But: if jpegtran is given the additional flag "-perfect", it refuses to rotate the image with the message "jpegtran: transformation is not perfect". So it seems that, at least with the jpegtran algorithm, lossless rotation of these images is not possible?

This still looks like a bug in the jpegtran code, but at the very least it should be possible to incorporate the check done by the command line flag "-perfect" into the KDE copy of the code and do something sensible if it fails. I don't know what that would be, though.
Comment 8 Martin Rehn 2008-07-21 20:34:03 UTC
I tried exiftran, and it gives the same (bad) result as jpegtran. I suppose they use the same code.

The bug is also present in KDE4; Gwenview 2.1 / KDE 4.0.98. (Note that Gwenview caches the image to be displayed, so right after the rotation it will look all right. You have to exit Gwenview and start it again to see the problem.)

Also: It does not seem to be the case that the input files are malformed; I get the same result when I create a 2592x1944 pixel image in the GIMP (v. 2.4.5) and save it with the standard jpeg options.

Any proposed workaround for this? Is there any program out there that does the rotation properly? Non-lossless rotation would always work of course, but that is not ideal. (Note that if you happen to own a camera that produces pictures in the "wrong" format, this bug will apply to *all* your photos.)
Comment 9 Martin Rehn 2008-07-21 20:50:20 UTC
Below is the dialog that gThumb pops up when rotating one of these images. The message is very informative and seems to indicate that there is indeed no "right" way of doing the rotation. If you select "OK" in the dialog, the rotation is performed with the same result as in all the other tools above (some pixels misplaced). This is actually reversible, as advertised. If you select "Trim", the image is trimmed to a multiple of 8 pixels, and then rotated without problems.

Perhaps KDE should borrow both the code and the dialog box from GNOME here. There could of course be a third option in that dialog, which would be to do a lossy rotation, without trimming (decompress-rotate-recompress).

------The gThumb dialog:------

== Problem transforming the image: image.jpeg ==

This transformation may introduce small image distortions along one or more edges, because the image dimensions are not multiples of 8.

The distortion is reversible, however. If the resulting image is unacceptable, simply apply the reverse transformation to return to the original image.

You can also choose to discard (or trim) any untransformable edge pixels. For practical use, this mode gives the best looking results, but the transformation is not strictly lossless anymore.

[Trim] [Cancel] [OK]

------
Comment 10 Martin Rehn 2008-07-21 21:29:22 UTC
Sorry for spamming this bug report, but for completeness, there is a fourth option: instead of trimming the picture dimensions to a multiple of 8 pixels, you can *extend* them to such a multiple [1, 2]. This introduces some "ghost" pictures along the edge, but it is a lossless operation, as far as the information in the image is concerned, and the ghost pixels will likely be less conspicuous than are the misplaced pixels currently. The operation is not reversible, though, since the image dimensions are changed.

So, in the spirit of besting GNOME when it comes to options, here are the possible ways to deal with failing lossless rotation (as stated above jpegtran has code to detect the failure):

a) Lossless rotation, leaving pixels in the wrong location (as today; reversible; very ugly; no information loss).

b) Lossless rotation, introducing ghost pixels (non-reversible; possibly less ugly; no information loss).

c) Trimming, followed by lossless rotation (looks good; information loss)

d) Lossy rotation (preserves image size; quality loss; more quality loss if rotated again since we are still not at a multiple of the code block size)

Trimming (c) is probably the best choice for large-size pictures, where the lost pixels are not important. But in some cases those pixels may matter, so the user should be allowed to choose what to do, I think. Maybe we could even offer to remember the choice on an image-size basis, so that the user can go ahead and use trimming for his photos without confirmation, but then get asked again when trying to rotate some other image.

[1] http://www.impulseadventure.com/photo/rotation-partial-mcu.html
[2] Not always a multiple of eight; can also be a multiple of 16, depending on the size of the code blocks in the jpeg.
Comment 11 caulier.gilles 2008-12-07 20:51:58 UTC
David, 

This file still valid using kipi-plugins 0.1.6 ? 

Gilles Caulier
Comment 12 David John Mills 2008-12-07 23:16:31 UTC
I'm now using openSUSE 11.0 which has kipi-plugins-0.1.5-13.1.  I grabbed a copy of img_7951-thumb.jpg (from this bug report) and rotated using digikam.  This time it did not result in a faulty image.

So the bug appears to be fixed.

Should I change the state?

Thanks,

David.
Comment 13 caulier.gilles 2008-12-08 05:58:06 UTC
Thanks for the report. I close this file now
Comment 14 Martin Walch 2010-11-08 04:14:59 UTC
Please reopen this bug report. At least for me this bug is still valid. Steps to reproduce:

1. Find a jpeg/jfif file with dimensions that are not multiples of the blocksize (aka "iMCU size", usually 8 or 16). The file testorig.jpg that ships with the jpeg library from www.ijg.org is such a file.
2. Run gwenview and open this file.
2. Rotate or flip the image one time in the desired direction.
2 b. Gwenview does not really show the actual output, therefore save the file and press F5 for reloading.

Now there is an ugly stripe at one of the edges.

For clarification: Producing these ugly results actually *is* the documented behaviour of jpegtran.

From the jpegtran man page:
> The transpose transformation has no restrictions regarding image dimensions.
> The other transformations operate rather oddly if the image dimensions are not
> a multiple of the iMCU size (usually 8 or 16 pixels), because they can only
> transform complete blocks of DCT coefficient data in the desired way.

> jpegtran's default behavior when transforming an odd-size image is designed to
> preserve exact reversibility and mathematical consistency of the
> transformation set. As stated, transpose is able to flip the entire image
> area. Horizontal mirroring leaves any partial iMCU column at the right edge
> untouched, but is able to flip all rows of the image. Similarly, vertical
> mirroring leaves any partial iMCU row at the bottom edge untouched, but is
> able to flip all columns. The other transforms can be built up as sequences of
> transpose and flip operations; for consistency, their actions on edge pixels
> are defined to be the same as the end result of the corresponding
> transpose-and-flip sequence.

I think lossless transformation is a useful feature and I like to see it in KDE programs like gwenview. However, rotation and flipping are simple one-click-operations in gwenview. The ugly results that you currently get sometimes are not what a normal user would intuitively expect.

As it seems, gwenview is expecting that the transformations are lossless *and* complete, because step 2b was needed: gwenview is doing a fast rotation of the internal bitmap representation of the image instead of reloading the transformed source image.

Please find a solution for all of this. Ideally, lossless transformations would be possible and indicated as such. But also a simple rotation of the *whole* image should be possible in one click.

Is it mathematically possible at all to apply the transformation to the cropped DCT blocks? I mean: is there to every cropped block a rotated and cropped block that yields exactly the same values? Or at least: is there a bijection between them? Intuitively, I would guess that there is such a bijection with a good or even perfect approximation. However, I do not know if there is a fast algorithm (O (n * log n)) for doing such a transformation.

If there *is* such a fast algorithm, maybe this could be incorporated into jpegtran?