From 8d61b6699d9f2466af87a35a894fb626fd5bf455 Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Thu, 27 Sep 2018 13:25:57 +0100 Subject: [PATCH] [4.0] PixelBuffer::Rotate() amendments. * The Rotate() method returns true if success. * Checks memory allocations to avoid issues with static code analyzers. * Some amendments in doxygen doc. Change-Id: Iefc3b2a2a484aa720e7bcd1447d7d79ac201784d Signed-off-by: Victor Cebollada --- adaptors/common/pixel-buffer-impl.cpp | 29 +++++++++------- adaptors/common/pixel-buffer-impl.h | 2 +- .../devel-api/adaptor-framework/pixel-buffer.cpp | 4 +-- .../devel-api/adaptor-framework/pixel-buffer.h | 8 +++-- .../portable/image-operations.cpp | 40 ++++++++-------------- platform-abstractions/portable/image-operations.h | 5 +++ 6 files changed, 44 insertions(+), 44 deletions(-) diff --git a/adaptors/common/pixel-buffer-impl.cpp b/adaptors/common/pixel-buffer-impl.cpp index fbf72a1..84b5c9d 100644 --- a/adaptors/common/pixel-buffer-impl.cpp +++ b/adaptors/common/pixel-buffer-impl.cpp @@ -216,7 +216,7 @@ void PixelBuffer::AllocateFixedSize( uint32_t size ) mBufferSize = size; } -void PixelBuffer::Rotate( Degree angle ) +bool PixelBuffer::Rotate( Degree angle ) { // Check first if Rotate() can perform the operation in the current pixel buffer. @@ -247,7 +247,7 @@ void PixelBuffer::Rotate( Degree angle ) { // Can't rotate the pixel buffer with the current pixel format. DALI_LOG_ERROR( "Can't rotate the pixel buffer with the current pixel format\n" ); - return; + return false; } float radians = Radian( angle ).radian; @@ -259,7 +259,7 @@ void PixelBuffer::Rotate( Degree angle ) if( radians < Dali::Math::MACHINE_EPSILON_10 ) { // Nothing to do if the angle is zero. - return; + return true; } const unsigned int pixelSize = Pixel::GetBytesPerPixel( mPixelFormat ); @@ -274,13 +274,21 @@ void PixelBuffer::Rotate( Degree angle ) mWidth, mHeight ); - // Release the memory of the current pixel buffer. - ReleaseBuffer(); + // Check whether the rotation succedded and set the new pixel buffer data. + const bool success = nullptr != pixelsOut; - // Set the new pixel buffer. - mBuffer = pixelsOut; - pixelsOut = nullptr; - mBufferSize = mWidth * mHeight * pixelSize; + if( success ) + { + // Release the memory of the current pixel buffer. + ReleaseBuffer(); + + // Set the new pixel buffer. + mBuffer = pixelsOut; + pixelsOut = nullptr; + mBufferSize = mWidth * mHeight * pixelSize; + } + + return success; } void PixelBuffer::ScaleAndCrop( float scaleFactor, ImageDimensions cropDimensions ) @@ -456,9 +464,6 @@ void PixelBuffer::MultiplyColorByAlpha() } } - - - }// namespace Adaptor }// namespace Internal }// namespace Dali diff --git a/adaptors/common/pixel-buffer-impl.h b/adaptors/common/pixel-buffer-impl.h index b8ad251..e8eb98e 100644 --- a/adaptors/common/pixel-buffer-impl.h +++ b/adaptors/common/pixel-buffer-impl.h @@ -215,7 +215,7 @@ public: /** * @copydoc Devel::PixelBuffer::Rotate() */ - void Rotate( Degree angle ); + bool Rotate( Degree angle ); private: /* diff --git a/adaptors/devel-api/adaptor-framework/pixel-buffer.cpp b/adaptors/devel-api/adaptor-framework/pixel-buffer.cpp index 3e01857..c448c0e 100644 --- a/adaptors/devel-api/adaptor-framework/pixel-buffer.cpp +++ b/adaptors/devel-api/adaptor-framework/pixel-buffer.cpp @@ -126,9 +126,9 @@ bool PixelBuffer::GetMetadata( Property::Map& metadata ) const return GetImplementation(*this).GetMetadata(metadata); } -void PixelBuffer::Rotate( Degree angle ) +bool PixelBuffer::Rotate( Degree angle ) { - GetImplementation(*this).Rotate( angle ); + return GetImplementation(*this).Rotate( angle ); } } // namespace Devel diff --git a/adaptors/devel-api/adaptor-framework/pixel-buffer.h b/adaptors/devel-api/adaptor-framework/pixel-buffer.h index b59214a..50b364d 100644 --- a/adaptors/devel-api/adaptor-framework/pixel-buffer.h +++ b/adaptors/devel-api/adaptor-framework/pixel-buffer.h @@ -2,7 +2,7 @@ #define DALI_PIXEL_BUFFER_H /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 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. @@ -218,13 +218,15 @@ public: /** * @brief Rotates the pixel buffer by the given angle. * - * @note Operation valid for pixel formats: A8, L8, LA88, RGB888, RGB8888, BGR8888, RGBA8888 and BGRA8888. Does nothing otherwise. + * @note Operation valid for pixel formats: A8, L8, LA88, RGB888, RGB8888, BGR8888, RGBA8888 and BGRA8888. Fails otherwise. * @note The operation does nothing for angles equivalent to 0 degrees: -360, 360, 720, etc. * @note If the pixel buffer does rotate, all the pointers to the internal pixel buffer retrieved by the method GetPixelBuffer() become invalid. * * @param[in] angle The angle in degrees. + * + * @return @e false if the rotation fails (invalid pixel format or memory issues). */ - void Rotate( Degree angle ); + bool Rotate( Degree angle ); public: diff --git a/platform-abstractions/portable/image-operations.cpp b/platform-abstractions/portable/image-operations.cpp index fdf20c1..a54eae0 100644 --- a/platform-abstractions/portable/image-operations.cpp +++ b/platform-abstractions/portable/image-operations.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -2235,8 +2236,8 @@ void RotateByShear( const uint8_t* const pixelsIn, return; } - const uint8_t* const firstHorizontalSkwePixelsIn = fastRotationPerformed ? pixelsOut : pixelsIn; - uint8_t* tmpFirstHorizontalSkwePixelsIn = fastRotationPerformed ? pixelsOut : nullptr; // keep the pointer to free the memory. + const uint8_t* const firstHorizontalSkewPixelsIn = fastRotationPerformed ? pixelsOut : pixelsIn; + std::unique_ptr tmpPixelsInPtr( ( fastRotationPerformed ? pixelsOut : nullptr ), free ); // Reset the input/output widthIn = widthOut; @@ -2261,12 +2262,10 @@ void RotateByShear( const uint8_t* const pixelsIn, if( nullptr == pixelsOut ) { - // Free the memory allocated by the 'Fast Rotations'. - free( tmpFirstHorizontalSkwePixelsIn ); - widthOut = 0u; heightOut = 0u; + // The deleter of the tmpPixelsInPtr unique pointer is called freeing the memory allocated by the 'Fast rotations'. // Nothing else to do if the memory allocation fails. return; } @@ -2276,13 +2275,11 @@ void RotateByShear( const uint8_t* const pixelsIn, const float shear = angleTangent * ( ( angleTangent >= 0.f ) ? ( 0.5f + static_cast( y ) ) : ( 0.5f + static_cast( y ) - static_cast( heightOut ) ) ); const int intShear = static_cast( floor( shear ) ); - HorizontalSkew( firstHorizontalSkwePixelsIn, widthIn, pixelSize, pixelsOut, widthOut, y, intShear, shear - static_cast( intShear ) ); + HorizontalSkew( firstHorizontalSkewPixelsIn, widthIn, pixelSize, pixelsOut, widthOut, y, intShear, shear - static_cast( intShear ) ); } - // Free the memory allocated by the 'Fast Rotations'. - free( tmpFirstHorizontalSkwePixelsIn ); - - uint8_t* tmpPixelsIn = pixelsOut; + // Reset the 'pixel in' pointer with the output of the 'First Horizontal Skew' and free the memory allocated by the 'Fast Rotations'. + tmpPixelsInPtr.reset( pixelsOut ); unsigned int tmpWidthIn = widthOut; unsigned int tmpHeightIn = heightOut; @@ -2301,12 +2298,10 @@ void RotateByShear( const uint8_t* const pixelsIn, if( nullptr == pixelsOut ) { - // Free the memory allocated by the 'First Horizontal Skew'. - free( tmpPixelsIn ); - widthOut = 0u; heightOut = 0u; + // The deleter of the tmpPixelsInPtr unique pointer is called freeing the memory allocated by the 'First Horizontal Skew'. // Nothing else to do if the memory allocation fails. return; } @@ -2318,14 +2313,11 @@ void RotateByShear( const uint8_t* const pixelsIn, for( column = 0u; column < widthOut; ++column, offset -= angleSinus ) { const int shear = static_cast( floor( offset ) ); - VerticalSkew( tmpPixelsIn, tmpWidthIn, tmpHeightIn, pixelSize, pixelsOut, widthOut, heightOut, column, shear, offset - static_cast( shear ) ); + VerticalSkew( tmpPixelsInPtr.get(), tmpWidthIn, tmpHeightIn, pixelSize, pixelsOut, widthOut, heightOut, column, shear, offset - static_cast( shear ) ); } - - // Free the memory allocated by the 'First Horizontal Skew'. - free( tmpPixelsIn ); - + // Reset the 'pixel in' pointer with the output of the 'Vertical Skew' and free the memory allocated by the 'First Horizontal Skew'. // Reset the input/output - tmpPixelsIn = pixelsOut; + tmpPixelsInPtr.reset( pixelsOut ); tmpWidthIn = widthOut; tmpHeightIn = heightOut; pixelsOut = nullptr; @@ -2342,12 +2334,10 @@ void RotateByShear( const uint8_t* const pixelsIn, if( nullptr == pixelsOut ) { - // Free the memory allocated by the 'Vertical Skew'. - free( tmpPixelsIn ); - widthOut = 0u; heightOut = 0u; + // The deleter of the tmpPixelsInPtr unique pointer is called freeing the memory allocated by the 'Vertical Skew'. // Nothing else to do if the memory allocation fails. return; } @@ -2357,12 +2347,10 @@ void RotateByShear( const uint8_t* const pixelsIn, for( unsigned int y = 0u; y < heightOut; ++y, offset += angleTangent ) { const int shear = static_cast( floor( offset ) ); - HorizontalSkew( tmpPixelsIn, tmpWidthIn, pixelSize, pixelsOut, widthOut, y, shear, offset - static_cast( shear ) ); + HorizontalSkew( tmpPixelsInPtr.get(), tmpWidthIn, pixelSize, pixelsOut, widthOut, y, shear, offset - static_cast( shear ) ); } - // Free the memory allocated by the 'Vertical Skew'. - free( tmpPixelsIn ); - + // The deleter of the tmpPixelsInPtr unique pointer is called freeing the memory allocated by the 'Vertical Skew'. // @note Allocated memory by the last 'Horizontal Skew' has to be freed by the caller to this function. } diff --git a/platform-abstractions/portable/image-operations.h b/platform-abstractions/portable/image-operations.h index b83cca1..540b9e0 100644 --- a/platform-abstractions/portable/image-operations.h +++ b/platform-abstractions/portable/image-operations.h @@ -390,6 +390,11 @@ void Resample( const unsigned char * __restrict__ inPixels, /** * @brief Rotates the input image with an implementation of the 'Rotate by Shear' algorithm. * + * @pre @p pixelsIn must not alias @p pixelsOut. The input image should be a totally + * separate buffer from the output buffer. + * + * @note This function allocates memory in @p pixelsOut which has to be released by calling @e free() + * * @param[in] pixelsIn The input buffer. * @param[in] widthIn The width of the input buffer. * @param[in] heightIn The height of the input buffer. -- 2.7.4