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 NikonFl7 makernotes group #1963

Merged

Conversation

postscript-dev
Copy link
Collaborator

NikonFl7 is enabled for camera models where the Exif.NikonFl7.version tag is 0107 or 0108. The tags are taken from ExifTool's Nikon FlashInfo0107 tags.

This is part of resolving #1941.

NikonFl7 differs from existing NikonFl groups as it uses bigEndian format. This is because Exif.NikonFl7.ExternalFlashFirmware is a short and was incorrectly output when using invalidByteOrder or littleEndian. The other groups use invalidByteOrder which may be wrong. Sadly all of Exiv2's test images for those groups don't use external flashes and the tag is set to zero.

Changes:

  • Add NikonFl7 group
  • Add testing
  • Update documentation

Source: Exiftool

@postscript-dev postscript-dev self-assigned this Oct 14, 2021
@postscript-dev postscript-dev added documentation enhancement feature / functionality enhancements makerNote Anything related to one of the various supported MakerNote formats prettyPrinter Anything related to the output formatting of a value labels Oct 14, 2021
@codecov
Copy link

codecov bot commented Oct 14, 2021

Codecov Report

Merging #1963 (562b10f) into main (5dca23b) will decrease coverage by 0.10%.
The diff coverage is 47.30%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1963      +/-   ##
==========================================
- Coverage   61.29%   61.19%   -0.11%     
==========================================
  Files          96       96              
  Lines       19110    19269     +159     
  Branches     9760     9862     +102     
==========================================
+ Hits        11713    11791      +78     
- Misses       5076     5135      +59     
- Partials     2321     2343      +22     
Impacted Files Coverage Δ
src/makernote_int.cpp 67.62% <ø> (ø)
src/tags_int.cpp 77.05% <ø> (ø)
src/tiffimage_int.cpp 79.55% <ø> (ø)
src/nikonmn_int.cpp 46.76% <46.62%> (+0.45%) ⬆️
src/tags_int.hpp 93.10% <75.00%> (+0.51%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5dca23b...562b10f. Read the comment docs.

std::ostringstream oss;
oss.copyfmt(os);
float temp = ( value.toFloat()/float(-6.0) );
temp *= float(1.00001); // Avoid round-off errors
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you just use std::round here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that using std::round() would only round to the nearest integer which would loose accuracy. I copied the formula from ExifTool (found in exiftool/Nikon.pm and exiftool/Exif.pm).

I am happy to make the change if you know more about this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@postscript-dev: I did a bit of experimenting and I don't think this code is working correctly. For example, if temp == 1.5 then it prints 2/2. Similarly when temp == 0.666666 it prints 0/3. I think the perl code in Exif.pm must have different rounding behavior than C++ does. Regardless, that perl code in Exif.pm looks numerically clumsy to me. My suggestion is to use a condition like this to check whether the number is suitable for printing as a fraction:

std::abs(std::fmod(temp*3, 1)) < 0.001

I have attached the three files that I used for testing: files.tar.gz

  • print_fraction.pm is based on the code in Exif.pm
  • print_fraction1.cpp is based on your code
  • print_fraction2.cpp is my version that uses std::abs and std::fmod.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had much time recently and realised that I needed to look at this again. Thanks for helping.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a mistake before. We need to use std::abs(std::remainderf(...)), not std::abs(std::fmod(...)). With that change, this multiplication is unnecessary. (The goal is that numbers like 0.4999 or 0.5001 are printed as a fraction.)

Suggested change
temp *= float(1.00001); // Avoid round-off errors

src/nikonmn_int.cpp Outdated Show resolved Hide resolved
@lgtm-com
Copy link

lgtm-com bot commented Oct 17, 2021

This pull request introduces 1 alert when merging 5a0f93f into bbfbcb6 - view on LGTM.com

new alerts:

  • 1 for Comparison result is always the same

src/nikonmn_int.cpp Outdated Show resolved Hide resolved
This differs from other `NikonFl` groups as it uses `bigEndian` format. This
is because `Exif.NikonFl7.ExternalFlashFirmware` is a short and was
incorrectly output when using `invalidByteOrder` or `littleEndian`. The other
groups use `invalidByteOrder` which may be wrong. Sadly all of Exiv2s
+ Fix fuzzing CI errors of `exp2` and `round` not being in `std` by adding
  `#include <cmath>`
+ Fix Windows CI warning C4305 by explicitly defining value as a float
src/nikonmn_int.cpp Outdated Show resolved Hide resolved
src/nikonmn_int.cpp Outdated Show resolved Hide resolved
src/nikonmn_int.cpp Outdated Show resolved Hide resolved
std::ostringstream oss;
oss.copyfmt(os);
float temp = ( value.toFloat()/float(-6.0) );
temp *= float(1.00001); // Avoid round-off errors
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a mistake before. We need to use std::abs(std::remainderf(...)), not std::abs(std::fmod(...)). With that change, this multiplication is unnecessary. (The goal is that numbers like 0.4999 or 0.5001 are printed as a fraction.)

Suggested change
temp *= float(1.00001); // Avoid round-off errors

@postscript-dev postscript-dev requested review from kevinbackhouse and removed request for kmilos November 3, 2021 17:42
@kevinbackhouse kevinbackhouse merged commit 7c8e6fc into Exiv2:main Nov 7, 2021
@postscript-dev postscript-dev deleted the add_FlashInfo0107_makernote_group branch November 8, 2021 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement feature / functionality enhancements makerNote Anything related to one of the various supported MakerNote formats prettyPrinter Anything related to the output formatting of a value
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants