Added Property OrientationCorrection which can control if the image should be rotated
to it's Orientation as defined by exif data.
Provided for JPEG images containing the exif data for Orientation.
Limitations:
The image provided will be cached, the orientation of the first cached image will be
used for subsequent images until the cache image is released.
Change-Id: I7627839c143c06dfde63a32eb8171e2205bf18af
FittingMode::SCALE_TO_FILL,
SamplingMode::BOX_THEN_LINEAR,
TextureManager::NO_ATLAS,
- &observer );
+ &observer,
+ true );
const VisualUrl& url = textureManager.GetVisualUrl( textureId );
const char* TEST_INVALID_FILE_NAME = TEST_RESOURCE_DIR "/invalid.jpg";
const char* TEST_REMOTE_INVALID_FILE_NAME = "https://www.tizen.org/invalid.png";
const char* TEST_MASK_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/mask.png";
+const char* TEST_ROTATED_IMAGE = TEST_RESOURCE_DIR "/keyboard-Landscape.jpg";
bool gResourceReadySignalFired = false;
END_TEST;
}
+
+int UtcDaliImageVisualOrientationCorrection(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "UtcDaliImageVisualOrientationCorrection Enabling OrientationCorrection should rotate an image with exif (90deg) orientation data with requested" );
+
+ VisualFactory factory = VisualFactory::Get();
+ tet_infoline( "Create visual with Orientation correction set OFF" );
+ Property::Map propertyMap;
+ propertyMap.Insert( Visual::Property::TYPE, Visual::IMAGE );
+ propertyMap.Insert( ImageVisual::Property::URL, TEST_ROTATED_IMAGE );
+ propertyMap.Insert( DevelImageVisual::Property::ORIENTATION_CORRECTION, false );
+ Visual::Base imageVisual = factory.CreateVisual( propertyMap );
+
+ tet_infoline( "Create control for visual, need to loaded it" );
+ DummyControl actor = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+ Stage::GetCurrent().Add( actor );
+
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual );
+ // Wait for image to load
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+ Vector2 originalImageSize;
+ tet_infoline( "Get size of original visual to compare later with rotated image" );
+ imageVisual.GetNaturalSize( originalImageSize );
+ DALI_TEST_GREATER( originalImageSize.width, originalImageSize.height, TEST_LOCATION ); // Width and Height must be different for this test.
+ imageVisual.Reset(); // remove handle so can unregister it and remove from cache
+ dummyImpl.UnregisterVisual( DummyControl::Property::TEST_VISUAL );
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Create visual with Orientation correction set ON " );
+ propertyMap.Clear();
+ propertyMap.Insert( Visual::Property::TYPE, Visual::IMAGE );
+ propertyMap.Insert( ImageVisual::Property::URL, TEST_ROTATED_IMAGE );
+ propertyMap.Insert( DevelImageVisual::Property::ORIENTATION_CORRECTION, true );
+ imageVisual = factory.CreateVisual( propertyMap );
+
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual );
+ // Wait for image to load
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+ Vector2 rotatedImageSize;
+ imageVisual.GetNaturalSize( rotatedImageSize );
+ tet_infoline( "Confirm that visual has rotated" );
+ DALI_TEST_EQUALS( originalImageSize.width, rotatedImageSize.height , TEST_LOCATION );
+ DALI_TEST_EQUALS( originalImageSize.height, rotatedImageSize.width , TEST_LOCATION );
+
+ Property::Map resultMap;
+ imageVisual.CreatePropertyMap( resultMap );
+
+ // check the Property::ORIENTATION_CORRECTION value from the returned map
+ Property::Value* typeValue = resultMap.Find( DevelImageVisual::Property::ORIENTATION_CORRECTION, Property::BOOLEAN );
+ DALI_TEST_EQUALS( typeValue->Get<bool>(), true, TEST_LOCATION );
+
+ END_TEST;
+}
* @see ReleasePolicy::Type
*/
RELEASE_POLICY = CROP_TO_MASK + 2,
+
+ /**
+ * @brief Determines if image orientation should be corrected so the image displays as it was intended.
+ * @details Name "orientationCorrection", Type Property::BOOLEAN, if true the image's orientation will be corrected.
+ * @note Default true
+ */
+ ORIENTATION_CORRECTION = CROP_TO_MASK + 3,
};
} //namespace Property
namespace Internal
{
+namespace
+{
+const bool ENABLE_ORIENTATION_CORRECTION( true );
+} // namespace
+
FixedImageCache::FixedImageCache(
TextureManager& textureManager, UrlList& urlList, ImageCache::FrameReadyObserver& observer,
unsigned int batchSize )
mImageUrls[ mUrlIndex ].mTextureId =
mTextureManager.RequestLoad( url, ImageDimensions(), FittingMode::SCALE_TO_FILL,
SamplingMode::BOX_THEN_LINEAR, TextureManager::NO_ATLAS,
- this );
+ this, ENABLE_ORIENTATION_CORRECTION );
mRequestingLoad = false;
++mUrlIndex;
}
#else
#define LOG_CACHE
#endif
+
+const bool ENABLE_ORIENTATION_CORRECTION( true );
+
}
namespace Dali
mImageUrls[ imageFrame.mUrlIndex ].mTextureId =
mTextureManager.RequestLoad( url, ImageDimensions(), FittingMode::SCALE_TO_FILL,
SamplingMode::BOX_THEN_LINEAR, TextureManager::NO_ATLAS,
- this );
+ this, ENABLE_ORIENTATION_CORRECTION );
mRequestingLoad = false;
}
mLoadPolicy( DevelImageVisual::LoadPolicy::ATTACHED ),
mReleasePolicy( DevelImageVisual::ReleasePolicy::DESTROYED ),
mAttemptAtlasing( false ),
- mLoading( false )
+ mLoading( false ),
+ mOrientationCorrection( true )
{
}
{
DoSetProperty( Toolkit::DevelImageVisual::Property::RELEASE_POLICY, keyValue.second );
}
+ else if( keyValue.first == ORIENTATION_CORRECTION_NAME )
+ {
+ DoSetProperty( Toolkit::DevelImageVisual::Property::ORIENTATION_CORRECTION, keyValue.second );
+ }
}
}
if ( mLoadPolicy == DevelImageVisual::LoadPolicy::IMMEDIATE )
{
auto attemptAtlasing = mAttemptAtlasing;
- LoadTexture( attemptAtlasing, mAtlasRect, mTextures );
+ LoadTexture( attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection );
}
}
int loadPolicy;
Scripting::GetEnumerationProperty( value, LOAD_POLICY_TABLE, LOAD_POLICY_TABLE_COUNT, loadPolicy );
mLoadPolicy = DevelImageVisual::LoadPolicy::Type( loadPolicy );
+ break;
+ }
+ case Toolkit::DevelImageVisual::Property::ORIENTATION_CORRECTION:
+ {
+ bool orientationCorrection( mOrientationCorrection );
+ if( value.Get( orientationCorrection ) )
+ {
+ mOrientationCorrection = orientationCorrection;
+ }
+ break;
}
}
}
return mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
}
-void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& textures )
+void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection )
{
TextureManager& textureManager = mFactoryCache.GetTextureManager();
textures = textureManager.LoadTexture( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode,
mMaskingData, IsSynchronousResourceLoading(), mTextureId,
atlasRect, atlasing, mLoading, mWrapModeU,
- mWrapModeV, textureObserver, atlasUploadObserver, atlasManager );
+ mWrapModeV, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection );
}
void ImageVisual::InitializeRenderer()
if( mTextureId == TextureManager::INVALID_TEXTURE_ID && ! mTextures ) // Only load the texture once
{
- LoadTexture( attemptAtlasing, mAtlasRect, mTextures );
+ LoadTexture( attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection );
}
if( attemptAtlasing ) // Flag needs to be set before creating renderer
map.Insert( Toolkit::DevelImageVisual::Property::LOAD_POLICY, mLoadPolicy );
map.Insert( Toolkit::DevelImageVisual::Property::RELEASE_POLICY, mReleasePolicy );
-
+ map.Insert( Toolkit::DevelImageVisual::Property::ORIENTATION_CORRECTION, mOrientationCorrection );
}
void ImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
*
* The following properties are optional
*
- * | %Property Name | Type |
- * |--------------------|-------------------|
- * | url | STRING |
- * | alphaMaskUrl | STRING |
- * | fittingMode | INTEGER OR STRING |
- * | samplingMode | INTEGER OR STRING |
- * | desiredWidth | INTEGER |
- * | desiredHeight | INTEGER |
- * | synchronousLoading | BOOLEAN |
- * | pixelArea | VECTOR4 |
- * | wrapModeU | INTEGER OR STRING |
- * | wrapModeV | INTEGER OR STRING |
- * | loadPolicy | INTEGER OR STRING |
- * | releasePolicy | INTEGER OR STRING |
+ * | %Property Name | Type |
+ * |-----------------------|-------------------|
+ * | url | STRING |
+ * | alphaMaskUrl | STRING |
+ * | fittingMode | INTEGER OR STRING |
+ * | samplingMode | INTEGER OR STRING |
+ * | desiredWidth | INTEGER |
+ * | desiredHeight | INTEGER |
+ * | synchronousLoading | BOOLEAN |
+ * | pixelArea | VECTOR4 |
+ * | wrapModeU | INTEGER OR STRING |
+ * | wrapModeV | INTEGER OR STRING |
+ * | loadPolicy | INTEGER OR STRING |
+ * | releasePolicy | INTEGER OR STRING |
+ * | orientationCorrection | BOOLEAN |
*
* where pixelArea is a rectangular area.
* In its Vector4 value, the first two elements indicate the top-left position of the area,
* @param[in, out] atlasing flag if the image has been put in a atlas (true), passing false will not atlas even if possible.
* @param[out] atlasRect if atlasing is used this the texture area of the image in the atlas.
* @param[out] textures resulting texture set from the image loading.
+ * @param[in] orientationCorrection flag determines if orientation correction should be performed
*/
- void LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& textures );
+ void LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection );
/**
* @brief Initializes the Dali::Renderer from the image url
Vector4 mAtlasRect;
bool mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture
bool mLoading; ///< True if the texture is still loading.
+ bool mOrientationCorrection; ///< true if the image will have it's orientation corrected.
};
bool synchronousLoading, TextureManager::TextureId& textureId, Vector4& textureRect,
bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU,
Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
- AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager)
+ AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager, bool orientationCorrection )
{
TextureSet textureSet;
PixelData data;
if( url.IsValid() )
{
- Devel::PixelBuffer pixelBuffer = LoadImageFromFile( url.GetUrl(), desiredSize, fittingMode, samplingMode );
+ Devel::PixelBuffer pixelBuffer = LoadImageFromFile( url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection );
if( pixelBuffer )
{
data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
atlasingStatus = false;
if( !maskInfo )
{
- textureId = RequestLoad( url, desiredSize, fittingMode, samplingMode, TextureManager::NO_ATLAS, textureObserver );
+ textureId = RequestLoad( url, desiredSize, fittingMode, samplingMode, TextureManager::NO_ATLAS, textureObserver, orientationCorrection );
}
else
{
fittingMode, samplingMode,
TextureManager::NO_ATLAS,
maskInfo->mCropToMask,
- textureObserver );
+ textureObserver,
+ orientationCorrection);
}
TextureManager::LoadState loadState = GetTextureState( textureId );
FittingMode::Type fittingMode,
Dali::SamplingMode::Type samplingMode,
const UseAtlas useAtlas,
- TextureUploadObserver* observer )
+ TextureUploadObserver* observer,
+ bool orientationCorrection )
{
- return RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas, false, UPLOAD_TO_TEXTURE, observer );
+ return RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas, false, UPLOAD_TO_TEXTURE, observer, orientationCorrection );
}
TextureManager::TextureId TextureManager::RequestLoad(
Dali::SamplingMode::Type samplingMode,
const UseAtlas useAtlas,
bool cropToMask,
- TextureUploadObserver* observer )
+ TextureUploadObserver* observer,
+ bool orientationCorrection )
{
- return RequestLoadInternal( url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas, cropToMask, UPLOAD_TO_TEXTURE, observer );
+ return RequestLoadInternal( url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas, cropToMask, UPLOAD_TO_TEXTURE, observer, orientationCorrection );
}
TextureManager::TextureId TextureManager::RequestMaskLoad( const VisualUrl& maskUrl )
{
// Use the normal load procedure to get the alpha mask.
- return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL );
+ return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL, true );
}
TextureManager::TextureId TextureManager::RequestLoadInternal(
UseAtlas useAtlas,
bool cropToMask,
StorageType storageType,
- TextureUploadObserver* observer )
+ TextureUploadObserver* observer,
+ bool orientationCorrection )
{
// First check if the requested Texture is cached.
const TextureHash textureHash = GenerateHash( url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas, maskTextureId );
textureId = GenerateUniqueTextureId();
mTextureInfoContainer.push_back( TextureInfo( textureId, maskTextureId, url.GetUrl(),
desiredSize, contentScale, fittingMode, samplingMode,
- false, cropToMask, useAtlas, textureHash ) );
+ false, cropToMask, useAtlas, textureHash, orientationCorrection ) );
cacheIndex = mTextureInfoContainer.size() - 1u;
DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex, textureId );
TextureInfo& textureInfo( mTextureInfoContainer[ cacheIndex ] );
textureInfo.maskTextureId = maskTextureId;
textureInfo.storageType = storageType;
+ textureInfo.orientationCorrection = orientationCorrection;
DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureInfo loadState:%s\n",
textureInfo.loadState == TextureManager::NOT_STARTED ? "NOT_STARTED" :
DALI_ASSERT_ALWAYS(loadingHelperIt != loadersContainer.End());
loadingHelperIt->Load(textureInfo.textureId, textureInfo.url,
textureInfo.desiredSize, textureInfo.fittingMode,
- textureInfo.samplingMode, true);
+ textureInfo.samplingMode, textureInfo.orientationCorrection );
}
}
bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU,
Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
AtlasUploadObserver* atlasObserver,
- ImageAtlasManagerPtr imageAtlasManager);
+ ImageAtlasManagerPtr imageAtlasManager,
+ bool orientationCorrection );
/**
* @brief Requests an image load of the given URL.
*
* When the client has finished with the Texture, Remove() should be called.
*
- * @param[in] url The URL of the image to load
- * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
- * @param[in] fittingMode The FittingMode to use
- * @param[in] samplingMode The SamplingMode to use
- * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
- * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
- * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
- * This is called when an image load completes (or fails).
- * @return A TextureId to use as a handle to reference this Texture
+ * @param[in] url The URL of the image to load
+ * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
+ * @param[in] fittingMode The FittingMode to use
+ * @param[in] samplingMode The SamplingMode to use
+ * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
+ * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
+ * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
+ * This is called when an image load completes (or fails).
+ * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
+ * @return A TextureId to use as a handle to reference this Texture
*/
TextureId RequestLoad( const VisualUrl& url,
const ImageDimensions desiredSize,
FittingMode::Type fittingMode,
Dali::SamplingMode::Type samplingMode,
const UseAtlas useAtlasing,
- TextureUploadObserver* observer );
+ TextureUploadObserver* observer,
+ bool orientationCorrection );
/**
* @brief Requests an image load of the given URL, when the texture has
*
* When the client has finished with the Texture, Remove() should be called.
*
- * @param[in] url The URL of the image to load
- * @param[in] maskTextureId The texture id of an image to mask this with (can be INVALID if no masking required)
- * @param[in] contentScale The scale factor to apply to the image before masking
- * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
- * @param[in] fittingMode The FittingMode to use
- * @param[in] samplingMode The SamplingMode to use
- * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
- * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
- * @param[in] cropToMask Only used with masking, this will crop the scaled image to the mask size. If false, then the mask will be scaled to fit the image before being applied.
- * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
- * This is called when an image load completes (or fails).
- * @return A TextureId to use as a handle to reference this Texture
+ * @param[in] url The URL of the image to load
+ * @param[in] maskTextureId The texture id of an image to mask this with (can be INVALID if no masking required)
+ * @param[in] contentScale The scale factor to apply to the image before masking
+ * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
+ * @param[in] fittingMode The FittingMode to use
+ * @param[in] samplingMode The SamplingMode to use
+ * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
+ * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
+ * @param[in] cropToMask Only used with masking, this will crop the scaled image to the mask size. If false, then the mask will be scaled to fit the image before being applied.
+ * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
+ * This is called when an image load completes (or fails).
+ * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
+ * @return A TextureId to use as a handle to reference this Texture
*/
TextureId RequestLoad( const VisualUrl& url,
TextureId maskTextureId,
Dali::SamplingMode::Type samplingMode,
const UseAtlas useAtlasing,
bool cropToMask,
- TextureUploadObserver* observer );
+ TextureUploadObserver* observer,
+ bool orientationCorrection );
/**
* Requests a masking image to be loaded. This mask is not uploaded to GL,
*
* When the client has finished with the Texture, Remove() should be called.
*
- * @param[in] url The URL of the image to load
- * @param[in] maskTextureId The texture id of an image to use as a mask. If no mask is required, then set to INVALID_TEXTURE_ID
- * @param[in] contentScale The scaling factor to apply to the content when masking
- * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
- * @param[in] fittingMode The FittingMode to use
- * @param[in] samplingMode The SamplingMode to use
- * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
- * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
- * @param[in] cropToMask Whether to crop the target after masking, or scale the mask to the image before masking.
- * @param[in] storageType, Whether the pixel data is stored in the cache or uploaded to the GPU
- * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
- * This is called when an image load completes (or fails).
- * @return A TextureId to use as a handle to reference this Texture
+ * @param[in] url The URL of the image to load
+ * @param[in] maskTextureId The texture id of an image to use as a mask. If no mask is required, then set to INVALID_TEXTURE_ID
+ * @param[in] contentScale The scaling factor to apply to the content when masking
+ * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
+ * @param[in] fittingMode The FittingMode to use
+ * @param[in] samplingMode The SamplingMode to use
+ * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
+ * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
+ * @param[in] cropToMask Whether to crop the target after masking, or scale the mask to the image before masking.
+ * @param[in] storageType, Whether the pixel data is stored in the cache or uploaded to the GPU
+ * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
+ * This is called when an image load completes (or fails).
+ * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
+ * @return A TextureId to use as a handle to reference this Texture
*/
TextureId RequestLoadInternal(
const VisualUrl& url,
UseAtlas useAtlas,
bool cropToMask,
StorageType storageType,
- TextureUploadObserver* observer );
+ TextureUploadObserver* observer,
+ bool orientationCorrection );
typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching.
bool loadSynchronously,
bool cropToMask,
UseAtlas useAtlas,
- TextureManager::TextureHash hash )
+ TextureManager::TextureHash hash,
+ bool orientationCorrection )
: url( url ),
desiredSize( desiredSize ),
useSize( desiredSize ),
storageType( UPLOAD_TO_TEXTURE ),
loadSynchronously( loadSynchronously ),
useAtlas( useAtlas ),
- cropToMask( cropToMask )
+ cropToMask( cropToMask ),
+ orientationCorrection( true )
{
}
bool loadSynchronously:1; ///< True if synchronous loading was requested
UseAtlas useAtlas:1; ///< USE_ATLAS if an atlas was requested. This is updated to false if atlas is not used
bool cropToMask:1; ///< true if the image should be cropped to the mask size.
+ bool orientationCorrection:1; ///< true if the image should be rotated to match exif orientation data
};
// Structs:
const char * const CROP_TO_MASK_NAME("cropToMask");
const char * const LOAD_POLICY_NAME("loadPolicy");
const char * const RELEASE_POLICY_NAME("releasePolicy");
+const char * const ORIENTATION_CORRECTION_NAME("orientationCorrection");
// Text visual
const char * const TEXT_PROPERTY( "text" );
extern const char * const CROP_TO_MASK_NAME;
extern const char * const LOAD_POLICY_NAME;
extern const char * const RELEASE_POLICY_NAME;
+extern const char * const ORIENTATION_CORRECTION_NAME;
// Text visual
extern const char * const TEXT_PROPERTY;