Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pretty printer for GPSImgDirection & GPSTrack #1541

Closed
John-N-G opened this issue Apr 10, 2021 · 14 comments
Closed

Add pretty printer for GPSImgDirection & GPSTrack #1541

John-N-G opened this issue Apr 10, 2021 · 14 comments
Labels
prettyPrinter Anything related to the output formatting of a value
Milestone

Comments

@John-N-G
Copy link

_IMG1061 - small

Hi,

I recently reported a bug to DigiKam who have identified that the issue lies within the Exiv2 libraries. Specifically, GPS image direction is displayed as, for example, "26819/100" when it should be showing "268.19 deg".

I've attached an image with GPS/compass EXIF data so you can verify this for yourselves.

I'd be very grateful if you could look into this - I imagine it's a simple formatting error in the code. DigiKam is a great product and so, by extension, is your contribution to it - thank you.

Best regards,

John Gass

@hassec
Copy link
Member

hassec commented Apr 10, 2021

Hi @John-N-G,

thanks for the report.
Using your file I confirm that, exiv2 prints

Exif.GPSInfo.GPSTrackRef                     Ascii       2  True direction
Exif.GPSInfo.GPSTrack                        Rational    1  27093/100
Exif.GPSInfo.GPSImgDirectionRef              Ascii       2  True direction
Exif.GPSInfo.GPSImgDirection                 Rational    1  32098/100

I agree that it would be nicer to format this differently, eg. 320.98 deg as you suggested.
But I'd not classify this as a bug, as the information is complete and correct.
Thus it's more a wish for different formatting.

As far as I can tell, this would be a change that impacts every consumer of exiv2, and thus I'm not sure if it's something that can be done in a minor release.
Likely more suitable for a future major release. But I'll let @clanmills comment on this.

To be fair, given that all info is available, this seems like a trivial thing to fix on the DigiKam side.

@hassec hassec added enhancement feature / functionality enhancements prettyPrinter Anything related to the output formatting of a value labels Apr 10, 2021
@clanmills
Copy link
Collaborator

Thank You @John-N-G for your generous words of praise for Exiv2. And thank you @hassec for your correct analysis.

Your issue is a presentation issue in digiKam. The data in your file is Exif Rational which are integers pairs. You have 3 pairs which represent degrees, minutes and seconds. https://exiv2.org/tags.html

The exiv2 command-line program provides two presentation styles.

Value style '-pv' is the value and is an ascii formatted version of the "raw" values in the image:

506 rmills@rmillsm1:~ $ exiv2 -pv -g Latitude -g Longitude  ~/Downloads/114268738-a429ab00-99fa-11eb-9fe8-73c1f372d5b4.jpg 
0x0001 GPSInfo      GPSLatitudeRef              Ascii       2  N
0x0002 GPSInfo      GPSLatitude                 Rational    3  51/1 20029833/1000000 0/1
0x0003 GPSInfo      GPSLongitudeRef             Ascii       2  W
0x0004 GPSInfo      GPSLongitude                Rational    3  0/1 4863667/1000000 0/1

Translated style '-pt' is a human friendly formatted string. I chose to express it as deg ' " which is how most folks would interpret the data. I didn't use the degree symbol ° because it is not 7-bit ascii.

507 rmills@rmillsm1:~ $ exiv2 -pt -g Latitude -g Longitude  ~/Downloads/114268738-a429ab00-99fa-11eb-9fe8-73c1f372d5b4.jpg 
Exif.GPSInfo.GPSLatitudeRef                  Ascii       2  North
Exif.GPSInfo.GPSLatitude                     Rational    3  51deg 20' 0"
Exif.GPSInfo.GPSLongitudeRef                 Ascii       2  West
Exif.GPSInfo.GPSLongitude                    Rational    3  0deg 5' 0"
508 rmills@rmillsm1:~ $ 

The people at DigiKam blame everything involving metadata on Exiv2. In this case, I can say with certainty that Exiv2 is not to blame.

@clanmills clanmills removed the enhancement feature / functionality enhancements label Apr 10, 2021
@clanmills clanmills self-assigned this Apr 10, 2021
@clanmills clanmills added this to the v0.27.4 milestone Apr 10, 2021
@hassec hassec modified the milestones: v0.27.4, v1.00 Apr 10, 2021
@hassec hassec changed the title GPS image direction formatting error Add pretty printer for GPSImgDirection & GPSTrack Apr 10, 2021
@hassec hassec reopened this Apr 10, 2021
@hassec hassec assigned hassec and unassigned clanmills Apr 10, 2021
@hassec
Copy link
Member

hassec commented Apr 10, 2021

Just for completeness I'm including the DigiKam bug: https://bugs.kde.org/show_bug.cgi?id=435317

@John-N-G Thanks for already updating the bug there with our response.

I hope you don't mind, I renamed the issue to make it more clear for us.
I'll add the required changes to change the formatting on these values.
But note that v1.0 is currently aimed for the end of this year, so it will be awhile before you get the fix, unless you build exiv2 from source yourself.

@clanmills
Copy link
Collaborator

Yup. I got a little confused. I had totally forgotten about adding the Direction and Track tags in v0.27.4. I think they are specified in the Exif 2.32 spec. The "translated" values are performed in Exiv2 by providing a "pretty printer" function such as printDegrees() which I added to handle Latitude and Longitude.

We should add a pretty printer for Track and Direction for use by the Exiv2 command-line program. When no "pretty printer" is available, the code prints the value.

I can't remember if the pretty printers can be called via the Exiv2 API.

516 rmills@rmillsm1:~/gnu/github/exiv2/0.27-maintenance $ exiv2 -pv -g Track -g Direction ~/Downloads/114268738-a429ab00-99fa-11eb-9fe8-73c1f372d5b4.jpg 
0x000e GPSInfo      GPSTrackRef                 Ascii       2  T
0x000f GPSInfo      GPSTrack                    Rational    1  27093/100
0x0010 GPSInfo      GPSImgDirectionRef          Ascii       2  T
0x0011 GPSInfo      GPSImgDirection             Rational    1  32098/100
517 rmills@rmillsm1:~/gnu/github/exiv2/0.27-maintenance $ exiv2 -pt -g Track -g Direction ~/Downloads/114268738-a429ab00-99fa-11eb-9fe8-73c1f372d5b4.jpg 
Exif.GPSInfo.GPSTrackRef                     Ascii       2  True direction
Exif.GPSInfo.GPSTrack                        Rational    1  27093/100
Exif.GPSInfo.GPSImgDirectionRef              Ascii       2  True direction
Exif.GPSInfo.GPSImgDirection                 Rational    1  32098/100
518 rmills@rmillsm1:~/gnu/github/exiv2/0.27-maintenance $ 

None-the-less, this is a presentation matter which is DigiKam's domain and responsibility.

@clanmills
Copy link
Collaborator

Exiv2 provide an API to use the pretty printers from an application. See https://exiv2.org/doc/classExiv2_1_1Exifdatum.html

So there are two similar functions:

API Comment
std::string Exiv2::Exifdatum::toString() const; Return the value as a string.
std::string Exiv2::Exifdatum::print() const; Write the interpreted value to a string.

Here's additional information concerning print()

Exiv2::Exifdatum::write
Write the interpreted value to an output stream, return the stream.

The method takes an optional pointer to a metadata container. Pretty-print functions may use that to refer to other metadata as it is sometimes not sufficient to know only the value of the metadatum that should be interpreted. Thus, it is advisable to always call this method with a pointer to the metadata container if possible.

This functionality is currently only implemented for Exif tags. The pointer is ignored when used to write IPTC datasets or XMP properties.

Without the optional metadata pointer, you do not usually have to use this function; it is used for the implementation of the output operator for Metadatum, operator<<(std::ostream &os, const Metadatum &md).

See also print(), which prints the interpreted value to a string.

@clanmills
Copy link
Collaborator

The Exif 2.32 Spec is here: https://fotomagazin.hu/wp-content/uploads/2020/05/CIPA_DC_008_EXIF_2019.pdf

Table 15 (page 77) lists 32 GPS tags. Let's make sure all those tags are in Exiv2 (I believe they are) and with appropriate "pretty Printers".

@kmilos
Copy link
Collaborator

kmilos commented Apr 11, 2021

I believe we reviewed the tag coverage, but it might be the case we didn't focus on pretty printing. I'll take another pass as well.

In any case, apps have full acces to rationals through the API so they can choose to present the data in any format they want, I don't think our convenience functions for console output should be used universally...

@clanmills
Copy link
Collaborator

Thanks, @kmilos. There's such a myriad of details in the metadata mountain. The only viable way to deal with everything is "step-wise refinement". He's not as ugly as his cousin "trial and error".

