Skip to content

Added Exif parsing for PNG Issue 16579#19439

Merged
opencv-pushbot merged 1 commit intoopencv:3.4from
raaldrid:Exif_support_for_PNG_issue_16579
Feb 10, 2021
Merged

Added Exif parsing for PNG Issue 16579#19439
opencv-pushbot merged 1 commit intoopencv:3.4from
raaldrid:Exif_support_for_PNG_issue_16579

Conversation

@raaldrid
Copy link
Copy Markdown
Contributor

@raaldrid raaldrid commented Feb 1, 2021

Merge with extra: opencv/opencv_extra#843

Added Exif parsing for PNG files to support Exif orientation tag. Moved decoder specific Exif parsing to JPEG and PNG decoders, respectively. Issue 16579

resolves #16579

Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

  • [X ] I agree to contribute to the project under Apache 2 License.
  • [X ] To the best of my knowledge, the proposed patch is not based on a code under GPL or other license that is incompatible with OpenCV
  • [X ] The PR is proposed to proper branch
  • [X ] There is reference to original bug report and related work
  • [X ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
    Patch to opencv_extra has the same branch name.
  • [X ] The feature is well documented and sample code can be built with the project CMake
opencv_extra=raaldrid-exif_PNG_test_files

@asmorkalov
Copy link
Copy Markdown
Contributor

@rrrapha Thanks for the contribution! Please pay attention on CI builds. It looks like your patch breaks build:

[ 30%] [ 30%] /build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/loadsave.cpp: In function 'void* cv::imread_(const cv::String&, int, int, cv::Mat*)':
/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/loadsave.cpp:511:51: error: invalid initialization of non-const reference of type 'cv::ExifReader&' from an rvalue of type 'cv::ExifReader'
         ApplyExifOrientation(decoder->exif(), *mat);
                                                   ^
/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/loadsave.cpp:357:13: error: in passing argument 1 of 'void cv::ApplyExifOrientation(cv::ExifReader&, cv::Mat&)'
 static void ApplyExifOrientation(ExifReader& exif, Mat& img)
             ^
/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/loadsave.cpp: In function 'bool cv::imreadmulti_(const cv::String&, int, std::vector<cv::Mat>&)':
/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/loadsave.cpp:611:54: error: invalid initialization of non-const reference of type 'cv::ExifReader&' from an rvalue of type 'cv::ExifReader'
             ApplyExifOrientation(decoder->exif(), mat);
                                                      ^
/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/loadsave.cpp:357:13: error: in passing argument 1 of 'void cv::ApplyExifOrientation(cv::ExifReader&, cv::Mat&)'
 static void ApplyExifOrientation(ExifReader& exif, Mat& img)
             ^
/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/loadsave.cpp: In function 'void* cv::imdecode_(const cv::Mat&, int, int, cv::Mat*)':
/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/loadsave.cpp:906:51: error: invalid initialization of non-const reference of type 'cv::ExifReader&' from an rvalue of type 'cv::ExifReader'
         ApplyExifOrientation(decoder->exif(), *mat);
                                                   ^
/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/loadsave.cpp:357:13: error: in passing argument 1 of 'void cv::ApplyExifOrientation(cv::ExifReader&, cv::Mat&)'
 static void ApplyExifOrientation(ExifReader& exif, Mat& img)

int width() const { return m_width; }
int height() const { return m_height; }
virtual int type() const { return m_type; }
ExifReader exif() const { return m_exif; }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ExifReader

reference: ExifReader&?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you @alalek. My bad. I changed that code slightly to return an ExifEntry_t copy instead, as returning an exif reference that could be altered seemed poor design. The decoder should be the only class able to edit the ExifReader.

The current PR contains squashed fix, and appears to be failing the build now only due to missing the png exif orientation test image files to execute the new test cases. The test files are in a PR on opencv_extra: opencv/opencv_extra#843

@raaldrid raaldrid force-pushed the Exif_support_for_PNG_issue_16579 branch 2 times, most recently from 51924b5 to ff104a9 Compare February 3, 2021 01:46
@asmorkalov
Copy link
Copy Markdown
Contributor

@raaldrid Build is still broken:

/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/grfmt_jpeg.cpp:247:46: error: 'AppMarkerTypes' is not a class or namespace
             jpeg_save_markers(&state->cinfo, AppMarkerTypes::APP1, 0xffff);
                                              ^
/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/grfmt_jpeg.cpp: In member function 'virtual bool cv::JpegDecoder::readData(cv::Mat&)':
/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/grfmt_jpeg.cpp:465:40: error: 'AppMarkerTypes' is not a class or namespace
                 if (cmarker->marker == AppMarkerTypes::APP1)
                                        ^
make[2]: *** [modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/src/grfmt_jpeg.cpp.o] Error 1

@raaldrid raaldrid force-pushed the Exif_support_for_PNG_issue_16579 branch 2 times, most recently from a0944da to 6ae58eb Compare February 4, 2021 04:13
@raaldrid
Copy link
Copy Markdown
Contributor Author

raaldrid commented Feb 4, 2021

Hi @alalek, apologies for the build issues. I need to configure my local setup to use CMake natively. I am using VS CMake plugin which is obviously not mirroring the build process accurately. While I'm doing that, I wanted to bring to your attention the latest error(s):

/build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/grfmt_png.cpp:291:50: error: 'PNG_INFO_eXIf' was not declared in this scope if( png_get_valid(png_ptr, info_ptr, PNG_INFO_eXIf) ) ^ /build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/grfmt_png.cpp:292:67: error: 'png_get_eXIf_1' was not declared in this scope png_get_eXIf_1(png_ptr, info_ptr, &num_exif, &exif); ^ /build/precommit_linux64/3.4/opencv/modules/imgcodecs/src/grfmt_png.cpp:294:67: error: 'png_get_eXIf_1' was not declared in this scope png_get_eXIf_1(png_ptr, end_info, &num_exif, &exif);

This stumped me for a little. What I believe to be happening is that the build is using version 1.2.50 of libpng. Exif support was added to libpng in version 1.6.31 (revised in 1.6.32, so that version or greater is desired). From the CMake stdio log:

-- Found PNG: /usr/lib/x86_64-linux-gnu/libpng.so (found version "1.2.50") -- Looking for /usr/include/libpng/png.h -- Looking for /usr/include/libpng/png.h - found

Is it possible to update the libpng version in 3.4 branch to 1.6.32 or greater? Thanks.

References for libpng version 1.6.31 and 1.6.32 exif support/changes:
http://www.libpng.org/pub/png/libpng-manual.txt
https://fossies.org/linux/libpng/CHANGES

@alalek
Copy link
Copy Markdown
Member

alalek commented Feb 4, 2021

/usr/lib/x86_64-linux-gnu/libpng.so

This is a system dependency. It can't be upgraded.

You should add version check through #if and disable functionality in #else branch for unsupported libpng versions.

@raaldrid raaldrid force-pushed the Exif_support_for_PNG_issue_16579 branch 4 times, most recently from 4af7460 to 98d3012 Compare February 5, 2021 19:43
@raaldrid
Copy link
Copy Markdown
Contributor Author

raaldrid commented Feb 5, 2021

I added #if version check to the PR. Interestingly it looks like the included header version is different from the libpng.so file for 3 of the builds which appear to be failing due to the new test cases. The new test cases I also #if version checked so they should not be running unless a newer version of libpng is being used, thus my theory that the included header doesn't match the .so version. Ideas? I #if checked the new test cases because they will fail if an old lippng is in use.

@asmorkalov
Copy link
Copy Markdown
Contributor

jenkins cn please retry a build

@raaldrid raaldrid force-pushed the Exif_support_for_PNG_issue_16579 branch 2 times, most recently from f88ba27 to cf9381d Compare February 8, 2021 18:22
@raaldrid
Copy link
Copy Markdown
Contributor Author

raaldrid commented Feb 8, 2021

@asmorkalov I don't understand the meaning behind "jenkins cn". I did retry a build. The Jenkins builds are still failing, tho buildbot seems fine. The Jenkins builds are now failing due to other test cases not being able to find files:

Test Result (4 failures / ±0)opencv_test_dnn / Test_ONNX_layers.NormalizeFusionSubgraph/0opencv_test_dnn / Test_ONNX_layers.Mish/0opencv_test_dnn / Test_ONNX_layers.CalculatePads/0opencv_test_dnn / Test_TensorFlow_layers.leaky_relu/0

Question: I am puzzled why the buildbot builds are all passing when my PR for opencv_extra hasn't been approved? (opencv/opencv_extra#843) The test files for png exif shouldn't exist in the repo so I am puzzled why those test cases are succeeding. (And per the debug output they are succeeding, not being omitted due to an old libpng version.)

@asmorkalov
Copy link
Copy Markdown
Contributor

@raaldrid Sorry for confusion. Jenkins is very young and is not well aligned with BuildBot's strategy for opencv_extra PRs. We are working on that right now. Please ignore Jenkins status for now, only BuildBot pass is required.

…oder specific Exif parsing to JPEG and PNG decoders, respectively. Issue 16579
@raaldrid raaldrid force-pushed the Exif_support_for_PNG_issue_16579 branch from 45f175a to 650836d Compare February 9, 2021 18:36
@raaldrid
Copy link
Copy Markdown
Contributor Author

raaldrid commented Feb 9, 2021

@asmorkalov Okay. Thank you for the clarification. I assume my PR is under code review, then. I made one final edit (tested previously) to switch from comparing #if PNG_LIBPNG_VER >= 1.6.31 to #ifdef PNG_eXIf_SUPPORTED (defined in pnglibconf.h). I think the latter is more self explanatory and better aligned with the intended use of libpng. From I can see both have the same end result.

If you have a suggestion for an issue for me to tackle next I would appreciate it. Otherwise I will dig around.

@raaldrid raaldrid requested a review from alalek February 10, 2021 18:51
Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

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

Well done! Thank you for great contribution 👍

@opencv-pushbot opencv-pushbot merged commit 93783df into opencv:3.4 Feb 10, 2021
@alalek alalek mentioned this pull request Feb 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenCV does not respect exif orientation in PNG file

4 participants