From 99c5e3300e611a4519a2e47c502223d440f795e9 Mon Sep 17 00:00:00 2001 From: tscholb Date: Fri, 19 Feb 2021 12:05:33 +0900 Subject: [PATCH] Fix jpeg loader considering rotation 1.Add GetOriginalImageSize() considering rotation 2.Naming modifcation of jpegTransform Change-Id: I4459c44e15a06ca1d585b8493ad569741db5f055 --- dali/devel-api/adaptor-framework/image-loading.cpp | 6 +- dali/devel-api/adaptor-framework/image-loading.h | 7 +- dali/internal/imaging/common/loader-jpeg-turbo.cpp | 93 +++++++++++----------- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/dali/devel-api/adaptor-framework/image-loading.cpp b/dali/devel-api/adaptor-framework/image-loading.cpp index eac5e61..44bcac7 100644 --- a/dali/devel-api/adaptor-framework/image-loading.cpp +++ b/dali/devel-api/adaptor-framework/image-loading.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,9 +65,9 @@ ImageDimensions GetClosestImageSize(const std::string& filename, return dimension; } -ImageDimensions GetOriginalImageSize(const std::string& filename) +ImageDimensions GetOriginalImageSize(const std::string& filename, bool orientationCorrection) { - return TizenPlatform::ImageLoader::GetClosestImageSize(filename, ImageDimensions(0, 0), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true); + return TizenPlatform::ImageLoader::GetClosestImageSize(filename, ImageDimensions(0, 0), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, orientationCorrection); } Devel::PixelBuffer DownloadImageSynchronously(const std::string& url, ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection) diff --git a/dali/devel-api/adaptor-framework/image-loading.h b/dali/devel-api/adaptor-framework/image-loading.h index b00cd28..a66028d 100644 --- a/dali/devel-api/adaptor-framework/image-loading.h +++ b/dali/devel-api/adaptor-framework/image-loading.h @@ -2,7 +2,7 @@ #define DALI_IMAGE_LOADING_H /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,13 +70,14 @@ DALI_ADAPTOR_API ImageDimensions GetClosestImageSize( bool orientationCorrection = true); /** - * @brief Get the size of an original image + * @brief Get the size of an original image. this method will respect any rotation of image. * @param[in] filename name of the image. + * @param[in] orientationCorrection Reorient the image to respect any orientation metadata in its header. * * @return dimensions to original image */ DALI_ADAPTOR_API ImageDimensions GetOriginalImageSize( - const std::string& filename); + const std::string& filename, bool orientationCorrection = true); /** * @brief Load an image synchronously from a remote resource. diff --git a/dali/internal/imaging/common/loader-jpeg-turbo.cpp b/dali/internal/imaging/common/loader-jpeg-turbo.cpp index 901ce7e..ba57d0f 100644 --- a/dali/internal/imaging/common/loader-jpeg-turbo.cpp +++ b/dali/internal/imaging/common/loader-jpeg-turbo.cpp @@ -56,11 +56,11 @@ enum class JpegTransform { NONE, //< no transformation 0th-Row = top & 0th-Column = left FLIP_HORIZONTAL, //< horizontal flip 0th-Row = top & 0th-Column = right - FLIP_VERTICAL, //< vertical flip 0th-Row = bottom & 0th-Column = right - TRANSPOSE, //< transpose across UL-to-LR axis 0th-Row = bottom & 0th-Column = left - TRANSVERSE, //< transpose across UR-to-LL axis 0th-Row = left & 0th-Column = top + ROTATE_180, //< 180-degree rotation 0th-Row = bottom & 0th-Column = right + FLIP_VERTICAL, //< vertical flip 0th-Row = bottom & 0th-Column = left + TRANSPOSE, //< transpose across UL-to-LR axis 0th-Row = left & 0th-Column = top ROTATE_90, //< 90-degree clockwise rotation 0th-Row = right & 0th-Column = top - ROTATE_180, //< 180-degree rotation 0th-Row = right & 0th-Column = bottom + TRANSVERSE, //< transpose across UR-to-LL axis 0th-Row = right & 0th-Column = bottom ROTATE_270, //< 270-degree clockwise (or 90 ccw) 0th-Row = left & 0th-Column = bottom }; @@ -324,7 +324,7 @@ struct PixelType }; template -void FlipVertical(PixelArray buffer, int width, int height) +void Rotate180(PixelArray buffer, int width, int height) { // Destination pixel, set as the first pixel of screen auto to = reinterpret_cast*>(buffer); @@ -356,7 +356,7 @@ void FlipHorizontal(PixelArray buffer, int width, int height) } template -void Transpose(PixelArray buffer, int width, int height) +void FlipVertical(PixelArray buffer, int width, int height) { //Transform vertically only for(auto iy = 0; iy < height / 2; ++iy) @@ -371,7 +371,7 @@ void Transpose(PixelArray buffer, int width, int height) } template -void Transverse(PixelArray buffer, int width, int height) +void Transpose(PixelArray buffer, int width, int height) { using PixelT = PixelType; Vector data; @@ -422,7 +422,7 @@ void Rotate90(PixelArray buffer, int width, int height) } template -void Rotate180(PixelArray buffer, int width, int height) +void Transverse(PixelArray buffer, int width, int height) { using PixelT = PixelType; Vector data; @@ -920,17 +920,17 @@ JpegTransform ConvertExifOrientation(ExifData* exifData) } case 3: { - transform = JpegTransform::FLIP_VERTICAL; + transform = JpegTransform::ROTATE_180; break; } case 4: { - transform = JpegTransform::TRANSPOSE; + transform = JpegTransform::FLIP_VERTICAL; break; } case 5: { - transform = JpegTransform::TRANSVERSE; + transform = JpegTransform::TRANSPOSE; break; } case 6: @@ -940,7 +940,7 @@ JpegTransform ConvertExifOrientation(ExifData* exifData) } case 7: { - transform = JpegTransform::ROTATE_180; + transform = JpegTransform::TRANSVERSE; break; } case 8: @@ -962,8 +962,7 @@ JpegTransform ConvertExifOrientation(ExifData* exifData) bool TransformSize(int requiredWidth, int requiredHeight, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, JpegTransform transform, int& preXformImageWidth, int& preXformImageHeight, int& postXformImageWidth, int& postXformImageHeight) { bool success = true; - - if(transform == JpegTransform::ROTATE_90 || transform == JpegTransform::ROTATE_270 || transform == JpegTransform::ROTATE_180 || transform == JpegTransform::TRANSVERSE) + if(transform == JpegTransform::TRANSPOSE || transform == JpegTransform::ROTATE_90 || transform == JpegTransform::TRANSVERSE || transform == JpegTransform::ROTATE_270) { std::swap(requiredWidth, requiredHeight); std::swap(postXformImageWidth, postXformImageHeight); @@ -1110,47 +1109,49 @@ bool LoadJpegHeader(const Dali::ImageLoader::Input& input, unsigned int& width, FILE* const fp = input.file; bool success = false; - if(requiredWidth == 0 && requiredHeight == 0) - { - success = LoadJpegHeader(fp, width, height); - } - else + + unsigned int headerWidth; + unsigned int headerHeight; + + success = LoadJpegHeader(fp, headerWidth, headerHeight); + if(success) { - // Double check we get the same width/height from the header - unsigned int headerWidth; - unsigned int headerHeight; - if(LoadJpegHeader(fp, headerWidth, headerHeight)) - { - auto transform = JpegTransform::NONE; + auto transform = JpegTransform::NONE; - if(input.reorientationRequested) + if(input.reorientationRequested) + { + auto exifData = LoadExifData(fp); + if(exifData) { - auto exifData = LoadExifData(fp); - if(exifData) - { - transform = ConvertExifOrientation(exifData.get()); - } - - int preXformImageWidth = headerWidth; - int preXformImageHeight = headerHeight; - int postXformImageWidth = headerWidth; - int postXformImageHeight = headerHeight; + transform = ConvertExifOrientation(exifData.get()); + } + } - success = TransformSize(requiredWidth, requiredHeight, input.scalingParameters.scalingMode, input.scalingParameters.samplingMode, transform, preXformImageWidth, preXformImageHeight, postXformImageWidth, postXformImageHeight); - if(success) - { - width = postXformImageWidth; - height = postXformImageHeight; - } + if(requiredWidth == 0 && requiredHeight == 0) + { + if(transform == JpegTransform::TRANSPOSE || transform == JpegTransform::ROTATE_90 || transform == JpegTransform::TRANSVERSE || transform == JpegTransform::ROTATE_270) + { + std::swap(headerWidth, headerHeight); } - else + } + else + { + int preXformImageWidth = headerWidth; + int preXformImageHeight = headerHeight; + int postXformImageWidth = headerWidth; + int postXformImageHeight = headerHeight; + + success = TransformSize(requiredWidth, requiredHeight, input.scalingParameters.scalingMode, input.scalingParameters.samplingMode, transform, preXformImageWidth, preXformImageHeight, postXformImageWidth, postXformImageHeight); + if(success) { - success = true; - width = headerWidth; - height = headerHeight; + headerWidth = postXformImageWidth; + headerHeight = postXformImageHeight; } } + width = headerWidth; + height = headerHeight; } + return success; } -- 2.7.4