@kmilos
Copy link
Collaborator

kmilos commented Apr 12, 2021

Ok, so it turns out there are a few places where we just use the default printValue() instead of the usual printFloat() for rational type:

  • TIFF/EP tags:

0x013e, WhitePoint
0x013f, PrimaryChromaticities
0x0211, YCbCrCoefficients
0x0214, ReferenceBlackWhite
0x828f, BatteryLevel
0x920b, FlashEnergy
0x9215, ExposureIndex

  • DNG tags:

0xc61a, BlackLevel
0xc61b, BlackLevelDeltaH
0xc61c, BlackLevelDeltaV
0xc61e, DefaultScale
0xc627, AnalogBalance
0xc629, AsShotWhiteXY
0xc62a, BaselineExposure
0xc62b, BaselineNoise
0xc62c, BaselineSharpness
0xc62e, LinearResponseLimit
0xc630, LensInfo
0xc631, ChromaBlurRadius
0xc632, AntiAliasStrength
0xc633, ShadowScale
0xc65c, BestQualityScale
0xc6f7, NoiseReductionApplied
0xc764, FrameRate
0xc772, TStop
0xc7ea, DepthNear
0xc7eb, DepthFar

... and all the color profile matrices

  • Exif tags:

9400,Temperature,SRATIONAL,1
9401,Humidity,RATIONAL,1
9402,Pressure,RATIONAL,1
9403,WaterDepth,SRATIONAL,1
9404,Acceleration,RATIONAL,1
9405,CameraElevationAngle,SRATIONAL,1
A20B,FlashEnergy,RATIONAL,1
A215,ExposureIndex,RATIONAL,1
A432,LensSpecification,RATIONAL,4

  • GPS tags:

B,GPSDOP,RATIONAL,1
D,GPSSpeed,RATIONAL,1
F,GPSTrack,RATIONAL,1
11,GPSImgDirection,RATIONAL,1
18,GPSDestBearing,RATIONAL,1
1A,GPSDestDistance,RATIONAL,1
1F,GPSHPositioningError,RATIONAL,1

We're also missing the Exif 0xa500 Gamma tag. (PR created for main branch)

Any preference on how to proceed, and whether we want to change something for 0.27.4?

Simply replacing everywhere is risky, as a couple of tags assign special meaning to values 0/0 or 1/0...

@kmilos
Copy link
Collaborator

kmilos commented Apr 13, 2021

ExifTool output for the attached image:

>exiftool -a -u -s -GPS:all 114268738-a429ab00-99fa-11eb-9fe8-73c1f372d5b4.jpg
GPSVersionID                    : 2.3.0.0
GPSLatitudeRef                  : North
GPSLatitude                     : 51 deg 20' 1.79"
GPSLongitudeRef                 : West
GPSLongitude                    : 0 deg 4' 51.82"
GPSAltitudeRef                  : Above Sea Level
GPSAltitude                     : 155.6 m
GPSTimeStamp                    : 14:03:31
GPSSatellites                   : 09
GPSStatus                       : Measurement Active
GPSMeasureMode                  : 3-Dimensional Measurement
GPSSpeedRef                     : km/h
GPSSpeed                        : 0.02
GPSTrackRef                     : True North
GPSTrack                        : 270.93
GPSImgDirectionRef              : True North
GPSImgDirection                 : 320.98
GPSMapDatum                     : WGS-84
GPSProcessingMethod             : GPS
GPSDateStamp                    : 2021:02:18

