From 424f9137f798faee7b40342503d06e11bd18d1a1 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Sat, 24 Feb 2024 11:47:42 -0800 Subject: [PATCH] fix(heic): Don't auto-transform camera-rotated images (#4142) It seems that unlike most image formats where we merely note the camera rotation but don't rotate the pixels, the heic reader automatically rotated. The trick is that using the C++ API wrapper of libheif, there is no way to pass the decoder options struct that is where you need to say not to auto-transform. Needed to drop down to the lower level C API for this one spot. We want this format to behave like the others -- the orientation is advisory, and it's up to the app how to deal with it. But we have back compatibility to deal with. If a rotated image is aecountered, OIIO 2.5 and earlier will by default still auto-rotate to preserve compatibility, but OIIO 2.6+ will not auto-rotate. When not rotating, the Orientation metadata will reflect the desired display orientation of the image, according to what was in the file. When auto-rotating, Orientation will be 1 (canonical display orientation), and a new attribute "heif:Orientation" will reflect what was originally in the file. When opening a file for input, the special configuration metadata hint "heif:reorient" can express a preference for auto-rotation, overriding the default. Thus, setting this hint to 0 for OIIO 2.5 will turn off auto-rotation, and setting it to 1 for OIIO 2.6+ will make it auto-rotate like it used to do. I also added some additional tests for heif files. Along the way I fixed a rather embarrassing documentation problem as well, where all the orientation codes were "off by 1", oh boy. Fixes #4123 --------- Signed-off-by: Larry Gritz --- src/cmake/testing.cmake | 6 +- src/doc/builtinplugins.rst | 28 +++++ src/doc/imageinput.rst | 4 + src/doc/stdmetadata.rst | 26 ++-- src/heif.imageio/heifinput.cpp | 118 +++++++++++++++--- testsuite/heif/ref/out-libheif1.4.txt | 112 +++++++++++++++++ testsuite/heif/ref/out-libheif1.5.txt | 112 +++++++++++++++++ .../heif/ref/out-libheif1.9-with-av1.txt | 107 ++++++++++++++++ testsuite/heif/ref/out-libheif1.9.txt | 107 ++++++++++++++++ testsuite/heif/run.py | 4 + 10 files changed, 593 insertions(+), 31 deletions(-) diff --git a/src/cmake/testing.cmake b/src/cmake/testing.cmake index 52f3a9d8f8..8b26cb46aa 100644 --- a/src/cmake/testing.cmake +++ b/src/cmake/testing.cmake @@ -260,8 +260,10 @@ macro (oiio_add_all_tests) IMAGEDIR openexr-images URL http://github.com/AcademySoftwareFoundation/openexr-images) oiio_add_tests (heif - FOUNDVAR Libheif_FOUND ENABLEVAR ENABLE_Libheif - URL https://github.com/nokiatech/heif/tree/gh-pages/content) + FOUNDVAR Libheif_FOUND + ENABLEVAR ENABLE_Libheif + IMAGEDIR oiio-images/heif + URL http://github.com/AcademySoftwareFoundation/openexr-images) oiio_add_tests (ico ENABLEVAR ENABLE_ICO IMAGEDIR oiio-images URL "Recent checkout of oiio-images") diff --git a/src/doc/builtinplugins.rst b/src/doc/builtinplugins.rst index d5fc7c7192..adddb5d9a3 100644 --- a/src/doc/builtinplugins.rst +++ b/src/doc/builtinplugins.rst @@ -685,6 +685,11 @@ preferred except when legacy file access is required. * - ``oiio:Gamma`` - float - the gamma correction specified in the RGBE header (if it's gamma corrected). + * - ``heif:Orientation`` + - int + - If the configuration option ``heif:reorient`` is nonzero and + reorientation was performed, this will be set to the original + orientation in the file. **Configuration settings for HDR input** @@ -704,6 +709,14 @@ options are supported: - ptr - Pointer to a ``Filesystem::IOProxy`` that will handle the I/O, for example by reading from memory rather than the file system. + * - ``oiio:reorient`` + - int + - The default of 1 means to let libheif auto-reorient the image to + undo the camera's orientation (this will set a "heif:Orientation" + metadata to the Exif orientation code indicating the original + orientation of the image). If this hint is set to 0, the pixels will be + left in their orientation as stored in the file, and the "Orientation" + metadata will reflect that. **Configuration settings for HDR output** @@ -750,6 +763,15 @@ currently supported for reading, but not yet writing. All pixel data is uint8, though we hope to add support for HDR (more than 8 bits) in the future. +The default behavior of the HEIF reader is to reorient the image to the +orientation indicated by the camera, and to report the "Orientation" metadata +as 1 (indicating that the image should be displayed as returned) and set the +"oiio:OriginalOrientation" metadata to what was originally stored in the file. +If you want to read the image without automatic reorientation, you can set the +configuration option "oiio:reorient" to 0, in which case the pixels will be +left in their orientation as stored in the file, and the "Orientation" +metadata will reflect that. + **Configuration settings for HEIF input** When opening an HEIF ImageInput with a *configuration* (see @@ -769,6 +791,12 @@ attributes are supported: cause the reader to leave alpha unassociated (versus the default of premultiplying color channels by alpha if the alpha channel is unassociated). + * - ``oiio:reorient`` + - int + - If nonzero, asks libheif to reorient any images (and report them as + having Orientation 1). If zero, then libheif will not reorient the + image and the Orientation metadata will be set to reflect the camera + orientation. **Configuration settings for HEIF output** diff --git a/src/doc/imageinput.rst b/src/doc/imageinput.rst index 36d85511d6..7d1db81b73 100644 --- a/src/doc/imageinput.rst +++ b/src/doc/imageinput.rst @@ -923,6 +923,10 @@ hints are supported by each reader) are: cause the reader to leave alpha unassociated (versus the default of premultiplying color channels by alpha if the alpha channel is unassociated). + * - ``oiio:reorient`` + - int + - If zero, disables any automatic reorientation that the reader may + ordinarily do to present te pixels in the preferred display orientation. Examples: diff --git a/src/doc/stdmetadata.rst b/src/doc/stdmetadata.rst index 96836367df..a66cbb54c1 100644 --- a/src/doc/stdmetadata.rst +++ b/src/doc/stdmetadata.rst @@ -77,21 +77,21 @@ Display hints .. option:: "Orientation" : int - y default, image pixels are ordered from the top of the display to the - ottom, and within each scanline, from left to right (i.e., the same - rdering as English text and scan progression on a CRT). But the - "Orientation"` field can suggest that it should be displayed with - different orientation, according to the TIFF/EXIF conventions: + By default, image pixels are ordered from the top of the display to the + bottom, and within each scanline, from left to right (i.e., the same + ordering as English text and scan progression on a CRT). But the + `"Orientation"` field can suggest that it should be displayed with + a different orientation, according to the TIFF/EXIF conventions: === ========================================================================== - 0 normal (top to bottom, left to right) - 1 flipped horizontally (top to botom, right to left) - 2 rotated :math:`180^\circ` (bottom to top, right to left) - 3 flipped vertically (bottom to top, left to right) - 4 transposed (left to right, top to bottom) - 5 rotated :math:`90^\circ` clockwise (right to left, top to bottom) - 6 transverse (right to left, bottom to top) - 7 rotated :math:`90^\circ` counter-clockwise (left to right, bottom to top) + 1 normal (top to bottom, left to right) + 2 flipped horizontally (top to bottom, right to left) + 3 rotated :math:`180^\circ` (bottom to top, right to left) + 4 flipped vertically (bottom to top, left to right) + 5 transposed (left to right, top to bottom) + 6 rotated :math:`90^\circ` clockwise (right to left, top to bottom) + 7 transverse (right to left, bottom to top) + 8 rotated :math:`90^\circ` counter-clockwise (left to right, bottom to top) === ========================================================================== .. option:: "PixelAspectRatio" : float diff --git a/src/heif.imageio/heifinput.cpp b/src/heif.imageio/heifinput.cpp index 3b833d36f0..cba7b20d16 100644 --- a/src/heif.imageio/heifinput.cpp +++ b/src/heif.imageio/heifinput.cpp @@ -8,6 +8,14 @@ #include +#define MAKE_LIBHEIF_VERSION(a, b, c, d) \ + (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) + +#if LIBHEIF_NUMERIC_VERSION >= MAKE_LIBHEIF_VERSION(1, 17, 0, 0) +# include +#endif + + // This plugin utilises libheif: // https://github.com/strukturag/libheif @@ -18,6 +26,7 @@ // https://github.com/nokiatech/heif/tree/gh-pages/content + OIIO_PLUGIN_NAMESPACE_BEGIN class HeifInput final : public ImageInput { @@ -50,6 +59,7 @@ class HeifInput final : public ImageInput { bool m_associated_alpha = true; bool m_keep_unassociated_alpha = false; bool m_do_associate = false; + bool m_reorient = true; std::unique_ptr m_ctx; heif_item_id m_primary_id; // id of primary image std::vector m_item_ids; // ids of all other images @@ -137,6 +147,7 @@ HeifInput::open(const std::string& name, ImageSpec& newspec, m_keep_unassociated_alpha = (config.get_int_attribute("oiio:UnassociatedAlpha") != 0); + m_reorient = config.get_int_attribute("oiio:reorient", 1); try { m_ctx->read_from_file(name); @@ -200,14 +211,14 @@ HeifInput::seek_subimage(int subimage, int miplevel) return false; } + auto id = (subimage == 0) ? m_primary_id : m_item_ids[subimage - 1]; + m_ihandle = m_ctx->get_image_handle(id); + m_has_alpha = m_ihandle.has_alpha_channel(); + auto chroma = m_has_alpha ? heif_chroma_interleaved_RGBA + : heif_chroma_interleaved_RGB; +#if 0 try { - auto id = (subimage == 0) ? m_primary_id : m_item_ids[subimage - 1]; - m_ihandle = m_ctx->get_image_handle(id); - m_has_alpha = m_ihandle.has_alpha_channel(); - auto chroma = m_has_alpha ? heif_chroma_interleaved_RGBA - : heif_chroma_interleaved_RGB; - m_himage = m_ihandle.decode_image(heif_colorspace_RGB, chroma); - + m_himage = m_ihandle.decode_image(heif_colorspace_RGB, chroma); } catch (const heif::Error& err) { std::string e = err.get_message(); errorf("%s", e.empty() ? "unknown exception" : e.c_str()); @@ -217,6 +228,23 @@ HeifInput::seek_subimage(int subimage, int miplevel) errorf("%s", e.empty() ? "unknown exception" : e.c_str()); return false; } +#else + std::unique_ptr + options(heif_decoding_options_alloc(), heif_decoding_options_free); + options->ignore_transformations = !m_reorient; + // print("Got decoding options version {}\n", options->version); + struct heif_image* img_tmp = nullptr; + struct heif_error herr = heif_decode_image(m_ihandle.get_raw_image_handle(), + &img_tmp, heif_colorspace_RGB, + chroma, options.get()); + if (img_tmp) + m_himage = heif::Image(img_tmp); + if (herr.code != heif_error_Ok || !img_tmp) { + errorfmt("Could not decode image ({})", herr.message); + m_ctx.reset(); + return false; + } +#endif int bits = m_himage.get_bits_per_pixel(heif_channel_interleaved); m_spec = ImageSpec(m_ihandle.get_width(), m_ihandle.get_height(), bits / 8, @@ -270,21 +298,79 @@ HeifInput::seek_subimage(int subimage, int miplevel) decode_xmp(metacontents, m_spec); } else { #ifdef DEBUG - std::cout << "Don't know how to decode meta " << m - << " type=" << m_ihandle.get_metadata_type(m) - << " contenttype='" - << m_ihandle.get_metadata_content_type(m) << "'\n"; - std::cout << "---\n" - << string_view((const char*)&metacontents[0], - metacontents.size()) - << "\n---\n"; + print( + "Don't know how to decode meta {} type='{}' contenttype='{}'\n", + m, m_ihandle.get_metadata_type(m), + m_ihandle.get_metadata_content_type(m)); + print("---\n{}\n---\n", + string_view((const char*)metacontents.data(), + metacontents.size())); #endif } } + // Try to discover the orientation. The Exif is unreliable. We have to go + // through the transformation properties ourselves. A tricky bit is that + // the C++ API doesn't give us a direct way to get the context ptr, we + // need to resort to some casting trickery, with knowledge that the C++ + // heif::Context class consists solely of a std::shared_ptr to a + // heif_context. + // NO int orientation = m_spec.get_int_attribute("Orientation", 1); + int orientation = 1; + const heif_context* raw_ctx + = reinterpret_cast*>(m_ctx.get())->get(); + int xpcount = heif_item_get_transformation_properties(raw_ctx, id, nullptr, + 100); + orientation = 1; + xpcount = std::min(xpcount, 100); // clamp to some reasonable limit + std::vector xprops(xpcount); + heif_item_get_transformation_properties(raw_ctx, id, xprops.data(), + xpcount); + for (int i = 0; i < xpcount; ++i) { + auto type = heif_item_get_property_type(raw_ctx, id, xprops[i]); + if (type == heif_item_property_type_transform_rotation) { + int rot = heif_item_get_property_transform_rotation_ccw(raw_ctx, id, + xprops[i]); + // cw[] maps to one additional clockwise 90 degree turn + static const int cw[] = { 0, 6, 7, 8, 5, 2, 3, 4, 1 }; + for (int i = 0; i < rot / 90; ++i) + orientation = cw[orientation]; + } else if (type == heif_item_property_type_transform_mirror) { + int mirror = heif_item_get_property_transform_mirror(raw_ctx, id, + xprops[i]); + // 1 2 3 4 5 6 7 8 + static const int mirrorh[] = { 0, 2, 1, 4, 3, 6, 5, 8, 7 }; + static const int mirrorv[] = { 0, 4, 3, 2, 1, 8, 7, 6, 5 }; + if (mirror == heif_transform_mirror_direction_vertical) { + orientation = mirrorv[orientation]; + } else if (mirror == heif_transform_mirror_direction_horizontal) { + orientation = mirrorh[orientation]; + } + } + } + // Erase the orientation metadata because libheif appears to be doing // the rotation-to-canonical-direction for us. - m_spec.erase_attribute("Orientation"); + if (orientation != 1) { + if (m_reorient) { + // If libheif auto-reoriented, record the original orientation in + // "oiio:OriginalOrientation" and set the "Orientation" attribute + // to 1 since we're presenting the image to the caller in the + // usual orientation. + m_spec.attribute("oiio:OriginalOrientation", orientation); + m_spec.attribute("Orientation", 1); + } else { + // libheif supplies oriented width & height, so if we are NOT + // auto-reorienting and it's one of the orientations that swaps + // width and height, we need to do that swap ourselves. + // Note: all the orientations that swap width and height are 5-8, + // whereas 1-4 preserve aspect ratio. + if (orientation >= 5) { + std::swap(m_spec.width, m_spec.height); + std::swap(m_spec.full_width, m_spec.full_height); + } + } + } m_subimage = subimage; return true; diff --git a/testsuite/heif/ref/out-libheif1.4.txt b/testsuite/heif/ref/out-libheif1.4.txt index c9639d4c0d..11a6e3c543 100644 --- a/testsuite/heif/ref/out-libheif1.4.txt +++ b/testsuite/heif/ref/out-libheif1.4.txt @@ -7,6 +7,7 @@ ref/IMG_7702_small.heic : 512 x 300, 3 channel, uint8 heif FNumber: 1.8 Make: "Apple" Model: "iPhone 7" + Orientation: 1 (normal) ResolutionUnit: 2 (inches) Software: "12.1.2" XResolution: 72 @@ -38,3 +39,114 @@ ref/IMG_7702_small.heic : 512 x 300, 3 channel, uint8 heif Exif:SubsecTimeOriginal: "006" Exif:WhiteBalance: 0 (auto) oiio:ColorSpace: "sRGB" +Reading ref/Chimera-AV1-8bit-162.avif +ref/Chimera-AV1-8bit-162.avif : 480 x 270, 3 channel, uint8 heif + SHA-1: F8FDAF1BD56A21E3AF99CF8EE7FA45434D2826C7 + channel list: R, G, B + oiio:ColorSpace: "sRGB" +Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic +../oiio-images/heif/greyhounds-looking-for-a-table.heic : 3024 x 4032, 3 channel, uint8 heif + SHA-1: 8211F56BBABDC7615CCAF67CBF49741D1A292D2E + channel list: R, G, B + DateTime: "2023:09:28 09:44:03" + ExposureTime: 0.0135135 + FNumber: 2.4 + Make: "Apple" + Model: "iPhone 12 Pro" + Orientation: 1 (normal) + ResolutionUnit: 2 (inches) + Software: "16.7" + XResolution: 72 + YResolution: 72 + Exif:ApertureValue: 2.52607 (f/2.4) + Exif:BrightnessValue: 2.7506 + Exif:ColorSpace: 65535 + Exif:DateTimeDigitized: "2023:09:28 09:44:03" + Exif:DateTimeOriginal: "2023:09:28 09:44:03" + Exif:DigitalZoomRatio: 1.3057 + Exif:ExifVersion: "0232" + Exif:ExposureBiasValue: 0 + Exif:ExposureMode: 0 (auto) + Exif:ExposureProgram: 2 (normal program) + Exif:Flash: 16 (no flash, flash suppression) + Exif:FocalLength: 1.54 (1.54 mm) + Exif:FocalLengthIn35mmFilm: 17 + Exif:LensMake: "Apple" + Exif:LensModel: "iPhone 12 Pro back triple camera 1.54mm f/2.4" + Exif:LensSpecification: 1.54, 6, 1.6, 2.4 + Exif:MeteringMode: 5 (pattern) + Exif:OffsetTime: "+02:00" + Exif:OffsetTimeDigitized: "+02:00" + Exif:OffsetTimeOriginal: "+02:00" + Exif:PhotographicSensitivity: 320 + Exif:PixelXDimension: 4032 + Exif:PixelYDimension: 3024 + Exif:SensingMethod: 2 (1-chip color area) + Exif:ShutterSpeedValue: 6.20983 (1/74 s) + Exif:SubsecTimeDigitized: "886" + Exif:SubsecTimeOriginal: "886" + Exif:WhiteBalance: 0 (auto) + GPS:Altitude: 3.24105 (3.24105 m) + GPS:AltitudeRef: 0 (above sea level) + GPS:DateStamp: "2023:09:28" + GPS:DestBearing: 90.2729 + GPS:DestBearingRef: "T" (true north) + GPS:HPositioningError: 5.1893 + GPS:ImgDirection: 90.2729 + GPS:ImgDirectionRef: "T" (true north) + GPS:Latitude: 41, 50, 58.43 + GPS:LatitudeRef: "N" + GPS:Longitude: 3, 7, 31.98 + GPS:LongitudeRef: "E" + GPS:Speed: 0.171966 + GPS:SpeedRef: "K" (km/hour) + oiio:ColorSpace: "sRGB" + oiio:OriginalOrientation: 6 +Reading ../oiio-images/heif/sewing-threads.heic +../oiio-images/heif/sewing-threads.heic : 4000 x 3000, 3 channel, uint8 heif + SHA-1: 6A061BFE2F0BAC4CC94F5D9D5A6E674634149813 + channel list: R, G, B + DateTime: "2023:12:12 18:39:16" + ExposureTime: 0.04 + FNumber: 1.8 + Make: "samsung" + Model: "SM-A326B" + Orientation: 1 (normal) + ResolutionUnit: 2 (inches) + Software: "A326BXXS8CWK2" + XResolution: 72 + YResolution: 72 + Exif:ApertureValue: 1.69 (f/1.8) + Exif:BrightnessValue: 1.19 + Exif:ColorSpace: 1 + Exif:DateTimeDigitized: "2023:12:12 18:39:16" + Exif:DateTimeOriginal: "2023:12:12 18:39:16" + Exif:DigitalZoomRatio: 1 + Exif:ExifVersion: "0220" + Exif:ExposureBiasValue: 0 + Exif:ExposureMode: 0 (auto) + Exif:ExposureProgram: 2 (normal program) + Exif:Flash: 0 (no flash) + Exif:FocalLength: 4.6 (4.6 mm) + Exif:FocalLengthIn35mmFilm: 25 + Exif:MaxApertureValue: 1.69 (f/1.8) + Exif:MeteringMode: 2 (center-weighted average) + Exif:OffsetTime: "+01:00" + Exif:OffsetTimeOriginal: "+01:00" + Exif:PhotographicSensitivity: 500 + Exif:PixelXDimension: 4000 + Exif:PixelYDimension: 3000 + Exif:SceneCaptureType: 0 (standard) + Exif:ShutterSpeedValue: 0.04 (1/1 s) + Exif:SubsecTime: "576" + Exif:SubsecTimeDigitized: "576" + Exif:SubsecTimeOriginal: "576" + Exif:WhiteBalance: 0 (auto) + Exif:YCbCrPositioning: 1 + GPS:Altitude: 292 (292 m) + GPS:AltitudeRef: 0 (above sea level) + GPS:Latitude: 41, 43, 33.821 + GPS:LatitudeRef: "N" + GPS:Longitude: 1, 49, 34.0187 + GPS:LongitudeRef: "E" + oiio:ColorSpace: "sRGB" diff --git a/testsuite/heif/ref/out-libheif1.5.txt b/testsuite/heif/ref/out-libheif1.5.txt index b3fc595fa5..88a06c0b02 100644 --- a/testsuite/heif/ref/out-libheif1.5.txt +++ b/testsuite/heif/ref/out-libheif1.5.txt @@ -7,6 +7,7 @@ ref/IMG_7702_small.heic : 512 x 300, 3 channel, uint8 heif FNumber: 1.8 Make: "Apple" Model: "iPhone 7" + Orientation: 1 (normal) ResolutionUnit: 2 (inches) Software: "12.1.2" XResolution: 72 @@ -38,3 +39,114 @@ ref/IMG_7702_small.heic : 512 x 300, 3 channel, uint8 heif Exif:SubsecTimeOriginal: "006" Exif:WhiteBalance: 0 (auto) oiio:ColorSpace: "sRGB" +Reading ref/Chimera-AV1-8bit-162.avif +ref/Chimera-AV1-8bit-162.avif : 480 x 270, 3 channel, uint8 heif + SHA-1: F8FDAF1BD56A21E3AF99CF8EE7FA45434D2826C7 + channel list: R, G, B + oiio:ColorSpace: "sRGB" +Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic +../oiio-images/heif/greyhounds-looking-for-a-table.heic : 3024 x 4032, 3 channel, uint8 heif + SHA-1: 8211F56BBABDC7615CCAF67CBF49741D1A292D2E + channel list: R, G, B + DateTime: "2023:09:28 09:44:03" + ExposureTime: 0.0135135 + FNumber: 2.4 + Make: "Apple" + Model: "iPhone 12 Pro" + Orientation: 1 (normal) + ResolutionUnit: 2 (inches) + Software: "16.7" + XResolution: 72 + YResolution: 72 + Exif:ApertureValue: 2.52607 (f/2.4) + Exif:BrightnessValue: 2.7506 + Exif:ColorSpace: 65535 + Exif:DateTimeDigitized: "2023:09:28 09:44:03" + Exif:DateTimeOriginal: "2023:09:28 09:44:03" + Exif:DigitalZoomRatio: 1.3057 + Exif:ExifVersion: "0232" + Exif:ExposureBiasValue: 0 + Exif:ExposureMode: 0 (auto) + Exif:ExposureProgram: 2 (normal program) + Exif:Flash: 16 (no flash, flash suppression) + Exif:FocalLength: 1.54 (1.54 mm) + Exif:FocalLengthIn35mmFilm: 17 + Exif:LensMake: "Apple" + Exif:LensModel: "iPhone 12 Pro back triple camera 1.54mm f/2.4" + Exif:LensSpecification: 1.54, 6, 1.6, 2.4 + Exif:MeteringMode: 5 (pattern) + Exif:OffsetTime: "+02:00" + Exif:OffsetTimeDigitized: "+02:00" + Exif:OffsetTimeOriginal: "+02:00" + Exif:PhotographicSensitivity: 320 + Exif:PixelXDimension: 4032 + Exif:PixelYDimension: 3024 + Exif:SensingMethod: 2 (1-chip color area) + Exif:ShutterSpeedValue: 6.20983 (1/74 s) + Exif:SubsecTimeDigitized: "886" + Exif:SubsecTimeOriginal: "886" + Exif:WhiteBalance: 0 (auto) + GPS:Altitude: 3.24105 (3.24105 m) + GPS:AltitudeRef: 0 (above sea level) + GPS:DateStamp: "2023:09:28" + GPS:DestBearing: 90.2729 + GPS:DestBearingRef: "T" (true north) + GPS:HPositioningError: 5.1893 + GPS:ImgDirection: 90.2729 + GPS:ImgDirectionRef: "T" (true north) + GPS:Latitude: 41, 50, 58.43 + GPS:LatitudeRef: "N" + GPS:Longitude: 3, 7, 31.98 + GPS:LongitudeRef: "E" + GPS:Speed: 0.171966 + GPS:SpeedRef: "K" (km/hour) + oiio:ColorSpace: "sRGB" + oiio:OriginalOrientation: 6 +Reading ../oiio-images/heif/sewing-threads.heic +../oiio-images/heif/sewing-threads.heic : 4000 x 3000, 3 channel, uint8 heif + SHA-1: 6A061BFE2F0BAC4CC94F5D9D5A6E674634149813 + channel list: R, G, B + DateTime: "2023:12:12 18:39:16" + ExposureTime: 0.04 + FNumber: 1.8 + Make: "samsung" + Model: "SM-A326B" + Orientation: 1 (normal) + ResolutionUnit: 2 (inches) + Software: "A326BXXS8CWK2" + XResolution: 72 + YResolution: 72 + Exif:ApertureValue: 1.69 (f/1.8) + Exif:BrightnessValue: 1.19 + Exif:ColorSpace: 1 + Exif:DateTimeDigitized: "2023:12:12 18:39:16" + Exif:DateTimeOriginal: "2023:12:12 18:39:16" + Exif:DigitalZoomRatio: 1 + Exif:ExifVersion: "0220" + Exif:ExposureBiasValue: 0 + Exif:ExposureMode: 0 (auto) + Exif:ExposureProgram: 2 (normal program) + Exif:Flash: 0 (no flash) + Exif:FocalLength: 4.6 (4.6 mm) + Exif:FocalLengthIn35mmFilm: 25 + Exif:MaxApertureValue: 1.69 (f/1.8) + Exif:MeteringMode: 2 (center-weighted average) + Exif:OffsetTime: "+01:00" + Exif:OffsetTimeOriginal: "+01:00" + Exif:PhotographicSensitivity: 500 + Exif:PixelXDimension: 4000 + Exif:PixelYDimension: 3000 + Exif:SceneCaptureType: 0 (standard) + Exif:ShutterSpeedValue: 0.04 (1/1 s) + Exif:SubsecTime: "576" + Exif:SubsecTimeDigitized: "576" + Exif:SubsecTimeOriginal: "576" + Exif:WhiteBalance: 0 (auto) + Exif:YCbCrPositioning: 1 + GPS:Altitude: 292 (292 m) + GPS:AltitudeRef: 0 (above sea level) + GPS:Latitude: 41, 43, 33.821 + GPS:LatitudeRef: "N" + GPS:Longitude: 1, 49, 34.0187 + GPS:LongitudeRef: "E" + oiio:ColorSpace: "sRGB" diff --git a/testsuite/heif/ref/out-libheif1.9-with-av1.txt b/testsuite/heif/ref/out-libheif1.9-with-av1.txt index ea3ee36684..6d7074e131 100644 --- a/testsuite/heif/ref/out-libheif1.9-with-av1.txt +++ b/testsuite/heif/ref/out-libheif1.9-with-av1.txt @@ -7,6 +7,7 @@ ref/IMG_7702_small.heic : 512 x 300, 3 channel, uint8 heif FNumber: 1.8 Make: "Apple" Model: "iPhone 7" + Orientation: 1 (normal) ResolutionUnit: 2 (inches) Software: "12.1.2" XResolution: 72 @@ -43,3 +44,109 @@ ref/Chimera-AV1-8bit-162.avif : 480 x 270, 3 channel, uint8 heif SHA-1: F8FDAF1BD56A21E3AF99CF8EE7FA45434D2826C7 channel list: R, G, B oiio:ColorSpace: "sRGB" +Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic +../oiio-images/heif/greyhounds-looking-for-a-table.heic : 3024 x 4032, 3 channel, uint8 heif + SHA-1: 8211F56BBABDC7615CCAF67CBF49741D1A292D2E + channel list: R, G, B + DateTime: "2023:09:28 09:44:03" + ExposureTime: 0.0135135 + FNumber: 2.4 + Make: "Apple" + Model: "iPhone 12 Pro" + Orientation: 1 (normal) + ResolutionUnit: 2 (inches) + Software: "16.7" + XResolution: 72 + YResolution: 72 + Exif:ApertureValue: 2.52607 (f/2.4) + Exif:BrightnessValue: 2.7506 + Exif:ColorSpace: 65535 + Exif:DateTimeDigitized: "2023:09:28 09:44:03" + Exif:DateTimeOriginal: "2023:09:28 09:44:03" + Exif:DigitalZoomRatio: 1.3057 + Exif:ExifVersion: "0232" + Exif:ExposureBiasValue: 0 + Exif:ExposureMode: 0 (auto) + Exif:ExposureProgram: 2 (normal program) + Exif:Flash: 16 (no flash, flash suppression) + Exif:FocalLength: 1.54 (1.54 mm) + Exif:FocalLengthIn35mmFilm: 17 + Exif:LensMake: "Apple" + Exif:LensModel: "iPhone 12 Pro back triple camera 1.54mm f/2.4" + Exif:LensSpecification: 1.54, 6, 1.6, 2.4 + Exif:MeteringMode: 5 (pattern) + Exif:OffsetTime: "+02:00" + Exif:OffsetTimeDigitized: "+02:00" + Exif:OffsetTimeOriginal: "+02:00" + Exif:PhotographicSensitivity: 320 + Exif:PixelXDimension: 4032 + Exif:PixelYDimension: 3024 + Exif:SensingMethod: 2 (1-chip color area) + Exif:ShutterSpeedValue: 6.20983 (1/74 s) + Exif:SubsecTimeDigitized: "886" + Exif:SubsecTimeOriginal: "886" + Exif:WhiteBalance: 0 (auto) + GPS:Altitude: 3.24105 (3.24105 m) + GPS:AltitudeRef: 0 (above sea level) + GPS:DateStamp: "2023:09:28" + GPS:DestBearing: 90.2729 + GPS:DestBearingRef: "T" (true north) + GPS:HPositioningError: 5.1893 + GPS:ImgDirection: 90.2729 + GPS:ImgDirectionRef: "T" (true north) + GPS:Latitude: 41, 50, 58.43 + GPS:LatitudeRef: "N" + GPS:Longitude: 3, 7, 31.98 + GPS:LongitudeRef: "E" + GPS:Speed: 0.171966 + GPS:SpeedRef: "K" (km/hour) + oiio:ColorSpace: "sRGB" + oiio:OriginalOrientation: 6 +Reading ../oiio-images/heif/sewing-threads.heic +../oiio-images/heif/sewing-threads.heic : 4000 x 3000, 3 channel, uint8 heif + SHA-1: 6A061BFE2F0BAC4CC94F5D9D5A6E674634149813 + channel list: R, G, B + DateTime: "2023:12:12 18:39:16" + ExposureTime: 0.04 + FNumber: 1.8 + Make: "samsung" + Model: "SM-A326B" + Orientation: 1 (normal) + ResolutionUnit: 2 (inches) + Software: "A326BXXS8CWK2" + XResolution: 72 + YResolution: 72 + Exif:ApertureValue: 1.69 (f/1.8) + Exif:BrightnessValue: 1.19 + Exif:ColorSpace: 1 + Exif:DateTimeDigitized: "2023:12:12 18:39:16" + Exif:DateTimeOriginal: "2023:12:12 18:39:16" + Exif:DigitalZoomRatio: 1 + Exif:ExifVersion: "0220" + Exif:ExposureBiasValue: 0 + Exif:ExposureMode: 0 (auto) + Exif:ExposureProgram: 2 (normal program) + Exif:Flash: 0 (no flash) + Exif:FocalLength: 4.6 (4.6 mm) + Exif:FocalLengthIn35mmFilm: 25 + Exif:MaxApertureValue: 1.69 (f/1.8) + Exif:MeteringMode: 2 (center-weighted average) + Exif:OffsetTime: "+01:00" + Exif:OffsetTimeOriginal: "+01:00" + Exif:PhotographicSensitivity: 500 + Exif:PixelXDimension: 4000 + Exif:PixelYDimension: 3000 + Exif:SceneCaptureType: 0 (standard) + Exif:ShutterSpeedValue: 0.04 (1/1 s) + Exif:SubsecTime: "576" + Exif:SubsecTimeDigitized: "576" + Exif:SubsecTimeOriginal: "576" + Exif:WhiteBalance: 0 (auto) + Exif:YCbCrPositioning: 1 + GPS:Altitude: 292 (292 m) + GPS:AltitudeRef: 0 (above sea level) + GPS:Latitude: 41, 43, 33.821 + GPS:LatitudeRef: "N" + GPS:Longitude: 1, 49, 34.0187 + GPS:LongitudeRef: "E" + oiio:ColorSpace: "sRGB" diff --git a/testsuite/heif/ref/out-libheif1.9.txt b/testsuite/heif/ref/out-libheif1.9.txt index ad0902c165..efe5c1ff56 100644 --- a/testsuite/heif/ref/out-libheif1.9.txt +++ b/testsuite/heif/ref/out-libheif1.9.txt @@ -7,6 +7,7 @@ ref/IMG_7702_small.heic : 512 x 300, 3 channel, uint8 heif FNumber: 1.8 Make: "Apple" Model: "iPhone 7" + Orientation: 1 (normal) ResolutionUnit: 2 (inches) Software: "12.1.2" XResolution: 72 @@ -38,3 +39,109 @@ ref/IMG_7702_small.heic : 512 x 300, 3 channel, uint8 heif Exif:SubsecTimeOriginal: "006" Exif:WhiteBalance: 0 (auto) oiio:ColorSpace: "sRGB" +Reading ../oiio-images/heif/greyhounds-looking-for-a-table.heic +../oiio-images/heif/greyhounds-looking-for-a-table.heic : 3024 x 4032, 3 channel, uint8 heif + SHA-1: 8211F56BBABDC7615CCAF67CBF49741D1A292D2E + channel list: R, G, B + DateTime: "2023:09:28 09:44:03" + ExposureTime: 0.0135135 + FNumber: 2.4 + Make: "Apple" + Model: "iPhone 12 Pro" + Orientation: 1 (normal) + ResolutionUnit: 2 (inches) + Software: "16.7" + XResolution: 72 + YResolution: 72 + Exif:ApertureValue: 2.52607 (f/2.4) + Exif:BrightnessValue: 2.7506 + Exif:ColorSpace: 65535 + Exif:DateTimeDigitized: "2023:09:28 09:44:03" + Exif:DateTimeOriginal: "2023:09:28 09:44:03" + Exif:DigitalZoomRatio: 1.3057 + Exif:ExifVersion: "0232" + Exif:ExposureBiasValue: 0 + Exif:ExposureMode: 0 (auto) + Exif:ExposureProgram: 2 (normal program) + Exif:Flash: 16 (no flash, flash suppression) + Exif:FocalLength: 1.54 (1.54 mm) + Exif:FocalLengthIn35mmFilm: 17 + Exif:LensMake: "Apple" + Exif:LensModel: "iPhone 12 Pro back triple camera 1.54mm f/2.4" + Exif:LensSpecification: 1.54, 6, 1.6, 2.4 + Exif:MeteringMode: 5 (pattern) + Exif:OffsetTime: "+02:00" + Exif:OffsetTimeDigitized: "+02:00" + Exif:OffsetTimeOriginal: "+02:00" + Exif:PhotographicSensitivity: 320 + Exif:PixelXDimension: 4032 + Exif:PixelYDimension: 3024 + Exif:SensingMethod: 2 (1-chip color area) + Exif:ShutterSpeedValue: 6.20983 (1/74 s) + Exif:SubsecTimeDigitized: "886" + Exif:SubsecTimeOriginal: "886" + Exif:WhiteBalance: 0 (auto) + GPS:Altitude: 3.24105 (3.24105 m) + GPS:AltitudeRef: 0 (above sea level) + GPS:DateStamp: "2023:09:28" + GPS:DestBearing: 90.2729 + GPS:DestBearingRef: "T" (true north) + GPS:HPositioningError: 5.1893 + GPS:ImgDirection: 90.2729 + GPS:ImgDirectionRef: "T" (true north) + GPS:Latitude: 41, 50, 58.43 + GPS:LatitudeRef: "N" + GPS:Longitude: 3, 7, 31.98 + GPS:LongitudeRef: "E" + GPS:Speed: 0.171966 + GPS:SpeedRef: "K" (km/hour) + oiio:ColorSpace: "sRGB" + oiio:OriginalOrientation: 6 +Reading ../oiio-images/heif/sewing-threads.heic +../oiio-images/heif/sewing-threads.heic : 4000 x 3000, 3 channel, uint8 heif + SHA-1: 6A061BFE2F0BAC4CC94F5D9D5A6E674634149813 + channel list: R, G, B + DateTime: "2023:12:12 18:39:16" + ExposureTime: 0.04 + FNumber: 1.8 + Make: "samsung" + Model: "SM-A326B" + Orientation: 1 (normal) + ResolutionUnit: 2 (inches) + Software: "A326BXXS8CWK2" + XResolution: 72 + YResolution: 72 + Exif:ApertureValue: 1.69 (f/1.8) + Exif:BrightnessValue: 1.19 + Exif:ColorSpace: 1 + Exif:DateTimeDigitized: "2023:12:12 18:39:16" + Exif:DateTimeOriginal: "2023:12:12 18:39:16" + Exif:DigitalZoomRatio: 1 + Exif:ExifVersion: "0220" + Exif:ExposureBiasValue: 0 + Exif:ExposureMode: 0 (auto) + Exif:ExposureProgram: 2 (normal program) + Exif:Flash: 0 (no flash) + Exif:FocalLength: 4.6 (4.6 mm) + Exif:FocalLengthIn35mmFilm: 25 + Exif:MaxApertureValue: 1.69 (f/1.8) + Exif:MeteringMode: 2 (center-weighted average) + Exif:OffsetTime: "+01:00" + Exif:OffsetTimeOriginal: "+01:00" + Exif:PhotographicSensitivity: 500 + Exif:PixelXDimension: 4000 + Exif:PixelYDimension: 3000 + Exif:SceneCaptureType: 0 (standard) + Exif:ShutterSpeedValue: 0.04 (1/1 s) + Exif:SubsecTime: "576" + Exif:SubsecTimeDigitized: "576" + Exif:SubsecTimeOriginal: "576" + Exif:WhiteBalance: 0 (auto) + Exif:YCbCrPositioning: 1 + GPS:Altitude: 292 (292 m) + GPS:AltitudeRef: 0 (above sea level) + GPS:Latitude: 41, 43, 33.821 + GPS:LatitudeRef: "N" + GPS:Longitude: 1, 49, 34.0187 + GPS:LongitudeRef: "E" + oiio:ColorSpace: "sRGB" diff --git a/testsuite/heif/run.py b/testsuite/heif/run.py index 75989664cc..a220e3dc35 100755 --- a/testsuite/heif/run.py +++ b/testsuite/heif/run.py @@ -9,5 +9,9 @@ for f in files: command = command + info_command (os.path.join(imagedir, f)) +files = [ "greyhounds-looking-for-a-table.heic", "sewing-threads.heic" ] +for f in files: + command = command + info_command (os.path.join(OIIO_TESTSUITE_IMAGEDIR, f)) + # avif conversion is expected to fail if libheif is built without AV1 support failureok = 1