So no units for GPSSpeed, GPSTrack, and GPSImgDirection (I'll submit a patch to use printFloat() on these), while there is one for GPSAltitude (and we already have a special pretty-print function to include it as well).

@hassec
Copy link
Member

hassec commented Apr 13, 2021

IMHO GPSTrack and GPSImgDirection should get a unit.

@clanmills
Copy link
Collaborator

663 rmills@rmillsm1:~/gnu/github/exiv2/main $ exiv2 -g GPSInfo ~/Downloads/114268738-a429ab00-99fa-11eb-9fe8-73c1f372d5b4.jpg 
Exif.GPSInfo.GPSVersionID                    Byte        4  2.3.0.0
Exif.GPSInfo.GPSLatitudeRef                  Ascii       2  North
Exif.GPSInfo.GPSLatitude                     Rational    3  51deg 20' 0"
Exif.GPSInfo.GPSLongitudeRef                 Ascii       2  West
Exif.GPSInfo.GPSLongitude                    Rational    3  0deg 5' 0"
Exif.GPSInfo.GPSAltitudeRef                  Byte        1  Above sea level
Exif.GPSInfo.GPSAltitude                     Rational    1  155.6 m
Exif.GPSInfo.GPSTimeStamp                    Rational    3  14:03:31
Exif.GPSInfo.GPSSatellites                   Ascii       3  09
Exif.GPSInfo.GPSStatus                       Ascii       2  Measurement in progress
Exif.GPSInfo.GPSMeasureMode                  Ascii       2  Three-dimensional measurement
Exif.GPSInfo.GPSSpeedRef                     Ascii       2  km/h
Exif.GPSInfo.GPSSpeed                        Rational    1  2/100
Exif.GPSInfo.GPSTrackRef                     Ascii       2  True direction
Exif.GPSInfo.GPSTrack                        Rational    1  27093/100
Exif.GPSInfo.GPSImgDirectionRef              Ascii       2  True direction
Exif.GPSInfo.GPSImgDirection                 Rational    1  32098/100
Exif.GPSInfo.GPSMapDatum                     Ascii       7  WGS-84
Exif.GPSInfo.GPSProcessingMethod             Undefined  11  charset=Ascii GPS
Exif.GPSInfo.GPSDateStamp                    Ascii      11  2021:02:18
664 rmills@rmillsm1:~/gnu/github/exiv2/main $ 

I see that ExifTool says xx deg yy' zz" (space) and exiv2 says xxdeg yy' zz" (no space). Let's change printDegrees() to be consistent with ExifTool. (no man page changes necessary for this)

There are cosmetic differences with Status and MeasureMode, Speed and Direction Let's fix them. Please look at man/man1/exiv2.1 when changing prettyPrinters.

I see ExifTool doesn't provide a unit for Track and Direction. Let's be consistent and do likewise.

@kmilos
Copy link
Collaborator

kmilos commented Apr 13, 2021

Btw, there seems to be something more going on w/ the way we print the long/lat, check the seconds. I guess this is related to the second available Exif spec option where the minute value is a true rational (MMMM/100) and second is (0/1)...

$ ./exiv2 -g GPSInfo 114268738-a429ab00-99fa-11eb-9fe8-73c1f372d5b4.jpg
Exif.GPSInfo.GPSVersionID                    Byte        4  2.3.0.0
Exif.GPSInfo.GPSLatitudeRef                  Ascii       2  North
Exif.GPSInfo.GPSLatitude                     Rational    3  51 deg 20' 0"
Exif.GPSInfo.GPSLongitudeRef                 Ascii       2  West
Exif.GPSInfo.GPSLongitude                    Rational    3  0 deg 5' 0"
Exif.GPSInfo.GPSAltitudeRef                  Byte        1  Above sea level
Exif.GPSInfo.GPSAltitude                     Rational    1  155.6 m
Exif.GPSInfo.GPSTimeStamp                    Rational    3  14:03:31
Exif.GPSInfo.GPSSatellites                   Ascii       3  09
Exif.GPSInfo.GPSStatus                       Ascii       2  Measurement in progress
Exif.GPSInfo.GPSMeasureMode                  Ascii       2  3-dimensional measurement
Exif.GPSInfo.GPSSpeedRef                     Ascii       2  km/h
Exif.GPSInfo.GPSSpeed                        Rational    1  0.02
Exif.GPSInfo.GPSTrackRef                     Ascii       2  True direction
Exif.GPSInfo.GPSTrack                        Rational    1  270.93
Exif.GPSInfo.GPSImgDirectionRef              Ascii       2  True direction
Exif.GPSInfo.GPSImgDirection                 Rational    1  320.98
Exif.GPSInfo.GPSMapDatum                     Ascii       7  WGS-84
Exif.GPSInfo.GPSProcessingMethod             Undefined  11  charset=Ascii GPS
Exif.GPSInfo.GPSDateStamp                    Ascii      11  2021:02:18

@kmilos
Copy link
Collaborator

kmilos commented Apr 14, 2021

I think this now resolved by #1551, but feel free to reopen if different behaviour is expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
prettyPrinter Anything related to the output formatting of a value
Projects
None yet
Development

No branches or pull requests

4 participants