The point is to clean up the API and bury ImageAttributes.
A later patch will rewrite internals not to use it at all.
Change-Id: I58c738101c61ab1dc2c7b25894c933006aa9da50
Signed-off-by: Andrew Cox <andrew.cox@partner.samsung.com>
#include <dali/internal/event/common/thread-local-storage.h>
#include <dali/internal/event/images/image-factory.h>
#include <dali/internal/event/resources/resource-ticket.h>
+#include <dali/internal/common/image-attributes.h>
using namespace Dali;
using Internal::ResourceTicketPtr;
using Internal::ImageFactory;
using Internal::ImageFactoryCache::RequestPtr;
-
+using Internal::ImageAttributes;
namespace
{
#include <test-native-image.h>
// Internal headers are allowed here
-
+#include <dali/public-api/shader-effects/shader-effect.h>
#include <dali/internal/event/common/thread-local-storage.h>
#include <dali/internal/update/resources/bitmap-metadata.h>
#include <dali/internal/update/resources/resource-manager.h>
#include <dali/internal/render/gl-resources/texture-declarations.h>
#include <dali/internal/render/shaders/shader.h>
#include <dali/internal/common/owner-pointer.h>
-#include <dali/public-api/shader-effects/shader-effect.h>
-
+#include <dali/internal/common/image-attributes.h>
using namespace Dali;
+
#include <mesh-builder.h>
namespace
Internal::ImagePtr LoadImage(TestApplication& application, char* name)
{
- Internal::ResourceImagePtr image = Internal::ResourceImage::New( name, Dali::ImageAttributes::DEFAULT_ATTRIBUTES );
+ Internal::ResourceImagePtr image = Internal::ResourceImage::New( name, Internal::ImageAttributes::DEFAULT_ATTRIBUTES );
application.SendNotification(); // Flush update messages
application.Render(); // Process resource request
Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
Internal::ResourceTicketPtr CheckLoadBitmap(TestApplication& application, const char* name, int w, int h)
{
Internal::ResourceClient& resourceClient = Internal::ThreadLocalStorage::Get().GetResourceClient();
- ImageAttributes attr;
- Integration::BitmapResourceType bitmapRequest(attr);
+ Integration::BitmapResourceType bitmapRequest;
Internal::ResourceTicketPtr ticket = resourceClient.RequestResource( bitmapRequest, name );
ticket->AddObserver(testTicketObserver);
application.SendNotification(); // Flush update messages
tet_infoline("Testing bitmap requests");
Internal::ResourceManager& resourceManager = Internal::ThreadLocalStorage::Get().GetResourceManager();
- ImageAttributes attr;
- Integration::BitmapResourceType bitmapRequest (attr);
+ Integration::BitmapResourceType bitmapRequest;
Internal::ResourceId id(0);
testTicketObserver.Reset();
tet_infoline("Testing bitmap request ticket discard before load complete");
Internal::ResourceManager& resourceManager = Internal::ThreadLocalStorage::Get().GetResourceManager();
- ImageAttributes attr;
- Integration::BitmapResourceType bitmapRequest (attr);
+ Integration::BitmapResourceType bitmapRequest;
Internal::ResourceId id(0);
testTicketObserver.Reset();
tet_infoline("Load bitmap that doesn't exist, followed by ticket discard. Expect LoadingFailed");
Internal::ResourceManager& resourceManager = Internal::ThreadLocalStorage::Get().GetResourceManager();
- ImageAttributes attr;
- Integration::BitmapResourceType bitmapRequest (attr);
+ Integration::BitmapResourceType bitmapRequest;
Internal::ResourceId id(0);
testTicketObserver.Reset();
tet_infoline("Testing bitmap reload during first load");
Internal::ResourceManager& resourceManager = Internal::ThreadLocalStorage::Get().GetResourceManager();
- ImageAttributes attr;
- Integration::BitmapResourceType bitmapRequest (attr);
+ Integration::BitmapResourceType bitmapRequest;
Internal::ResourceId id(0);
testTicketObserver.Reset();
tet_infoline("Testing bitmap reload at end of first load");
Internal::ResourceManager& resourceManager = Internal::ThreadLocalStorage::Get().GetResourceManager();
- ImageAttributes attr;
- Integration::BitmapResourceType bitmapRequest (attr);
+ Integration::BitmapResourceType bitmapRequest;
Internal::ResourceId id(0);
testTicketObserver.Reset();
utc-Dali-HoverProcessing.cpp
utc-Dali-Image.cpp
utc-Dali-ImageActor.cpp
- utc-Dali-ImageAttributes.cpp
utc-Dali-KeyEvent.cpp
utc-Dali-Layer.cpp
utc-Dali-LocklessBuffer.cpp
#include "test-render-controller.h"
#include <dali/public-api/common/dali-common.h>
#include <dali/integration-api/resource-policies.h>
+#include <dali/integration-api/debug.h>
namespace Dali
{
void Initialize();
virtual ~TestApplication();
- static void LogMessage(Dali::Integration::Log::DebugPriority level, std::string& message);
+ static void LogMessage( Dali::Integration::Log::DebugPriority level, std::string& message );
Dali::Integration::Core& GetCore();
TestPlatformAbstraction& GetPlatform();
TestRenderController& GetRenderController();
mTrace.PushCall("Resume", "");
}
-void TestPlatformAbstraction::GetClosestImageSize( const std::string& filename,
- const ImageAttributes& attributes,
- Vector2& closestSize)
+ImageDimensions TestPlatformAbstraction::GetClosestImageSize( const std::string& filename,
+ ImageDimensions size,
+ FittingMode::Type fittingMode,
+ SamplingMode::Type samplingMode,
+ bool orientationCorrection )
{
- closestSize = mClosestSize;
+ ImageDimensions closestSize = ImageDimensions( mClosestSize.x, mClosestSize.y );
mTrace.PushCall("GetClosestImageSize", "");
+ return closestSize;
}
-void TestPlatformAbstraction::GetClosestImageSize( Integration::ResourcePointer resourceBuffer,
- const ImageAttributes& attributes,
- Vector2& closestSize)
+ImageDimensions TestPlatformAbstraction::GetClosestImageSize( Integration::ResourcePointer resourceBuffer,
+ ImageDimensions size,
+ FittingMode::Type fittingMode,
+ SamplingMode::Type samplingMode,
+ bool orientationCorrection )
{
- closestSize = mClosestSize;
+ ImageDimensions closestSize = ImageDimensions( mClosestSize.x, mClosestSize.y );
mTrace.PushCall("GetClosestImageSize", "");
+ return closestSize;
}
*/
virtual void Resume();
- virtual void GetClosestImageSize( const std::string& filename,
- const ImageAttributes& attributes,
- Vector2& closestSize);
-
- virtual void GetClosestImageSize( Integration::ResourcePointer resourceBuffer,
- const ImageAttributes& attributes,
- Vector2& closestSize);
+ virtual ImageDimensions GetClosestImageSize( const std::string& filename,
+ ImageDimensions size,
+ FittingMode::Type fittingMode,
+ SamplingMode::Type samplingMode,
+ bool orientationCorrection );
+
+ virtual ImageDimensions GetClosestImageSize( Integration::ResourcePointer resourceBuffer,
+ ImageDimensions size,
+ FittingMode::Type fittingMode,
+ SamplingMode::Type samplingMode,
+ bool orientationCorrection );
/**
* @copydoc PlatformAbstraction::LoadResource()
#include <algorithm>
#include <stdlib.h>
#include <dali/public-api/dali-core.h>
+#include <dali/integration-api/bitmap.h>
#include <dali-test-suite-utils.h>
#include <test-native-image.h>
{
TestApplication application;
- tet_infoline("UtcDaliEncodedBufferImageNew01() - EncodedBufferImage::New( const uint8_t * const encodedImage, const std::size_t encodedImageByteCount, const ImageAttributes& attributes, const ReleasePolicy releasePol )");
+ tet_infoline( "UtcDaliEncodedBufferImageNew01() - EncodedBufferImage::New( const uint8_t * const encodedImage, const std::size_t encodedImageByteCount, ImageDimensions size, FittingMode::Type scalingMode, SamplingMode::Type samplingMode, ReleasePolicy releasePol, bool orientationCorrection )" );
// Invoke default handle constructor for the Image base class:
Image image;
DALI_TEST_CHECK( !image );
// Trigger image decode to initialise the handle
- Dali::ImageAttributes imageAttributes;
- imageAttributes.SetSize( 720, 1280 );
- imageAttributes.SetScalingMode( Dali::ImageAttributes::FitHeight );
- image = EncodedBufferImage::New( sEncodedBufferImageDataPNG, sEncodedBufferImageDataPNGLength, imageAttributes, Image::NEVER );
+ image = EncodedBufferImage::New( sEncodedBufferImageDataPNG, sEncodedBufferImageDataPNGLength, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::DEFAULT, Image::NEVER );
DALI_TEST_CHECK( image );
DALI_TEST_CHECK( !image2 );
// Trigger image decode to initialise the handle
- image2 = EncodedBufferImage::New( sEncodedBufferImageDataPNG, sEncodedBufferImageDataPNGLength, imageAttributes, Image::UNUSED );
+ image2 = EncodedBufferImage::New( sEncodedBufferImageDataPNG, sEncodedBufferImageDataPNGLength, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::DEFAULT, Image::UNUSED );
DALI_TEST_CHECK( image2 );
END_TEST;
{
TestApplication application;
- tet_infoline("UtcDaliEncodedBufferImageNew02() - EncodedBufferImage::New( const uint8_t * const encodedImage, const std::size_t encodedImageByteCount, const ImageAttributes& attributes, const ReleasePolicy releasePol )");
+ tet_infoline( "UtcDaliEncodedBufferImageNew02() - EncodedBufferImage::New( const uint8_t * const encodedImage, const std::size_t encodedImageByteCount )" );
// Invoke default handle constructor for the Image base class:
Image image;
DALI_TEST_CHECK( !image );
// Trigger image decode to initialise the handle
- Dali::ImageAttributes imageAttributes;
- imageAttributes.SetSize( 720, 1280 );
- imageAttributes.SetScalingMode( Dali::ImageAttributes::FitHeight );
try
{
// This should throw on the null pointer:
- image = EncodedBufferImage::New( 0, sEncodedBufferImageDataPNGLength, imageAttributes, Image::NEVER );
+ image = EncodedBufferImage::New( 0, sEncodedBufferImageDataPNGLength );
tet_result( TET_FAIL );
}
catch (Dali::DaliException& e)
{
TestApplication application;
- tet_infoline("UtcDaliEncodedBufferImageNew03() - EncodedBufferImage::New( const uint8_t * const encodedImage, const std::size_t encodedImageByteCount, const ImageAttributes& attributes, const ReleasePolicy releasePol )");
+ tet_infoline( "UtcDaliEncodedBufferImageNew03() - EncodedBufferImage::New( const uint8_t * const encodedImage, const std::size_t encodedImageByteCount )" );
// Invoke default handle constructor for the Image base class:
Image image;
DALI_TEST_CHECK( !image );
// Trigger image decode to initialise the handle
- Dali::ImageAttributes imageAttributes;
try
{
// This should throw on the zero size:
- image = EncodedBufferImage::New( sEncodedBufferImageDataPNG, /** Trigger the assertion.*/ 0, imageAttributes, Image::NEVER );
+ image = EncodedBufferImage::New( sEncodedBufferImageDataPNG, /** Trigger the assertion.*/ 0 );
tet_result( TET_FAIL );
}
catch (Dali::DaliException& e)
#include <algorithm>
#include <stdlib.h>
#include <dali/public-api/dali-core.h>
+#include <dali/integration-api/bitmap.h>
#include <dali-test-suite-utils.h>
#include <test-native-image.h>
DALI_TEST_EQUALS( image1.GetWidth(), testSize.width, TEST_LOCATION );
DALI_TEST_EQUALS( image1.GetHeight(), testSize.height, TEST_LOCATION );
- Dali::ImageAttributes imageAttributes;
- imageAttributes.SetSize(128, 256);
- imageAttributes.SetScalingMode(Dali::ImageAttributes::FitHeight);
- Image image2 = ResourceImage::New(gTestImageFilename, imageAttributes);
+ Image image2 = ResourceImage::New( gTestImageFilename, ImageDimensions(128, 256), FittingMode::SCALE_TO_FILL, SamplingMode::DEFAULT );
DALI_TEST_EQUALS( image2.GetWidth(), 128u, TEST_LOCATION );
DALI_TEST_EQUALS( image2.GetHeight(), 256u, TEST_LOCATION );
{
ImageActor actor;
{
- ImageAttributes attrs;
- const Vector2 requestedSize( 40, 30 );
- attrs.SetSize( requestedSize.width, requestedSize.height );
- Image image = ResourceImage::New(gTestImageFilename, attrs);
+ Image image = ResourceImage::New(gTestImageFilename, ImageDimensions( 40, 30 ) );
actor = ImageActor::New(image);
Stage::GetCurrent().Add(actor);
#include <iostream>
#include <stdlib.h>
#include <dali/public-api/dali-core.h>
+#include <dali/integration-api/bitmap.h>
#include "dali-test-suite-utils/dali-test-suite-utils.h"
using namespace Dali;
const Vector2 closestImageSize( 80, 45);
application.GetPlatform().SetClosestImageSize(closestImageSize);
- ImageAttributes attrs;
- const Vector2 requestedSize( 40, 30 );
- attrs.SetSize( requestedSize.width, requestedSize.height );
- Image image = ResourceImage::New("image.jpg", attrs);
+ Vector2 requestedSize( 40, 30 );
+ Image image = ResourceImage::New("image.jpg", ImageDimensions( requestedSize.x, requestedSize.y ), FittingMode::DEFAULT, SamplingMode::DEFAULT );
ImageActor actor = ImageActor::New( image );
actor.SetRelayoutEnabled( false );
Stage::GetCurrent().Add(actor);
const Vector2 closestImageSize( 80, 45);
application.GetPlatform().SetClosestImageSize(closestImageSize);
- const Vector2 requestedSize( 40, 30 );
- ImageAttributes attrs;
- attrs.SetSize( requestedSize.width, requestedSize.height );
- Image image = ResourceImage::New("image.jpg", attrs);
+ Vector2 requestedSize( 40, 30 );
+ Image image = ResourceImage::New("image.jpg", ImageDimensions( requestedSize.x, requestedSize.y ), FittingMode::DEFAULT, SamplingMode::DEFAULT );
ImageActor actor = ImageActor::New( image );
actor.SetRelayoutEnabled( false );
Stage::GetCurrent().Add(actor);
application.GetPlatform().SetClosestImageSize(image2ClosestSize);
const Vector2 request2Size( 100, 100 );
- attrs.SetSize( request2Size.width, request2Size.height );
- Image image2 = ResourceImage::New("image2.jpg", attrs);
+ Image image2 = ResourceImage::New("image.jpg", ImageDimensions( request2Size.x, request2Size.y ), FittingMode::DEFAULT, SamplingMode::DEFAULT );
actor.SetImage(image2);
application.SendNotification(); // Flush update messages
Vector2 closestImageSize( 80, 45);
application.GetPlatform().SetClosestImageSize(closestImageSize);
- ImageAttributes attrs;
- const Vector2 requestedSize( 40, 30 );
- attrs.SetSize( requestedSize.width, requestedSize.height );
- Image image = ResourceImage::New("image.jpg", attrs);
+ Vector2 requestedSize( 40, 30 );
+ Image image = ResourceImage::New("image.jpg", ImageDimensions( requestedSize.x, requestedSize.y ), FittingMode::DEFAULT, SamplingMode::DEFAULT );
ImageActor actor = ImageActor::New( image );
actor.SetRelayoutEnabled( false );
Stage::GetCurrent().Add(actor);
application.GetPlatform().SetClosestImageSize(image2ClosestSize);
const Vector2 requestedSize2( 100, 100 );
- attrs.SetSize( requestedSize2.width, requestedSize2.height );
- Image image2 = ResourceImage::New("image2.jpg", attrs);
+ Image image2 = ResourceImage::New("image.jpg", ImageDimensions( requestedSize2.x, requestedSize2.y ), FittingMode::DEFAULT, SamplingMode::DEFAULT );
actor.SetImage(image2);
application.SendNotification(); // Flush update messages
Vector2 closestImageSize( 80, 45);
application.GetPlatform().SetClosestImageSize(closestImageSize);
- ImageAttributes attrs;
- const Vector2 requestedSize( 40, 30 );
- attrs.SetSize( requestedSize.width, requestedSize.height );
- Image image = ResourceImage::New("image.jpg", attrs);
+ Vector2 requestedSize( 40, 30 );
+ Image image = ResourceImage::New("image.jpg", ImageDimensions( requestedSize.x, requestedSize.y ), FittingMode::DEFAULT, SamplingMode::DEFAULT );
ImageActor actor = ImageActor::New( image );
actor.SetRelayoutEnabled( false );
Stage::GetCurrent().Add(actor);
Vector2 closestImageSize( 80, 45);
application.GetPlatform().SetClosestImageSize(closestImageSize);
- ImageAttributes attrs;
- const Vector2 requestedSize( 40, 30 );
- attrs.SetSize( requestedSize.width, requestedSize.height );
- Image image = ResourceImage::New("image.jpg", attrs);
+ Vector2 requestedSize( 40, 30 );
+ Image image = ResourceImage::New("image.jpg", ImageDimensions( requestedSize.x, requestedSize.y ), FittingMode::DEFAULT, SamplingMode::DEFAULT );
ImageActor actor = ImageActor::New( image );
actor.SetRelayoutEnabled( false );
Stage::GetCurrent().Add(actor);
+++ /dev/null
-/*
- * Copyright (c) 2014 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-#include <algorithm>
-#include <stdlib.h>
-#include <dali/public-api/dali-core.h>
-#include <dali-test-suite-utils.h>
-
-using std::max;
-using namespace Dali;
-
-void utc_dali_image_attributes_startup(void)
-{
- test_return_value = TET_UNDEF;
-}
-
-void utc_dali_image_attributes_cleanup(void)
-{
- test_return_value = TET_PASS;
-}
-
-int UtcDaliImageAttributesConstructor(void)
-{
- TestApplication application;
-
- tet_infoline("UtcDaliImageAttributesConstructor");
-
- // invoke default handle constructor
- ImageAttributes imageAttributes;
-
- DALI_TEST_CHECK( imageAttributes.GetWidth() == 0);
- END_TEST;
-}
-
-int UtcDaliImageAttributesLessThan(void)
-{
- TestApplication application;
-
- tet_infoline("UtcDaliImageAttributesLessThan");
-
- // invoke default handle constructor
- ImageAttributes imageAttributes;
-
- ImageAttributes imageAttributesWidth;
- imageAttributesWidth.SetSize(2,1);
- DALI_TEST_CHECK(imageAttributes < imageAttributesWidth);
-
- ImageAttributes imageAttributesHeight;
- imageAttributesHeight.SetSize(1,2);
- DALI_TEST_CHECK(imageAttributes < imageAttributesHeight);
-
- imageAttributesWidth.SetSize(Size(2,1));
- DALI_TEST_CHECK(imageAttributes < imageAttributesWidth);
-
- imageAttributesHeight.SetSize(Size(1,2));
- DALI_TEST_CHECK(imageAttributes < imageAttributesHeight);
-
-
- ImageAttributes imageAttributesScaling;
- imageAttributesScaling.SetScalingMode(ImageAttributes::FitHeight);
- DALI_TEST_CHECK(imageAttributes < imageAttributesScaling);
- END_TEST;
-}
-
-int UtcDaliImageAttributesEquality(void)
-{
- TestApplication application;
-
- tet_infoline("UtcDaliImageAttributesEquality");
-
- // invoke default handle constructor
- ImageAttributes imageAttributes01;
- ImageAttributes imageAttributes02;
-
- DALI_TEST_CHECK(imageAttributes02 == imageAttributes01);
- END_TEST;
-}
-
-int UtcDaliImageAttributesInEquality(void)
-{
- TestApplication application;
-
- tet_infoline("UtcDaliImageAttributesInEquality");
-
- // invoke default handle constructor
- ImageAttributes imageAttributes01;
- ImageAttributes imageAttributes02;
-
- DALI_TEST_CHECK((imageAttributes02 != imageAttributes01) == false);
- END_TEST;
-}
{
TestApplication application;
- tet_infoline("UtcDaliREsourceImageNew02 - ResourceImage::New(const std::string&, const ImageAttributes&)");
+ tet_infoline("UtcDaliREsourceImageNew02 - ResourceImage New( const std::string& url, ImageDimensions size, FittingMode scalingMode, SamplingMode samplingMode, bool orientationCorrection = true )");
// invoke default handle constructor
ResourceImage image;
DALI_TEST_CHECK( !image );
// initialise handle
- Dali::ImageAttributes imageAttributes;
- imageAttributes.SetSize(128, 256);
- imageAttributes.SetScalingMode(Dali::ImageAttributes::FitHeight);
- image = ResourceImage::New(gTestImageFilename, imageAttributes);
+ image = ResourceImage::New(gTestImageFilename, ImageDimensions( 128, 256 ), FittingMode::FIT_HEIGHT );
DALI_TEST_CHECK( image );
END_TEST;
Vector2 testSize(8.0f, 16.0f);
platform.SetClosestImageSize(testSize);
- Vector2 size = ResourceImage::GetImageSize(gTestImageFilename);
+ const ImageDimensions size = ResourceImage::GetImageSize(gTestImageFilename);
DALI_TEST_CHECK( application.GetPlatform().GetTrace().FindMethod("GetClosestImageSize"));
- DALI_TEST_EQUALS( size, testSize, TEST_LOCATION);
+ DALI_TEST_EQUALS( Vector2( size.GetX(), size.GetY() ), testSize, TEST_LOCATION);
END_TEST;
}
const unsigned int DRAW_MODE_VALUES_COUNT = sizeof( DRAW_MODE_VALUES ) / sizeof( DRAW_MODE_VALUES[0] );
-//////////////////////////////////////////////////////////////////////////////
-// Helpers for string to enum comparisons for Image and ImageAttributes
-//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+// Helpers for string to enum comparisons for Image and Image loading parameters
+////////////////////////////////////////////////////////////////////////////////
/**
* Template to check enumerations of type T, with a class of type X
return image;
}
-/// Helper method to create ImageAttributes using an Image
-ImageAttributes NewImageAttributes( const Property::Value& map )
-{
- ResourceImage image = ResourceImage::DownCast( NewImage( map ) );
- return image.GetAttributes();
-}
-
//////////////////////////////////////////////////////////////////////////////
// Helpers for string to enum comparisons for Actor to Property::Map
//////////////////////////////////////////////////////////////////////////////
DALI_TEST_ASSERT( e, "value.GetType()", TEST_LOCATION );
}
- // Invalid pixel-format
+ // Invalid fitting-mode
try
{
Property::Map map;
- map[ "pixel-format" ] = Vector3::ZERO;
+ map[ "fitting-mode" ] = Vector3::ZERO;
Image image = NewImage( map );
- tet_result( TET_FAIL );
+ DALI_TEST_EQUALS( "Expected exception to be thrown", "But exception was not thrown", TEST_LOCATION );
}
catch ( DaliException& e )
{
- DALI_TEST_ASSERT( e, "map.GetValue(field).GetType()", TEST_LOCATION );
+ DALI_TEST_ASSERT( e, "value.GetType() == Property::STRING", TEST_LOCATION );
// Invalid value
try
{
Property::Map map;
- map[ "pixel-format" ] = "INVALID";
+ map[ "fitting-mode" ] = "INVALID";
Image image = NewImage( map );
- tet_result( TET_FAIL );
+ DALI_TEST_EQUALS( "Expected exception to be thrown", "But exception was not thrown", TEST_LOCATION );
}
catch ( DaliException& e )
{
try
{
Property::Map map;
- map[ "scaling-mode" ] = Vector3::ZERO;
+ map[ "sampling-mode" ] = Vector3::ZERO;
Image image = NewImage( map );
- tet_result( TET_FAIL );
+ DALI_TEST_EQUALS( "Expected exception to be thrown", "But exception was not thrown", TEST_LOCATION );
}
catch ( DaliException& e )
{
- DALI_TEST_ASSERT( e, "map.GetValue(field).GetType()", TEST_LOCATION );
+ DALI_TEST_ASSERT( e, "value.GetType() == Property::STRING", TEST_LOCATION );
// Invalid value
try
{
Property::Map map;
- map[ "scaling-mode" ] = "INVALID";
+ map[ "sampling-mode" ] = "INVALID";
Image image = NewImage( map );
- tet_result( TET_FAIL );
+ DALI_TEST_EQUALS( "Expected exception to be thrown", "But exception was not thrown", TEST_LOCATION );
}
catch ( DaliException& e )
{
}
}
+ // Invalid orientation-correction
+ try
+ {
+ Property::Map map;
+ map[ "orientation" ] = Vector3::ZERO;
+ Image image = NewImage( map );
+ DALI_TEST_EQUALS( "Expected exception to be thrown", "But exception was not thrown", TEST_LOCATION );
+ }
+ catch ( DaliException& e )
+ {
+ DALI_TEST_ASSERT( e, "value.GetType() == Property::BOOLEAN", TEST_LOCATION );
+ }
+
// Invalid type
try
{
DALI_TEST_ASSERT( e, "!\"Unknown", TEST_LOCATION );
}
}
+
+ // Invalid pixel-format
+ try
+ {
+ Property::Map map;
+ map[ "pixel-format" ] = Vector3::ZERO;
+ Image image = NewImage( map );
+ tet_result( TET_FAIL );
+ }
+ catch ( DaliException& e )
+ {
+ DALI_TEST_ASSERT( e, "map.GetValue(field).GetType()", TEST_LOCATION );
+
+ // Invalid value
+ try
+ {
+ Property::Map map;
+ map[ "pixel-format" ] = "INVALID";
+ Image image = NewImage( map );
+ tet_result( TET_FAIL );
+ }
+ catch ( DaliException& e )
+ {
+ DALI_TEST_ASSERT( e, "!\"Unknown", TEST_LOCATION );
+ }
+ }
+
END_TEST;
}
{ "IMMEDIATE", ResourceImage::IMMEDIATE },
{ "ON_DEMAND", ResourceImage::ON_DEMAND }
};
- TestEnumStrings< ResourceImage::LoadPolicy, ResourceImage >( map, values, ( sizeof( values ) / sizeof ( values[0] ) ), &ResourceImage::GetLoadPolicy, &NewResourceImage );
+ TestEnumStrings< ResourceImage::LoadPolicy, ResourceImage >( map, values, ( sizeof( values ) / sizeof ( values[0] ) ), &ResourceImage::GetLoadPolicy, &NewResourceImage );
}
// release-policy
//map.erase( map.end() - 2, map.end() );
- // scaling-mode
- map[ "scaling-mode" ] = "";
- {
- const StringEnum< int > values[] =
- {
- { "SHRINK_TO_FIT", ImageAttributes::ShrinkToFit },
- { "SCALE_TO_FILL", ImageAttributes::ScaleToFill },
- { "FIT_WIDTH", ImageAttributes::FitWidth },
- { "FIT_HEIGHT", ImageAttributes::FitHeight },
- };
- TestEnumStrings< ImageAttributes::ScalingMode, ImageAttributes >( map, values, ( sizeof( values ) / sizeof ( values[0] ) ), &ImageAttributes::GetScalingMode, &NewImageAttributes );
- }
-
// type FrameBufferImage
map[ "type" ] = "FrameBufferImage";
{
{ "COMPRESSED_SRGB8_ALPHA8_ETC2_EAC", Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC },
{ "COMPRESSED_RGB8_ETC1", Pixel::COMPRESSED_RGB8_ETC1 },
{ "COMPRESSED_RGB_PVRTC_4BPPV1", Pixel::COMPRESSED_RGB_PVRTC_4BPPV1 },*/
- // BufferImage doesnot support compressed format
+ // BufferImage does not support compressed formats
};
TestEnumStrings< Pixel::Format, BufferImage >( map, values, ( sizeof( values ) / sizeof ( values[0] ) ), &BufferImage::GetPixelFormat, &NewBufferImage );
DALI_TEST_EQUALS( value.GetValue( "load-policy" ).Get< std::string >(), "IMMEDIATE", TEST_LOCATION );
DALI_TEST_CHECK( value.HasKey( "release-policy") );
DALI_TEST_EQUALS( value.GetValue( "release-policy" ).Get< std::string >(), "NEVER", TEST_LOCATION );
- DALI_TEST_CHECK( value.HasKey( "scaling-mode") );
- DALI_TEST_EQUALS( value.GetValue( "scaling-mode" ).Get< std::string >(), "SHRINK_TO_FIT", TEST_LOCATION );
DALI_TEST_CHECK( !value.HasKey( "width" ) );
DALI_TEST_CHECK( !value.HasKey( "height" ) );
}
// Change values
{
- ImageAttributes attributes;
- attributes.SetScalingMode( ImageAttributes::FitWidth );
- attributes.SetSize( 300, 400 );
- Image image = ResourceImage::New( "MY_PATH", attributes, ResourceImage::ON_DEMAND, Image::UNUSED );
+ ResourceImage image = ResourceImage::New( "MY_PATH", ResourceImage::ON_DEMAND, Image::UNUSED, ImageDimensions( 300, 400 ), FittingMode::FIT_WIDTH );
Property::Map map;
CreatePropertyMap( image, map );
DALI_TEST_EQUALS( value.GetValue( "load-policy" ).Get< std::string >(), "ON_DEMAND", TEST_LOCATION );
DALI_TEST_CHECK( value.HasKey( "release-policy") );
DALI_TEST_EQUALS( value.GetValue( "release-policy" ).Get< std::string >(), "UNUSED", TEST_LOCATION );
- DALI_TEST_CHECK( value.HasKey( "scaling-mode") );
- DALI_TEST_EQUALS( value.GetValue( "scaling-mode" ).Get< std::string >(), "FIT_WIDTH", TEST_LOCATION );
DALI_TEST_CHECK( value.HasKey( "width" ) );
DALI_TEST_EQUALS( value.GetValue( "width" ).Get< int >(), 300, TEST_LOCATION );
DALI_TEST_CHECK( value.HasKey( "height" ) );
*/
// INTERNAL INCLUDES
-#include <dali/integration-api/bitmap.h>
+
#include <dali/integration-api/resource-cache.h>
+#include <dali/integration-api/bitmap.h> ///@todo Remove this include (a bunch of stuff needs to include it though)
+#include <dali/public-api/images/image-operations.h>
namespace Dali
{
namespace Integration
{
-class Bitmap;
class DynamicsFactory;
* to cooperate with other apps and reduce the chance of this one being
* force-killed in a low memory situation.
*/
- virtual void Suspend() {} ///!ToDo: Make pure virtual once dali-adaptor patch is in place = 0;
+ virtual void Suspend() = 0;
/**
* Tell the platform abstraction that Dali is resuming from a pause, such as
* It is time to wake up sleeping background threads and recreate memory
* caches and other temporary data.
*/
- virtual void Resume() {} ///!ToDo: Make pure virtual once dali-adaptor patch is in place = 0;
+ virtual void Resume() = 0;
// Resource Loading
/**
- * Determine the size of an image the resource loaders will provide when given the same
- * image attributes.
+ * @brief Determine the size of an image the resource loaders will provide when
+ * given the same image loading parameters.
+ *
* This is a synchronous request.
* This function is used to determine the size of an image before it has loaded.
* @param[in] filename name of the image.
- * @param[in] attributes The attributes used to load the image
- * @param[out] closestSize Size of the image that will be loaded.
- */
- virtual void GetClosestImageSize( const std::string& filename,
- const ImageAttributes& attributes,
- Vector2& closestSize ) = 0;
-
- /**
- * Determine the size of an image the resource loaders will provide when given the same
- * image attributes.
+ * @param[in] size The requested size for the image.
+ * @param[in] fittingMode The method to use to map the source image to the desired
+ * dimensions.
+ * @param[in] samplingMode The image filter to use if the image needs to be
+ * downsampled to the requested size.
+ * @param[in] orientationCorrection Whether to use image metadata to rotate or
+ * flip the image, e.g., from portrait to landscape.
+ * @return dimensions that image will have if it is loaded with given parameters.
+ */
+ virtual ImageDimensions GetClosestImageSize( const std::string& filename,
+ ImageDimensions size = ImageDimensions( 0, 0 ),
+ FittingMode::Type fittingMode = FittingMode::SHRINK_TO_FIT,
+ SamplingMode::Type samplingMode = SamplingMode::BOX,
+ bool orientationCorrection = true) = 0;
+
+ /**
+ @brief Determine the size of an image the resource loaders will provide when
+ * given the same image loading parameters.
+ *
* This is a synchronous request.
* This function is used to determine the size of an image before it has loaded.
- * @param[in] resourceBuffer A pointer to an encoded image buffer
- * @param[in] attributes The attributes used to load the image
- * @param[out] closestSize Size of the image that will be loaded.
- */
- virtual void GetClosestImageSize( ResourcePointer resourceBuffer,
- const ImageAttributes& attributes,
- Vector2& closestSize ) = 0;
+ * @param[in] filename name of the image.
+ * @param[in] size The requested size for the image.
+ * @param[in] fittingMode The method to use to map the source image to the desired
+ * dimensions.
+ * @param[in] samplingMode The image filter to use if the image needs to be
+ * downsampled to the requested size.
+ * @param[in] orientationCorrection Whether to use image metadata to rotate or
+ * flip the image, e.g., from portrait to landscape.
+ * @return dimensions that image will have if it is loaded with given parameters.
+ */
+ virtual ImageDimensions GetClosestImageSize( ResourcePointer resourceBuffer,
+ ImageDimensions size = ImageDimensions( 0, 0 ),
+ FittingMode::Type fittingMode = FittingMode::SHRINK_TO_FIT,
+ SamplingMode::Type samplingMode = SamplingMode::BOX,
+ bool orientationCorrection = true) = 0;
/**
* Request a resource from the native filesystem. This is an asynchronous request.
* This is an asynchronous request.
*/
virtual void SaveResource(const ResourceRequest& request) = 0;
+
/**
* Cancel an ongoing LoadResource() request.
* Multi-threading note: this method will be called from the main thread only i.e. not
// INTERNAL INCLUDES
#include <dali/integration-api/resource-types.h>
+#include <dali/public-api/object/ref-object.h>
namespace Dali
{
// INTERNAL INCLUDES
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/common/vector-wrapper.h>
-#include <dali/public-api/images/image-attributes.h>
+#include <dali/public-api/images/image-operations.h>
+#include <dali/public-api/math/uint-16-pair.h>
+#include <dali/public-api/math/vector2.h>
#include <dali/integration-api/resource-declarations.h>
namespace Dali
{
+typedef Uint16Pair ImageDimensions;
+
namespace Integration
{
{
/**
* Constructor.
- * @param[in] attribs parameters for image loading request
+ * @param[in] size The requested size for the bitmap.
+ * @param[in] scalingMode The method to use to map the source bitmap to the desired
+ * dimensions.
+ * @param[in] samplingMode The filter to use if the bitmap needs to be downsampled
+ * to the requested size.
+ * @param[in] orientationCorrection Whether to use bitmap metadata to rotate or
+ * flip the bitmap, e.g., from portrait to landscape.
*/
- BitmapResourceType(const ImageAttributes& attribs)
+ BitmapResourceType( ImageDimensions size = ImageDimensions( 0, 0 ),
+ FittingMode::Type scalingMode = FittingMode::DEFAULT,
+ SamplingMode::Type samplingMode = SamplingMode::DEFAULT,
+ bool orientationCorrection = true )
: ResourceType(ResourceBitmap),
- imageAttributes(attribs) {}
+ size(size), scalingMode(scalingMode), samplingMode(samplingMode), orientationCorrection(orientationCorrection) {}
/**
* Destructor.
*/
virtual ResourceType* Clone() const
{
- return new BitmapResourceType(imageAttributes);
+ return new BitmapResourceType( size, scalingMode, samplingMode, orientationCorrection );
}
/**
* Attributes are copied from the request.
*/
- ImageAttributes imageAttributes;
+ ImageDimensions size;
+ FittingMode::Type scalingMode;
+ SamplingMode::Type samplingMode;
+ bool orientationCorrection;
private:
/**
* Constructor.
- * @param[in] attribs parameters for image loading request
+ * @param[in] dimensions Width and Height to allocate for image.
*/
- NativeImageResourceType(const ImageAttributes& attribs)
+ NativeImageResourceType( ImageDimensions dimensions )
: ResourceType(ResourceNativeImage),
- imageAttributes(attribs) {}
+ imageDimensions(dimensions) {}
/**
* Destructor.
*/
virtual ResourceType* Clone() const
{
- return new NativeImageResourceType(imageAttributes);
+ return new NativeImageResourceType(imageDimensions);
}
/**
* Attributes are copied from the request (if supplied).
*/
- ImageAttributes imageAttributes;
+ ImageDimensions imageDimensions;
private:
/**
* Constructor.
- * @param[in] attribs parameters for image loading request
+ * @param[in] dims Width and Height to allocate for image.
*/
- RenderTargetResourceType(const ImageAttributes& attribs)
+ RenderTargetResourceType( ImageDimensions dims )
: ResourceType(ResourceTargetImage),
- imageAttributes(attribs) {}
+ imageDimensions(dims) {}
/**
* Destructor.
*/
virtual ResourceType* Clone() const
{
- return new RenderTargetResourceType(imageAttributes);
+ return new RenderTargetResourceType(imageDimensions);
}
/**
- * Attributes are copied from the request.
+ * Image size is copied from the request.
*/
- ImageAttributes imageAttributes;
+ ImageDimensions imageDimensions;
private:
--- /dev/null
+/*
+ * Copyright (c) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/common/image-attributes.h>
+
+// EXTERNAL INCLUDES
+#include <cmath>
+
+namespace Dali
+{
+namespace Internal
+{
+
+const ImageAttributes ImageAttributes::DEFAULT_ATTRIBUTES;
+
+struct ImageAttributes::ImageAttributesImpl
+{
+ ImageAttributesImpl()
+ : width(0),
+ height(0),
+ scaling(Dali::FittingMode::SHRINK_TO_FIT),
+ filtering(SamplingMode::BOX),
+ mOrientationCorrection(false)
+ {
+ }
+
+ ~ImageAttributesImpl()
+ {
+ }
+
+ ImageAttributesImpl(const ImageAttributesImpl& rhs)
+ : width( rhs.width ),
+ height( rhs.height ),
+ scaling( rhs.scaling ),
+ filtering( rhs.filtering ),
+ mOrientationCorrection( rhs.mOrientationCorrection )
+ {
+ }
+
+ ImageAttributesImpl& operator=(const ImageAttributesImpl& rhs)
+ {
+ if (this != &rhs)
+ {
+ width = rhs.width;
+ height = rhs.height;
+ scaling = rhs.scaling;
+ filtering = rhs.filtering;
+
+ mOrientationCorrection = rhs.mOrientationCorrection;
+ }
+
+ return *this;
+ }
+
+ unsigned int width : 16; ///< image width in pixels
+ unsigned int height : 16; ///< image height in pixels
+ ScalingMode scaling : 3; ///< scaling option, ShrinkToFit is default
+ FilterMode filtering : 3; ///< filtering option. Box is the default
+ bool mOrientationCorrection : 1; ///< If true, image pixels are reordered according to orientation metadata on load.
+ bool isDistanceField : 1; ///< true, if the image is a distancefield. Default is false.
+};
+
+
+ImageAttributes::ImageAttributes()
+: impl( new ImageAttributesImpl() )
+{
+}
+
+ImageAttributes::ImageAttributes(const ImageAttributes& rhs)
+: impl( new ImageAttributesImpl(*rhs.impl) )
+{
+}
+
+ImageAttributes& ImageAttributes::operator=(const ImageAttributes& rhs)
+{
+ *impl = *rhs.impl;
+
+ return *this;
+}
+
+ImageAttributes::~ImageAttributes()
+{
+ delete impl;
+}
+
+void ImageAttributes::SetSize(unsigned int width, unsigned int height)
+{
+ impl->width = width;
+ impl->height = height;
+}
+
+void ImageAttributes::SetSize( const Size& size )
+{
+ impl->width = size.width;
+ impl->height = size.height;
+}
+
+void ImageAttributes::SetScalingMode( ScalingMode scale )
+{
+ impl->scaling = scale;
+}
+
+void ImageAttributes::SetFilterMode( FilterMode filtering )
+{
+ impl->filtering = filtering;
+}
+
+void ImageAttributes::SetOrientationCorrection(const bool enabled)
+{
+ impl->mOrientationCorrection = enabled;
+}
+
+void ImageAttributes::Reset( ImageDimensions dimensions, ScalingMode scaling, FilterMode sampling, bool orientationCorrection )
+{
+ impl->width = dimensions.GetWidth();
+ impl->height = dimensions.GetHeight();
+ impl->scaling = scaling;
+ impl->filtering = sampling;
+ impl->mOrientationCorrection = orientationCorrection;
+}
+
+unsigned int ImageAttributes::GetWidth() const
+{
+ return impl->width;
+}
+
+unsigned int ImageAttributes::GetHeight() const
+{
+ return impl->height;
+}
+
+Size ImageAttributes::GetSize() const
+{
+ return Size(impl->width, impl->height);
+}
+
+ImageAttributes::ScalingMode ImageAttributes::GetScalingMode() const
+{
+ return impl->scaling;
+}
+
+ImageAttributes::FilterMode ImageAttributes::GetFilterMode() const
+{
+ return impl->filtering;
+}
+
+bool ImageAttributes::GetOrientationCorrection() const
+{
+ return impl->mOrientationCorrection;
+}
+
+ImageAttributes ImageAttributes::New()
+{
+ return ImageAttributes();
+}
+
+ImageAttributes ImageAttributes::New(unsigned int imageWidth, unsigned int imageHeight)
+{
+ ImageAttributes attributes;
+ attributes.impl->width = imageWidth;
+ attributes.impl->height = imageHeight;
+ return attributes;
+}
+
+/**
+ * Less then comparison operator.
+ * @param [in] a parameter tested
+ * @param [in] b parameter tested
+ */
+bool operator<(const ImageAttributes& a, const ImageAttributes& b)
+{
+ // Bail out if one is distance field and the other is not.
+ if (a.impl->isDistanceField != b.impl->isDistanceField)
+ {
+ return a.impl->isDistanceField < b.impl->isDistanceField;
+ }
+
+ if (a.impl->width != b.impl->width)
+ {
+ return a.impl->width < b.impl->width;
+ }
+
+ if (a.impl->height != b.impl->height)
+ {
+ return a.impl->height < b.impl->height;
+ }
+
+ if (a.impl->mOrientationCorrection != b.impl->mOrientationCorrection)
+ {
+ return a.impl->mOrientationCorrection < b.impl->mOrientationCorrection;
+ }
+
+ if (a.impl->scaling != b.impl->scaling)
+ {
+ return a.impl->scaling < b.impl->scaling;
+ }
+
+ if (a.impl->filtering != b.impl->filtering)
+ {
+ return a.impl->filtering < b.impl->filtering;
+ }
+
+ // they are equal
+ return false;
+}
+
+/**
+ * Equal to comparison operator.
+ * @param [in] a parameter tested for equality
+ * @param [in] b parameter tested for equality
+ */
+bool operator==(const ImageAttributes& a, const ImageAttributes& b)
+{
+ return a.impl->width == b.impl->width &&
+ a.impl->height == b.impl->height &&
+ a.impl->mOrientationCorrection == b.impl->mOrientationCorrection &&
+ a.impl->scaling == b.impl->scaling &&
+ a.impl->filtering == b.impl->filtering;
+}
+
+/**
+ * Not equal to comparison operator.
+ * @param [in] a parameter tested for equality
+ * @param [in] b parameter tested for equality
+ */
+bool operator!=(const ImageAttributes& a, const ImageAttributes& b)
+{
+ return !(a == b);
+}
+
+} // namespace Internal
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_INTERNAL_IMAGE_ATTRIBUTES_H__
+#define __DALI_INTERNAL_IMAGE_ATTRIBUTES_H__
+
+/*
+ * Copyright (c) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <stdint.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/images/pixel.h>
+#include <dali/public-api/images/image-operations.h>
+#include <dali/public-api/math/rect.h>
+#include <dali/public-api/math/vector2.h>
+
+namespace Dali
+{
+namespace Internal
+{
+
+/**
+ * @brief Describes Image properties like dimensions and pixel format and
+ * operations to be applied to images during the load process.
+ *
+ * ImageAttributes is used to define a set of properties of an image and a
+ * sequence of operations to be applied when loading it.
+ *
+ * The overall order of operations which can be applied is:
+ * 1. Determine the desired dimensions for the final bitmap.
+ * 2. Scale the image to fit the desired dimensions.
+ *
+ * The default for each stage is to do nothing.
+ * To enable a calculation of desired final image dimensions and fitting to it, SetSize() must be called.
+ *
+ * The loader does not guarantee to rescale a loaded image to the exact desired dimensions, but it will make a best effort to downscale images.
+ * The fitting to destination dimensions controlled by the ScalingMode may choose to fit to a larger area with an equivalent aspect ratio.
+ * If the requested dimensions are larger than the loaded ones, it will never upscale on load to fill them but will instead fit to smaller dimensions of identical aspect ratio.
+ * This is transparent to an application as the upscaling can happen during rendering.
+ *
+ * To enable scaling of images on load, desired dimensions must be set using SetSize().
+ * Only one of the dimensions need be supplied, in which case, the other is calculated based on the aspect ratio of the raw loaded image.
+ * The desired dimensions 2-tuple 'd' is determined as follows for loaded image dimensions 'l' and 's', the dimensions tuple set with SetSize():
+ * * `d = s, if s.x != 0 & s.y != 0, else:`
+ * * `d = [s.x, s.x * (l.y / l.x)], if s.x != 0 & s.y = 0, else:`
+ * * `d = [s.y * (l.x / l.y), s.y], if s.x = 0 & s.y != 0, else:`
+ * * `d = l, otherwise.`
+ *
+ * Use cases for scaling images on load include:
+ * 1. Full-screen image display: Limit loaded image resolution to device resolution using ShrinkToFit mode.
+ * 2. Thumbnail gallery grid: Limit loaded image resolution to screen tile using ScaleToFill mode.
+ * 3. Image columns: Limit loaded image resolution to column width using FitWidth mode.
+ * 4. Image rows: Limit loaded image resolution to row height using FitHeight mode.
+ *
+ * @note The aspect ratio of image contents is preserved by all scaling modes, so for example squares in input images stay square after loading.
+ */
+class DALI_IMPORT_API ImageAttributes
+{
+public:
+
+ /**
+ * @brief Scaling options, used when resizing images on load to fit desired dimensions.
+ *
+ * A scaling mode controls the region of a loaded image to be mapped to the
+ * desired image rectangle specified using ImageAttributes.SetSize().
+ * All scaling modes preserve the aspect ratio of the image contents.
+ */
+ typedef Dali::FittingMode::Type ScalingMode;
+
+ /**
+ * @brief Filtering options, used when resizing images on load to sample original pixels.
+ *
+ * A FilterMode controls how pixels in the raw image on-disk are sampled and
+ * combined to generate each pixel of the destination loaded image.
+ *
+ * @note NoFilter and Box modes do not guarantee that the loaded pixel array
+ * exactly matches the rectangle specified by the desired dimensions and
+ * ScalingMode, but all other filter modes do if the desired dimensions are
+ * `<=` the raw dimensions of the image file.
+ */
+ typedef Dali::SamplingMode::Type FilterMode;
+
+ static const ImageAttributes DEFAULT_ATTRIBUTES; ///< Default attributes have no size
+
+ /**
+ * @brief Default constructor, initializes to default values.
+ */
+ ImageAttributes();
+
+ /**
+ * @brief This copy constructor is required for correctly copying internal implementation.
+ *
+ * @param [in] rhs A reference to the copied handle
+ */
+ ImageAttributes(const ImageAttributes& rhs);
+
+ /**
+ * @brief This assignment operator is required for correctly handling the internal implementation.
+ *
+ * @param [in] rhs A reference to the copied handle
+ * @return a reference to this object
+ */
+ ImageAttributes& operator=(const ImageAttributes& rhs);
+
+ /**
+ * @brief Default destructor.
+ */
+ ~ImageAttributes();
+
+ /**
+ * @brief Create an initialised image attributes object.
+ *
+ * @return A handle to a newly allocated object
+ */
+ static ImageAttributes New();
+
+ /**
+ * @brief Create an initialised image attributes object.
+ *
+ * @param [in] width desired width.
+ * @param [in] height desired height
+ * @return A handle to a newly allocated object
+ */
+ static ImageAttributes New(unsigned int width, unsigned int height);
+
+ /**
+ * @brief Set the size properties.
+ *
+ * By default width and height are set to zero which means the image loaded has the original size.
+ * If one dimension is set to non-zero, but the other zeroed, the unspecified one is derived from
+ * the one that is set and the aspect ratio of the image.
+ *
+ * @param [in] width desired width.
+ * @param [in] height desired height
+ */
+ void SetSize(unsigned int width, unsigned int height);
+
+ /**
+ * @brief Set the image dimension properties.
+ *
+ * By default, width and height are set to zero which means the image loaded has the original size.
+ * If one dimension is set to non-zero, but the other zeroed, the unspecified one is derived from
+ * the one that is set and the aspect ratio of the image.
+ *
+ * @param [in] size desired size.
+ */
+ void SetSize( const Size& size );
+
+ /**
+ * @brief Set the scale field of the image attributes.
+ *
+ * By default, ShrinkToFit is set.
+ * @param [in] scalingMode The desired scaling mode
+ */
+ void SetScalingMode( ScalingMode scalingMode );
+
+ /**
+ * @brief Setter for the FilterMode.
+ * By default, Box is set.
+ * @param [in] filterMode The desired filter mode.
+ */
+ void SetFilterMode( FilterMode filterMode );
+
+ /**
+ * @brief Set whether the image will be rotated/flipped back into portrait orientation.
+ *
+ * This will only be necessary if metadata indicates that the
+ * image has a different viewing orientation.
+ *
+ * This metadata, optionally present in formats that use exif for example,
+ * can encode the physical orientation of the camera which took the picture,
+ * establishing which directions in the image correspond to real-world "up"
+ * and the horizon.
+ * By default the metadata is ignored, but if this function is called with
+ * the value "true", the pixels of an image are reordered at load time to reflect
+ * the orientation in the metadata.
+ *
+ * @param [in] enabled If true, the image orientation metadata will be used to
+ * transform the pixels of the image as laid-out in memory.
+ */
+ void SetOrientationCorrection(bool enabled);
+
+ /**
+ * @brief Change all members in one operation.
+ * @param[in] dimensions width and height
+ * @param[in] scaling Scaling mode for resizing loads.
+ * @param[in] sampling Sampling mode.
+ * @param[in] orientation Orientation correction toggle.
+ */
+ void Reset( ImageDimensions dimensions = ImageDimensions(0, 0), ScalingMode scaling = ScalingMode(), FilterMode sampling = FilterMode(), bool orientationCorrection = true );
+
+
+ /**
+ * @brief Return the width currently represented by the attribute.
+ *
+ * @return width
+ */
+ unsigned int GetWidth() const;
+
+ /**
+ * @brief Return the height currently represented by the attribute.
+ *
+ * @return height
+ */
+ unsigned int GetHeight() const;
+
+ /**
+ * @brief Return the size currently represented by the attribute.
+ *
+ * @return size
+ */
+ Size GetSize() const;
+
+ /**
+ * @brief Return the scale currently represented by the attribute.
+ *
+ * @return scale
+ */
+ ScalingMode GetScalingMode() const;
+
+ /**
+ * @brief Getter for the FilterMode
+ *
+ * @return The FilterMode previously set, or the default value if none has
+ * been.
+ */
+ FilterMode GetFilterMode() const;
+
+ /**
+ * @brief Whether to correct for physical orientation of an image.
+ *
+ * @return Whether image pixels should be transformed according to the
+ * orientation metadata, if any.
+ */
+ bool GetOrientationCorrection() const;
+
+ /**
+ * @brief Less then comparison operator.
+ *
+ * @param [in] a parameter tested
+ * @param [in] b parameter tested
+ * @return true if a is less than b
+ */
+ friend bool operator<(const ImageAttributes& a, const ImageAttributes& b);
+
+ /**
+ * @brief Equal to comparison operator.
+ *
+ * @param [in] a parameter tested for equality
+ * @param [in] b parameter tested for equality
+ * @return true if a is equal to b
+ */
+ friend bool operator==(const ImageAttributes& a, const ImageAttributes& b);
+
+ /**
+ * @brief Not equal to comparison operator.
+ *
+ * @param [in] a parameter tested for equality
+ * @param [in] b parameter tested for equality
+ * @return true if a is not equal to b
+ */
+ friend bool operator!=(const ImageAttributes& a, const ImageAttributes& b);
+
+private:
+ struct ImageAttributesImpl;
+ ImageAttributesImpl* impl; ///< Implementation pointer
+};
+
+/**
+ * @brief Less then comparison operator.
+ *
+ * @param [in] a parameter tested
+ * @param [in] b parameter tested
+ * @return true if a is less than b
+ */
+DALI_IMPORT_API bool operator<(const ImageAttributes& a, const ImageAttributes& b);
+
+/**
+ * @brief Equal to comparison operator.
+ *
+ * @param [in] a parameter tested for equality
+ * @param [in] b parameter tested for equality
+ * @return true if a is equal to b
+ */
+DALI_IMPORT_API bool operator==(const ImageAttributes& a, const ImageAttributes& b);
+
+/**
+ * @brief Not equal to comparison operator.
+ *
+ * @param [in] a parameter tested for equality
+ * @param [in] b parameter tested for equality
+ * @return true if a is not equal to b
+ */
+DALI_IMPORT_API bool operator!=(const ImageAttributes& a, const ImageAttributes& b);
+
+} // namespace Internal
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_IMAGE_ATTRIBUTES_H__
Integration::BitmapPtr Atlas::LoadBitmap( const std::string& url )
{
- ImageAttributes loadedAttrs;
- Integration::BitmapResourceType resourceType( loadedAttrs );
+ Integration::BitmapResourceType resourceType;
Integration::PlatformAbstraction& platformAbstraction = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction();
Integration::ResourcePointer resource = platformAbstraction.LoadResourceSynchronously(resourceType, url);
} // unnamed namespace
EncodedBufferImagePtr EncodedBufferImage::New( const uint8_t * const encodedImage,
- const std::size_t encodedImageByteCount,
- const ImageAttributes& attributes,
- const ReleasePolicy releasePol )
+ std::size_t encodedImageByteCount,
+ ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode,
+ bool orientationCorrection,
+ ReleasePolicy releasePol )
{
DALI_ASSERT_DEBUG( encodedImage && "Null image pointer passed-in for decoding from memory." );
DALI_ASSERT_DEBUG( encodedImageByteCount > 0U && "Zero size passed for image resource in memory buffer." );
image->Initialize(); // Second stage initialization
// Replicate the functionality of ImageFactory::load() without the filesystem caching:
- Dali::Integration::BitmapResourceType resourceType( attributes );
+ Dali::Integration::BitmapResourceType resourceType( size, fittingMode, samplingMode, orientationCorrection );
RequestBufferPtr buffer( new RequestBuffer );
buffer->GetVector().Resize( encodedImageByteCount );
// Resize() won't throw on failure, so avoid a SEGV if the allocation failed:
memcpy( &(buffer->GetVector()[0]), encodedImage, encodedImageByteCount );
// Get image size from buffer
- Vector2 size;
- Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().GetClosestImageSize( buffer, attributes, size );
- image->mWidth = (unsigned int) size.width;
- image->mHeight = (unsigned int) size.height;
+ const ImageDimensions expectedSize = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().GetClosestImageSize( buffer, size, fittingMode, samplingMode, orientationCorrection );
+ image->mWidth = (unsigned int) expectedSize.GetWidth();
+ image->mHeight = (unsigned int) expectedSize.GetHeight();
ResourceClient &resourceClient = ThreadLocalStorage::Get().GetResourceClient();
ResourceTicketPtr ticket = resourceClient.DecodeResource( resourceType, buffer );
*/
static EncodedBufferImagePtr New(const uint8_t * const encodedImage,
const std::size_t encodedImageByteCount,
- const ImageAttributes& attributes,
+ ImageDimensions size = ImageDimensions(0, 0),
+ FittingMode::Type scalingMode = FittingMode::SHRINK_TO_FIT,
+ SamplingMode::Type samplingMode = SamplingMode::BOX,
+ bool orientationCorrection = true,
const ReleasePolicy releasePol=Dali::Image::NEVER);
};
// INTERNAL INCLUDES
#include <dali/public-api/common/dali-common.h>
#include <dali/internal/event/resources/resource-client.h>
-#include <dali/public-api/images/image-attributes.h>
+#include <dali/internal/common/image-attributes.h>
// EXTERNAL INCLUDES
#include <dali/internal/event/common/notification-manager.h>
#include <dali/internal/event/resources/resource-client.h>
#include <dali/internal/update/resources/resource-manager.h>
+#include <dali/internal/common/image-attributes.h>
// EXTERNAL INCLUDES
#include <float.h>
return ticket;
}
- Vector2 size;
- Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().GetClosestImageSize( request.url, *request.attributes, size );
+ ImageDimensions closestSize;
+ if( request.attributes )
+ {
+ closestSize = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().
+ GetClosestImageSize( request.url, ImageDimensions( request.attributes->GetSize().width, request.attributes->GetSize().width ),
+ request.attributes->GetScalingMode(), request.attributes->GetFilterMode(), request.attributes->GetOrientationCorrection() );
+ }
+ else
+ {
+ closestSize = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().GetClosestImageSize( request.url );
+ }
+ Vector2 size( closestSize.GetX(), closestSize.GetY() );
const ImageAttributes& attrib = static_cast<ImageTicket*>(ticket.Get())->GetAttributes();
{
// not loaded so either loading or not yet loaded, ask platform abstraction
Integration::PlatformAbstraction& platformAbstraction = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction();
- platformAbstraction.GetClosestImageSize( GetRequestPath( request ), GetRequestAttributes( request ), size );
+
+ const ImageAttributes& attributes = GetRequestAttributes( request );
+ const ImageDimensions closestSize = platformAbstraction.GetClosestImageSize( GetRequestPath( request ),
+ ImageDimensions( attributes.GetSize().width, attributes.GetSize().width ),
+ attributes.GetScalingMode(), attributes.GetFilterMode(), attributes.GetOrientationCorrection() );
+ size[0] = closestSize.GetX();
+ size[1] = closestSize.GetY();
}
}
mTicketsToRelease.clear();
}
-bool ImageFactory::CompareAttributes( const Dali::ImageAttributes& requested,
- const Dali::ImageAttributes& actual ) const
+bool ImageFactory::CompareAttributes( const ImageAttributes& requested,
+ const ImageAttributes& actual ) const
{
// do not load image resource again if there is a similar resource loaded:
// see explanation in image.h of what is deemed compatible
return (requested.GetScalingMode() == actual.GetScalingMode()) &&
(
(requested.GetFilterMode() == actual.GetFilterMode()) ||
- (requested.GetFilterMode() == ImageAttributes::DontCare)
+ (requested.GetFilterMode() == SamplingMode::DONT_CARE)
) &&
(fabsf(requested.GetWidth() - actual.GetWidth()) <= actual.GetWidth() * mMaxScale) &&
(fabsf(requested.GetHeight() - actual.GetHeight()) <= actual.GetHeight() * mMaxScale);
ResourceTicketPtr ImageFactory::IssueLoadRequest( const std::string& filename, const ImageAttributes* attr )
{
- ImageAttributes attributes;
+ ImageDimensions dimensions;
+ FittingMode::Type fittingMode = FittingMode::DEFAULT;
+ SamplingMode::Type samplingMode = SamplingMode::DEFAULT;
+ bool orientation = true;
if( attr )
{
- attributes = *attr;
+ dimensions = ImageDimensions::FromFloatVec2( attr->GetSize() );
+ fittingMode = attr->GetScalingMode();
+ samplingMode = attr->GetFilterMode();
+ orientation = attr->GetOrientationCorrection();
}
else
{
// query image size from file if NULL was provided
- Vector2 size = Dali::ResourceImage::GetImageSize( filename );
- attributes.SetSize( size.width, size.height );
+ dimensions = Dali::ResourceImage::GetImageSize( filename );
+ ///@ToDo: This is weird and pointless: we introduce a synchronous load of the image header on the event thread here to learn the image's on-disk dimensions to pass on to the resource system,
+ /// but the default behaviour of the resource system when no dimensions are provided is to use exactly these on-disk dimensions when it eventually does the full load and decode.
}
- BitmapResourceType resourceType( attributes );
+ BitmapResourceType resourceType( dimensions, fittingMode, samplingMode, orientation );
ResourceTicketPtr ticket = mResourceClient.RequestResource( resourceType, filename );
return ticket;
}
* @param [in] actual The actual attributes
* @return True if the attributes are compatible
*/
- bool CompareAttributes( const Dali::ImageAttributes& requested,
- const Dali::ImageAttributes& actual ) const;
+ bool CompareAttributes( const ImageAttributes& requested,
+ const ImageAttributes& actual ) const;
/**
* Inserts a new request to the request cache and url cache.
TypeRegistration mType( typeid( Dali::NinePatchImage ), typeid( Dali::Image ), NULL );
} // unnamed namespace
-NinePatchImagePtr NinePatchImage::New( const std::string& filename, const Dali::ImageAttributes& attributes, ReleasePolicy releasePol )
+NinePatchImagePtr NinePatchImage::New( const std::string& filename, const ImageAttributes& attributes, ReleasePolicy releasePol )
{
Internal::NinePatchImagePtr internal( new NinePatchImage( filename, attributes, releasePol ) );
internal->Initialize();
return internal;
}
-NinePatchImage::NinePatchImage( const std::string& filename, const Dali::ImageAttributes& attributes, ReleasePolicy releasePol)
+NinePatchImage::NinePatchImage( const std::string& filename, const ImageAttributes& attributes, ReleasePolicy releasePol )
: ResourceImage( IMAGE_LOAD_POLICY_DEFAULT, releasePol ),
mParsedBorder(false)
{
ThreadLocalStorage& tls = ThreadLocalStorage::Get();
- mResourceClient = &tls.GetResourceClient();
- Integration::PlatformAbstraction& platformAbstraction = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction();
-
- Vector2 closestSize;
- platformAbstraction.GetClosestImageSize( filename, attributes, closestSize );
- ImageAttributes loadedAttrs;
- loadedAttrs.SetSize( closestSize );
- mWidth = closestSize.width;
- mHeight = closestSize.height;
-
- Integration::BitmapResourceType resourceType( loadedAttrs );
+ Integration::PlatformAbstraction& platformAbstraction = tls.GetPlatformAbstraction();
+ Integration::BitmapResourceType resourceType( ImageDimensions::FromFloatVec2( attributes.GetSize() ), attributes.GetScalingMode(), attributes.GetFilterMode(), attributes.GetOrientationCorrection() );
// Note, bitmap is only destroyed when the image is destroyed.
- Integration::ResourcePointer resource = platformAbstraction.LoadResourceSynchronously(resourceType, filename);
+ Integration::ResourcePointer resource = platformAbstraction.LoadResourceSynchronously( resourceType, filename );
if( resource )
{
mBitmap = static_cast<Integration::Bitmap*>( resource.Get());
+ mWidth = mBitmap->GetImageWidth();
+ mHeight = mBitmap->GetImageHeight();
}
else
{
mBitmap.Reset();
+ mWidth = 0;
+ mHeight = 0;
}
}
return image;
}
-ResourceImagePtr ResourceImage::New( const std::string& url, const Dali::ImageAttributes& attributes, LoadPolicy loadPol, ReleasePolicy releasePol )
+ResourceImagePtr ResourceImage::New( const std::string& url, const ImageAttributes& attributes, LoadPolicy loadPol, ReleasePolicy releasePol )
{
ResourceImagePtr image;
if( IsNinePatch( url ) )
return connected;
}
-const Dali::ImageAttributes& ResourceImage::GetAttributes() const
+const ImageAttributes& ResourceImage::GetAttributes() const
{
if( mTicket )
{
* @return a pointer to a newly created object.
*/
static ResourceImagePtr New( const std::string& url,
- const Dali::ImageAttributes& attributes,
+ const ImageAttributes& attributes,
LoadPolicy loadPol = IMAGE_LOAD_POLICY_DEFAULT,
ReleasePolicy releasePol = IMAGE_RELEASE_POLICY_DEFAULT );
* If requested width or height was 0, they are replaced by concrete dimensions.
* @return a copy of the attributes
*/
- const Dali::ImageAttributes& GetAttributes() const;
+ const ImageAttributes& GetAttributes() const;
/**
* @copydoc Dali::ResourceImage::GetUrl()
// CLASS HEADER
#include <dali/internal/event/resources/image-ticket.h>
-#include <dali/public-api/images/image-attributes.h>
namespace Dali
{
// INTERNAL INCLUDES
#include <dali/internal/event/resources/resource-ticket.h>
#include <dali/public-api/images/image.h>
+#include <dali/internal/common/image-attributes.h>
namespace Dali
{
* If requested width or height was 0, they are replaced by concrete dimensions.
* @return a copy of the image attributes
*/
- const Dali::ImageAttributes& GetAttributes() const { return mAttributes;}
+ const ImageAttributes& GetAttributes() const { return mAttributes;}
/**
* Get the width of an image.
* Contains actual values only after the image has finished loading.
* If requested width or height was 0, the natural size is used.
*/
- Dali::ImageAttributes mAttributes;
+ ImageAttributes mAttributes;
/*
* ResourceClient needs to set dimensions and pixelformat.
const BitmapResourceType& bitmapResource = static_cast <const BitmapResourceType&> (type);
// image tickets will cache the requested parameters, which are updated on successful loading
ImageTicket* imageTicket = new ImageTicket(*this, newId, typePath);
- imageTicket->mAttributes = bitmapResource.imageAttributes;
+ imageTicket->mAttributes.Reset( bitmapResource.size, bitmapResource.scalingMode, bitmapResource.samplingMode, bitmapResource.orientationCorrection );
newTicket = imageTicket;
break;
}
const NativeImageResourceType& nativeResource = static_cast <const NativeImageResourceType&> (type);
// image tickets will cache the requested parameters, which are updated on successful loading
ImageTicket* imageTicket = new ImageTicket(*this, newId, typePath);
- imageTicket->mAttributes = nativeResource.imageAttributes;
+ imageTicket->mAttributes.SetSize( nativeResource.imageDimensions.GetWidth(), nativeResource.imageDimensions.GetHeight() );
newTicket = imageTicket;
break;
}
const BitmapResourceType& bitmapResource = static_cast <const BitmapResourceType&> ( type );
// Image tickets will cache the requested parameters, which are updated on successful loading
ImageTicket* imageTicket = new ImageTicket( *this, newId, typePath );
- imageTicket->mAttributes = bitmapResource.imageAttributes;
+ imageTicket->mAttributes.Reset( bitmapResource.size, bitmapResource.scalingMode, bitmapResource.samplingMode, bitmapResource.orientationCorrection );;
newTicket = imageTicket;
break;
}
const ResourceId newId = ++(mImpl->mNextId);
- Dali::ImageAttributes imageAttributes = Dali::ImageAttributes::New(bitmap->GetImageWidth(), bitmap->GetImageHeight());
- BitmapResourceType bitmapResourceType(imageAttributes); // construct first as no copy ctor (needed to bind ref to object)
+ ImageAttributes imageAttributes = ImageAttributes::New(bitmap->GetImageWidth(), bitmap->GetImageHeight());
+ BitmapResourceType bitmapResourceType( ImageDimensions::FromFloatVec2( imageAttributes.GetSize() ) ); // construct first as no copy ctor (needed to bind ref to object)
ResourceTypePath typePath(bitmapResourceType, "");
newTicket = new ImageTicket(*this, newId, typePath);
newTicket->mAttributes = imageAttributes;
const ResourceId newId = ++(mImpl->mNextId);
- Dali::ImageAttributes imageAttributes = Dali::ImageAttributes::New(width, height);
- RenderTargetResourceType renderTargetResourceType(imageAttributes) ; // construct first as no copy ctor (needed to bind ref to object)
+ ImageAttributes imageAttributes = ImageAttributes::New(width, height);
+ RenderTargetResourceType renderTargetResourceType( ImageDimensions( width, height ) ); // construct first as no copy ctor (needed to bind ref to object)
ResourceTypePath typePath(renderTargetResourceType, "");
newTicket = new ImageTicket(*this, newId, typePath);
newTicket->mAttributes = imageAttributes;
const ResourceId newId = ++(mImpl->mNextId);
- Dali::ImageAttributes imageAttributes = Dali::ImageAttributes::New(nativeImage.GetWidth(), nativeImage.GetHeight() );
- RenderTargetResourceType renderTargetResourceType(imageAttributes); // construct first as no copy ctor (needed to bind ref to object)
+ ImageAttributes imageAttributes = ImageAttributes::New( nativeImage.GetWidth(), nativeImage.GetHeight() );
+ RenderTargetResourceType renderTargetResourceType( ImageDimensions( nativeImage.GetWidth(), nativeImage.GetHeight() ) ); // construct first as no copy ctor (needed to bind ref to object)
ResourceTypePath typePath(renderTargetResourceType, "");
newTicket = new ImageTicket(*this, newId, typePath);
newTicket->mAttributes = imageAttributes;
ImageTicketPtr newTicket;
const ResourceId newId = ++(mImpl->mNextId);
- Dali::ImageAttributes imageAttributes = Dali::ImageAttributes::New( width, height);
- BitmapResourceType bitmapResourceType(imageAttributes); // construct first as no copy ctor (needed to bind ref to object)
+ ImageAttributes imageAttributes = ImageAttributes::New( width, height);
+ BitmapResourceType bitmapResourceType( ImageDimensions( width, height ) ); // construct first as no copy ctor (needed to bind ref to object)
ResourceTypePath typePath(bitmapResourceType, "");
newTicket = new ImageTicket(*this, newId, typePath);
}
}
-void ResourceClient::UpdateImageTicket( ResourceId id, const Dali::ImageAttributes& imageAttributes ) ///!< Issue #AHC01
+void ResourceClient::UpdateImageTicket( ResourceId id, const ImageAttributes& imageAttributes ) ///!< Issue #AHC01
{
DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceClient: UpdateImageTicket(id:%u)\n", id);
*/
void NotifySavingFailed( ResourceId id );
- /**
- * Finds ImageTicket which belongs to resource identified by id and updates the cached size and pixelformat
- * with the data from texture.
- * !!! NOTE, this will replace the whole ImageAttributes member of the ticket, not just the three properties mentioned !!!
+ /**
+ * Finds ImageTicket which belongs to resource identified by id and updates the cached
+ * attributes with a new set which contains the actual width and height of the loaded
+ * image but has undefined values for all other fields.
* @param id The resource id to find the ticket of
* @param imageAttributes The image attributes to assign to the ticket
*/
- void UpdateImageTicket( ResourceId id, const Dali::ImageAttributes& imageAttributes ); ///!< Issue #AHC01
+ void UpdateImageTicket( ResourceId id, const ImageAttributes& imageAttributes ); ///!< Issue #AHC01
private:
ResourceManager& mResourceManager; ///< The resource manager
Impl* mImpl;
};
-inline MessageBase* UpdateImageTicketMessage( ResourceClient& client, ResourceId id, const Dali::ImageAttributes& attrs )
+inline MessageBase* UpdateImageTicketMessage( ResourceClient& client, ResourceId id, const ImageAttributes& attrs )
{
- return new MessageValue2< ResourceClient, ResourceId, Dali::ImageAttributes >(
+ return new MessageValue2< ResourceClient, ResourceId, ImageAttributes >(
&client, &ResourceClient::UpdateImageTicket, id, attrs );
}
namespace
{
+/**
+ * @brief Compare two sets of image loading parameters for equality.
+ */
+inline bool AttributesEqual( ImageDimensions aDims, FittingMode::Type aScaling, SamplingMode::Type aSampling, bool aOrient, ImageDimensions bDims, FittingMode::Type bScaling, SamplingMode::Type bSampling, bool bOrient )
+{
+ return aDims == bDims &&
+ aScaling == bScaling &&
+ aSampling == bSampling &&
+ aOrient == bOrient;
+}
+
+/**
+ * @brief Compare two sets of image loading parameters
+ * @pre The two sets are not identical.
+ */
+inline bool AttributesLessAssumingNotEqual( ImageDimensions aDims, FittingMode::Type aScaling, SamplingMode::Type aSampling, bool aOrient, ImageDimensions bDims, FittingMode::Type bScaling, SamplingMode::Type bSampling, bool bOrient )
+{
+ return aDims < bDims &&
+ aScaling < bScaling &&
+ aSampling < bSampling &&
+ aOrient < bOrient;
+}
+
/**
* Compare two resource types.
* @return zero if the types are equal,
const BitmapResourceType& lhsBitmap = static_cast<const BitmapResourceType&>(lhs);
const BitmapResourceType& rhsBitmap = static_cast<const BitmapResourceType&>(rhs);
- if (lhsBitmap.imageAttributes != rhsBitmap.imageAttributes)
+ if( ! AttributesEqual( lhsBitmap.size, lhsBitmap.scalingMode, lhsBitmap.samplingMode, lhsBitmap.orientationCorrection,
+ rhsBitmap.size, rhsBitmap.scalingMode, rhsBitmap.samplingMode, rhsBitmap.orientationCorrection ) )
{
- result = lhsBitmap.imageAttributes < rhsBitmap.imageAttributes ? -1 : 1;
+ result = AttributesLessAssumingNotEqual( lhsBitmap.size, lhsBitmap.scalingMode, lhsBitmap.samplingMode, lhsBitmap.orientationCorrection,
+ rhsBitmap.size, rhsBitmap.scalingMode, rhsBitmap.samplingMode, rhsBitmap.orientationCorrection );
}
// else result = 0
break;
const NativeImageResourceType& lhsNativeImage = static_cast<const NativeImageResourceType&>(lhs);
const NativeImageResourceType& rhsNativeImage = static_cast<const NativeImageResourceType&>(rhs);
- if (lhsNativeImage.imageAttributes != rhsNativeImage.imageAttributes)
+ if (lhsNativeImage.imageDimensions != rhsNativeImage.imageDimensions)
{
- result = lhsNativeImage.imageAttributes < rhsNativeImage.imageAttributes ? -1 : 1;
+ result = lhsNativeImage.imageDimensions < rhsNativeImage.imageDimensions ? -1 : 1;
}
// else result = 0
break;
const RenderTargetResourceType& lhsImage = static_cast<const RenderTargetResourceType&>(lhs);
const RenderTargetResourceType& rhsImage = static_cast<const RenderTargetResourceType&>(rhs);
- if (lhsImage.imageAttributes != rhsImage.imageAttributes)
+ if (lhsImage.imageDimensions != rhsImage.imageDimensions)
{
- result = lhsImage.imageAttributes < rhsImage.imageAttributes ? -1 : 1;
+ result = lhsImage.imageDimensions < rhsImage.imageDimensions ? -1 : 1;
}
// else result = 0
break;
$(internal_src_dir)/common/internal-constants.cpp \
$(internal_src_dir)/common/message-buffer.cpp \
$(internal_src_dir)/common/image-sampler.cpp \
+ $(internal_src_dir)/common/image-attributes.cpp \
$(internal_src_dir)/common/fixed-size-memory-pool.cpp \
\
$(internal_src_dir)/event/actor-attachments/actor-attachment-impl.cpp \
#include <dali/public-api/common/map-wrapper.h>
#include <dali/public-api/common/set-wrapper.h>
#include <dali/public-api/math/vector2.h>
-#include <dali/public-api/images/image-attributes.h>
#include <dali/integration-api/debug.h>
#include <dali/internal/common/message.h>
+#include <dali/internal/common/image-attributes.h>
#include <dali/internal/event/common/notification-manager.h>
#include <dali/internal/event/resources/resource-type-path.h>
namespace Internal
{
+class ImageAttributes;
+
// value types used by messages
template <> struct ParameterType< Integration::LoadResourcePriority >
: public BasicType< Integration::LoadResourcePriority > {};
#include <dali/public-api/images/distance-field.h>
#include <dali/public-api/images/encoded-buffer-image.h>
#include <dali/public-api/images/frame-buffer-image.h>
-#include <dali/public-api/images/image-attributes.h>
#include <dali/public-api/images/image.h>
+#include <dali/public-api/images/image-operations.h>
#include <dali/public-api/images/native-image-interface.h>
#include <dali/public-api/images/native-image.h>
#include <dali/public-api/images/resource-image.h>
#include <dali/public-api/math/radian.h>
#include <dali/public-api/math/random.h>
#include <dali/public-api/math/rect.h>
+#include <dali/public-api/math/uint-16-pair.h>
#include <dali/public-api/math/vector2.h>
#include <dali/public-api/math/vector3.h>
#include <dali/public-api/math/vector4.h>
$(public_api_src_dir)/images/atlas.cpp \
$(public_api_src_dir)/images/distance-field.cpp \
$(public_api_src_dir)/images/image.cpp \
- $(public_api_src_dir)/images/image-attributes.cpp \
$(public_api_src_dir)/images/pixel.cpp \
$(public_api_src_dir)/images/buffer-image.cpp \
$(public_api_src_dir)/images/frame-buffer-image.cpp \
$(public_api_src_dir)/images/encoded-buffer-image.h \
$(public_api_src_dir)/images/frame-buffer-image.h \
$(public_api_src_dir)/images/image.h \
- $(public_api_src_dir)/images/image-attributes.h \
+ $(public_api_src_dir)/images/image-operations.h \
$(public_api_src_dir)/images/native-image-interface.h \
$(public_api_src_dir)/images/nine-patch-image.h \
$(public_api_src_dir)/images/pixel.h \
$(public_api_src_dir)/math/radian.h \
$(public_api_src_dir)/math/random.h \
$(public_api_src_dir)/math/rect.h \
+ $(public_api_src_dir)/math/uint-16-pair.h \
$(public_api_src_dir)/math/vector2.h \
$(public_api_src_dir)/math/vector3.h \
$(public_api_src_dir)/math/vector4.h \
$(public_api_src_dir)/math/viewport.h
+
public_api_core_modeling_header_files = \
$(public_api_src_dir)/modeling/bone.h \
$(public_api_src_dir)/modeling/material.h
// INTERNAL INCLUDES
#include <dali/integration-api/debug.h>
#include <dali/public-api/common/dali-common.h>
+#include <dali/internal/common/image-attributes.h>
#include <dali/internal/event/images/encoded-buffer-image-impl.h>
namespace Dali
{
}
-EncodedBufferImage EncodedBufferImage::New(const uint8_t * const encodedImage, const std::size_t encodedImageByteCount, const ImageAttributes& attributes, const ReleasePolicy releasePol)
+EncodedBufferImage EncodedBufferImage::New( const uint8_t * const encodedImage,
+ std::size_t encodedImageByteCount,
+ ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode,
+ ReleasePolicy releasePol,
+ bool orientationCorrection )
{
- Internal::EncodedBufferImagePtr internal=Internal::EncodedBufferImage::New(encodedImage, encodedImageByteCount, attributes, releasePol);
+ Internal::EncodedBufferImagePtr internal = Internal::EncodedBufferImage::New( encodedImage, encodedImageByteCount, size, fittingMode, samplingMode, orientationCorrection, releasePol );
EncodedBufferImage image(internal.Get());
return image;
}
-EncodedBufferImage EncodedBufferImage::New(const uint8_t * const encodedImage, const std::size_t encodedImageByteCount)
+EncodedBufferImage EncodedBufferImage::New( const uint8_t * const encodedImage, const std::size_t encodedImageByteCount )
{
- ImageAttributes attributes;
- Internal::EncodedBufferImagePtr internal = Internal::EncodedBufferImage::New(encodedImage, encodedImageByteCount, attributes, Dali::Image::NEVER);
+ ImageDimensions size(0, 0);
+ FittingMode::Type fittingMode = FittingMode::DEFAULT;
+ SamplingMode::Type samplingMode = SamplingMode::DEFAULT;
+ Internal::EncodedBufferImagePtr internal = Internal::EncodedBufferImage::New( encodedImage, encodedImageByteCount, size, fittingMode, samplingMode, true, Dali::Image::NEVER );
EncodedBufferImage image( internal.Get() );
return image;
}
{
}
-EncodedBufferImage::EncodedBufferImage(const EncodedBufferImage& handle)
+EncodedBufferImage::EncodedBufferImage( const EncodedBufferImage& handle )
: Image(handle)
{
}
-EncodedBufferImage& EncodedBufferImage::operator=(const EncodedBufferImage& rhs)
+EncodedBufferImage& EncodedBufferImage::operator=( const EncodedBufferImage& rhs )
{
BaseHandle::operator=(rhs);
return *this;
// INTERNAL INCLUDES
#include <dali/public-api/images/image.h>
-#include <dali/public-api/images/image-attributes.h>
+#include <dali/public-api/images/image-operations.h>
+#include <dali/public-api/math/uint-16-pair.h>
namespace Dali
{
class EncodedBufferImage;
}
+typedef Uint16Pair ImageDimensions;
+
/**
* @brief EncodedBufferImage represents an image resource that can be added to
* discard it as soon as the function returns.
* @param [in] encodedImageByteCount The size in bytes of the buffer pointed to
* by encodedImage.
- * @param [in] attributes Requested parameters for loading (size, scaling etc.).
+ * @param [in] size The width and height to fit the loaded image to.
+ * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
+ * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
* @param [in] releasePol The ReleasePolicy to apply to Image. If the Unused
+ * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
* policy is set, a reload will not be possible, so the Image should never be
* used once all actors using it have gone off-stage.
* @return A handle to a newly allocated object.
*/
- static EncodedBufferImage New(const uint8_t * const encodedImage, std::size_t encodedImageByteCount, const ImageAttributes& attributes, ReleasePolicy releasePol = Image::NEVER);
+ static EncodedBufferImage New( const uint8_t * const encodedImage, std::size_t encodedImageByteCount, ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, ReleasePolicy releasePol = Image::NEVER, bool orientationCorrection = true );
/**
* @brief Create an initialised image object from an encoded image buffer in memory.
* by encodedImage.
* @return A handle to a newly allocated object.
*/
- static EncodedBufferImage New(const uint8_t * const encodedImage, std::size_t encodedImageByteCount);
+ static EncodedBufferImage New( const uint8_t * const encodedImage, std::size_t encodedImageByteCount );
/**
* @brief Downcast an Object handle to EncodedBufferImage.
+++ /dev/null
-/*
- * Copyright (c) 2014 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/public-api/images/image-attributes.h>
-
-// EXTERNAL INCLUDES
-#include <cmath>
-
-namespace Dali
-{
-
-const ImageAttributes ImageAttributes::DEFAULT_ATTRIBUTES;
-
-struct ImageAttributes::ImageAttributesImpl
-{
- ImageAttributesImpl()
- : width(0),
- height(0),
- scaling(ShrinkToFit),
- filtering(Box),
- mOrientationCorrection(false)
- {
- }
-
- ~ImageAttributesImpl()
- {
- }
-
- ImageAttributesImpl(const ImageAttributesImpl& rhs)
- : width( rhs.width ),
- height( rhs.height ),
- scaling( rhs.scaling ),
- filtering( rhs.filtering ),
- mOrientationCorrection( rhs.mOrientationCorrection )
- {
- }
-
- ImageAttributesImpl& operator=(const ImageAttributesImpl& rhs)
- {
- if (this != &rhs)
- {
- width = rhs.width;
- height = rhs.height;
- scaling = rhs.scaling;
- filtering = rhs.filtering;
-
- mOrientationCorrection = rhs.mOrientationCorrection;
- }
-
- return *this;
- }
-
- unsigned int width : 16; ///< image width in pixels
- unsigned int height : 16; ///< image height in pixels
- ScalingMode scaling : 3; ///< scaling option, ShrinkToFit is default
- FilterMode filtering : 3; ///< filtering option. Box is the default
- bool mOrientationCorrection : 1; ///< If true, image pixels are reordered according to orientation metadata on load.
- bool isDistanceField : 1; ///< true, if the image is a distancefield. Default is false.
-};
-
-
-ImageAttributes::ImageAttributes()
-: impl( new ImageAttributesImpl() )
-{
-}
-
-ImageAttributes::ImageAttributes(const ImageAttributes& rhs)
-: impl( new ImageAttributesImpl(*rhs.impl) )
-{
-}
-
-ImageAttributes& ImageAttributes::operator=(const ImageAttributes& rhs)
-{
- *impl = *rhs.impl;
-
- return *this;
-}
-
-ImageAttributes::~ImageAttributes()
-{
- delete impl;
-}
-
-void ImageAttributes::SetSize(unsigned int width, unsigned int height)
-{
- impl->width = width;
- impl->height = height;
-}
-
-void ImageAttributes::SetSize( const Size& size )
-{
- impl->width = size.width;
- impl->height = size.height;
-}
-
-void ImageAttributes::SetScalingMode(ScalingMode scale)
-{
- impl->scaling = scale;
-}
-
-void ImageAttributes::SetFilterMode( FilterMode filtering )
-{
- impl->filtering = filtering;
-}
-
-void ImageAttributes::SetOrientationCorrection(const bool enabled)
-{
- impl->mOrientationCorrection = enabled;
-}
-
-unsigned int ImageAttributes::GetWidth() const
-{
- return impl->width;
-}
-
-unsigned int ImageAttributes::GetHeight() const
-{
- return impl->height;
-}
-
-Size ImageAttributes::GetSize() const
-{
- return Size(impl->width, impl->height);
-}
-
-ImageAttributes::ScalingMode ImageAttributes::GetScalingMode() const
-{
- return impl->scaling;
-}
-
-ImageAttributes::FilterMode ImageAttributes::GetFilterMode() const
-{
- return impl->filtering;
-}
-
-bool ImageAttributes::GetOrientationCorrection() const
-{
- return impl->mOrientationCorrection;
-}
-
-ImageAttributes ImageAttributes::New()
-{
- return ImageAttributes();
-}
-
-ImageAttributes ImageAttributes::New(unsigned int imageWidth, unsigned int imageHeight)
-{
- ImageAttributes attributes;
- attributes.impl->width = imageWidth;
- attributes.impl->height = imageHeight;
- return attributes;
-}
-
-/**
- * Less then comparison operator.
- * @param [in] a parameter tested
- * @param [in] b parameter tested
- */
-bool operator<(const ImageAttributes& a, const ImageAttributes& b)
-{
- // Bail out if one is distance field and the other is not.
- if (a.impl->isDistanceField != b.impl->isDistanceField)
- {
- return a.impl->isDistanceField < b.impl->isDistanceField;
- }
-
- if (a.impl->width != b.impl->width)
- {
- return a.impl->width < b.impl->width;
- }
-
- if (a.impl->height != b.impl->height)
- {
- return a.impl->height < b.impl->height;
- }
-
- if (a.impl->mOrientationCorrection != b.impl->mOrientationCorrection)
- {
- return a.impl->mOrientationCorrection < b.impl->mOrientationCorrection;
- }
-
- if (a.impl->scaling != b.impl->scaling)
- {
- return a.impl->scaling < b.impl->scaling;
- }
-
- if (a.impl->filtering != b.impl->filtering)
- {
- return a.impl->filtering < b.impl->filtering;
- }
-
- // they are equal
- return false;
-}
-
-/**
- * Equal to comparison operator.
- * @param [in] a parameter tested for equality
- * @param [in] b parameter tested for equality
- */
-bool operator==(const ImageAttributes& a, const ImageAttributes& b)
-{
- return a.impl->width == b.impl->width &&
- a.impl->height == b.impl->height &&
- a.impl->mOrientationCorrection == b.impl->mOrientationCorrection &&
- a.impl->scaling == b.impl->scaling &&
- a.impl->filtering == b.impl->filtering;
-}
-
-/**
- * Not equal to comparison operator.
- * @param [in] a parameter tested for equality
- * @param [in] b parameter tested for equality
- */
-bool operator!=(const ImageAttributes& a, const ImageAttributes& b)
-{
- return !(a == b);
-}
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_IMAGE_ATTRIBUTES_H__
-#define __DALI_IMAGE_ATTRIBUTES_H__
-
-/*
- * Copyright (c) 2014 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/public-api/images/pixel.h>
-#include <dali/public-api/math/rect.h>
-#include <dali/public-api/math/vector2.h>
-
-namespace Dali
-{
-
-class ImageAttributes;
-
-/**
- * @brief Describes Image properties like dimensions and pixel format and
- * operations to be applied to images during the load process.
- *
- * ImageAttributes is used to define a set of properties of an image and a
- * sequence of operations to be applied when loading it.
- *
- * The overall order of operations which can be applied is:
- * 1. Determine the desired dimensions for the final bitmap.
- * 2. Scale the image to fit the desired dimensions.
- *
- * The default for each stage is to do nothing.
- * To enable a calculation of desired final image dimensions and fitting to it, SetSize() must be called.
- *
- * The loader does not guarantee to rescale a loaded image to the exact desired dimensions, but it will make a best effort to downscale images.
- * The fitting to destination dimensions controlled by the ScalingMode may choose to fit to a larger area with an equivalent aspect ratio.
- * If the requested dimensions are larger than the loaded ones, it will never upscale on load to fill them but will instead fit to smaller dimensions of identical aspect ratio.
- * This is transparent to an application as the upscaling can happen during rendering.
- *
- * To enable scaling of images on load, desired dimensions must be set using SetSize().
- * Only one of the dimensions need be supplied, in which case, the other is calculated based on the aspect ratio of the raw loaded image.
- * The desired dimensions 2-tuple 'd' is determined as follows for loaded image dimensions 'l' and 's', the dimensions tuple set with SetSize():
- * * `d = s, if s.x != 0 & s.y != 0, else:`
- * * `d = [s.x, s.x * (l.y / l.x)], if s.x != 0 & s.y = 0, else:`
- * * `d = [s.y * (l.x / l.y), s.y], if s.x = 0 & s.y != 0, else:`
- * * `d = l, otherwise.`
- *
- * Use cases for scaling images on load include:
- * 1. Full-screen image display: Limit loaded image resolution to device resolution using ShrinkToFit mode.
- * 2. Thumbnail gallery grid: Limit loaded image resolution to screen tile using ScaleToFill mode.
- * 3. Image columns: Limit loaded image resolution to column width using FitWidth mode.
- * 4. Image rows: Limit loaded image resolution to row height using FitHeight mode.
- *
- * @note The aspect ratio of image contents is preserved by all scaling modes, so for example squares in input images stay square after loading.
- */
-class DALI_IMPORT_API ImageAttributes
-{
-public:
-
- /**
- * @brief Scaling options, used when resizing images on load to fit desired dimensions.
- *
- * A scaling mode controls the region of a loaded image to be mapped to the
- * desired image rectangle specified using ImageAttributes.SetSize().
- * All scaling modes preserve the aspect ratio of the image contents.
- */
- enum ScalingMode
- {
- ShrinkToFit, ///< Fit full image inside desired width & height, potentially not filling one of either the desired image width or height with pixels.
- ScaleToFill, ///< Image fills whole desired width & height with image data. The image is centred in the desired dimensions, exactly touching in one dimension, with image regions outside the other desired dimension cropped away.
- FitWidth, ///< Image fills whole width. Height is scaled proportionately to maintain aspect ratio.
- FitHeight ///< Image fills whole height. Width is scaled proportionately to maintain aspect ratio.
- };
-
- /**
- * @brief Filtering options, used when resizing images on load to sample original pixels.
- *
- * A FilterMode controls how pixels in the raw image on-disk are sampled and
- * combined to generate each pixel of the destination loaded image.
- *
- * @note NoFilter and Box modes do not guarantee that the loaded pixel array
- * exactly matches the rectangle specified by the desired dimensions and
- * ScalingMode, but all other filter modes do if the desired dimensions are
- * `<=` the raw dimensions of the image file.
- */
- enum FilterMode
- {
- Box, ///< Iteratively box filter to generate an image of 1/2, 1/4, 1/8, ... width and height and
- /// approximately the desired size, then if the ScaleToFill scaling mode is enabled, cut away the
- /// top/bottom or left/right borders of the image to match the aspect ratio of desired dimensions.
- /// This is the default.
- Nearest, ///< For each output pixel, read one input pixel.
- Linear, ///< For each output pixel, read a quad of four input pixels and write a weighted average of them.
- BoxThenNearest, ///< Iteratively box filter to generate an image of 1/2, 1/4, 1/8, ... width and height and
- /// approximately the desired size, then for each output pixel, read one pixel from the last level
- /// of box filtering.
- BoxThenLinear, ///< Iteratively box filter to almost the right size, then for each output pixel, read four pixels
- /// from the last level of box filtering and write their weighted average.
- NoFilter, ///< No filtering is performed. If the ScaleToFill scaling mode is enabled, the borders of the
- /// image may be trimmed to match the aspect ratio of the desired dimensions.
- DontCare ///< For when the client strongly prefers a cache-hit. Defaults to Box.
- };
-
- static const ImageAttributes DEFAULT_ATTRIBUTES; ///< Default attributes have no size
-
- /**
- * @brief Default constructor, initializes to default values.
- */
- ImageAttributes();
-
- /**
- * @brief This copy constructor is required for correctly copying internal implementation.
- *
- * @param [in] rhs A reference to the copied handle
- */
- ImageAttributes(const ImageAttributes& rhs);
-
- /**
- * @brief This assignment operator is required for correctly handling the internal implementation.
- *
- * @param [in] rhs A reference to the copied handle
- * @return a reference to this object
- */
- ImageAttributes& operator=(const ImageAttributes& rhs);
-
- /**
- * @brief Default destructor.
- */
- ~ImageAttributes();
-
- /**
- * @brief Create an initialised image attributes object.
- *
- * @return A handle to a newly allocated object
- */
- static ImageAttributes New();
-
- /**
- * @brief Create an initialised image attributes object.
- *
- * @param [in] width desired width.
- * @param [in] height desired height
- * @return A handle to a newly allocated object
- */
- static ImageAttributes New(unsigned int width, unsigned int height);
-
- /**
- * @brief Set the size properties.
- *
- * By default width and height are set to zero which means the image loaded has the original size.
- * If one dimension is set to non-zero, but the other zeroed, the unspecified one is derived from
- * the one that is set and the aspect ratio of the image.
- *
- * @param [in] width desired width.
- * @param [in] height desired height
- */
- void SetSize(unsigned int width, unsigned int height);
-
- /**
- * @brief Set the image dimension properties.
- *
- * By default, width and height are set to zero which means the image loaded has the original size.
- * If one dimension is set to non-zero, but the other zeroed, the unspecified one is derived from
- * the one that is set and the aspect ratio of the image.
- *
- * @param [in] size desired size.
- */
- void SetSize( const Size& size );
-
- /**
- * @brief Set the scale field of the image attributes.
- *
- * By default, ShrinkToFit is set.
- * @param [in] scalingMode The desired scaling mode
- */
- void SetScalingMode(ScalingMode scalingMode);
-
- /**
- * @brief Setter for the FilterMode.
- * By default, Box is set.
- * @param [in] filterMode The desired filter mode.
- */
- void SetFilterMode( FilterMode filterMode );
-
- /**
- * @brief Set whether the image will be rotated/flipped back into portrait orientation.
- *
- * This will only be necessary if metadata indicates that the
- * image has a different viewing orientation.
- *
- * This metadata, optionally present in formats that use exif for example,
- * can encode the physical orientation of the camera which took the picture,
- * establishing which directions in the image correspond to real-world "up"
- * and the horizon.
- * By default the metadata is ignored, but if this function is called with
- * the value "true", the pixels of an image are reordered at load time to reflect
- * the orientation in the metadata.
- *
- * @param [in] enabled If true, the image orientation metadata will be used to
- * transform the pixels of the image as laid-out in memory.
- */
- void SetOrientationCorrection(bool enabled);
-
-
- /**
- * @brief Return the width currently represented by the attribute.
- *
- * @return width
- */
- unsigned int GetWidth() const;
-
- /**
- * @brief Return the height currently represented by the attribute.
- *
- * @return height
- */
- unsigned int GetHeight() const;
-
- /**
- * @brief Return the size currently represented by the attribute.
- *
- * @return size
- */
- Size GetSize() const;
-
- /**
- * @brief Return the scale currently represented by the attribute.
- *
- * @return scale
- */
- ScalingMode GetScalingMode() const;
-
- /**
- * @brief Getter for the FilterMode
- *
- * @return The FilterMode previously set, or the default value if none has
- * been.
- */
- FilterMode GetFilterMode() const;
-
- /**
- * @brief Whether to correct for physical orientation of an image.
- *
- * @return Whether image pixels should be transformed according to the
- * orientation metadata, if any.
- */
- bool GetOrientationCorrection() const;
-
- /**
- * @brief Less then comparison operator.
- *
- * @param [in] a parameter tested
- * @param [in] b parameter tested
- * @return true if a is less than b
- */
- friend bool operator<(const ImageAttributes& a, const ImageAttributes& b);
-
- /**
- * @brief Equal to comparison operator.
- *
- * @param [in] a parameter tested for equality
- * @param [in] b parameter tested for equality
- * @return true if a is equal to b
- */
- friend bool operator==(const ImageAttributes& a, const ImageAttributes& b);
-
- /**
- * @brief Not equal to comparison operator.
- *
- * @param [in] a parameter tested for equality
- * @param [in] b parameter tested for equality
- * @return true if a is not equal to b
- */
- friend bool operator!=(const ImageAttributes& a, const ImageAttributes& b);
-
-private:
- struct ImageAttributesImpl;
- ImageAttributesImpl* impl; ///< Implementation pointer
-};
-
-/**
- * @brief Less then comparison operator.
- *
- * @param [in] a parameter tested
- * @param [in] b parameter tested
- * @return true if a is less than b
- */
-DALI_IMPORT_API bool operator<(const ImageAttributes& a, const ImageAttributes& b);
-
-/**
- * @brief Equal to comparison operator.
- *
- * @param [in] a parameter tested for equality
- * @param [in] b parameter tested for equality
- * @return true if a is equal to b
- */
-DALI_IMPORT_API bool operator==(const ImageAttributes& a, const ImageAttributes& b);
-
-/**
- * @brief Not equal to comparison operator.
- *
- * @param [in] a parameter tested for equality
- * @param [in] b parameter tested for equality
- * @return true if a is not equal to b
- */
-DALI_IMPORT_API bool operator!=(const ImageAttributes& a, const ImageAttributes& b);
-
-} // namespace Dali
-
-#endif // __DALI_IMAGE_ATTRIBUTES_H__
--- /dev/null
+#ifndef __DALI_IMAGE_OPERATIONS_H__
+#define __DALI_IMAGE_OPERATIONS_H__
+
+/*
+ * Copyright (c) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+
+// INTERNAL INCLUDES
+#include <dali/public-api/math/uint-16-pair.h>
+
+namespace Dali
+{
+
+/**
+ * @brief The integer dimensions of an image or a region of an image packed into
+ * 16 bits per component.
+ *
+ * This can only be used for images of up to 65535 x 65535 pixels.
+ */
+typedef Uint16Pair ImageDimensions;
+
+/**
+ * @brief Fitting options, used when resizing images to fit desired dimensions.
+ *
+ * A fitting mode controls the region of a loaded image to be mapped to the
+ * desired image rectangle.
+ * All fitting modes preserve the aspect ratio of the image contents.
+ */
+namespace FittingMode
+{
+ enum Type
+ {
+ SHRINK_TO_FIT, ///< Fit full image inside desired width & height, potentially not
+ /// filling one of either the desired image width or height with
+ /// pixels.
+ SCALE_TO_FILL, ///< Image fills whole desired width & height with image data. The
+ /// image is centred in the desired dimensions, exactly touching
+ /// in one dimension, with image regions outside the other desired
+ /// dimension cropped away.
+ FIT_WIDTH, ///< Image fills whole width. Height is scaled proportionately to
+ /// maintain aspect ratio.
+ FIT_HEIGHT ///< Image fills whole height. Width is scaled proportionately to
+ /// maintain aspect ratio.
+ };
+ const Type DEFAULT = SHRINK_TO_FIT;
+}
+
+/**
+ * @brief Filtering options, used when resizing images to sample original pixels.
+ *
+ * A SamplingMode controls how pixels in an input image are sampled and
+ * combined to generate each pixel of a destination image during a scaling.
+ *
+ * NoFilter and Box modes do not guarantee that the output pixel array
+ * exactly matches the rectangle specified by the desired dimensions and
+ * FittingMode, but all other filter modes do if the desired dimensions are
+ * `<=` the raw dimensions of the input image file.
+ */
+namespace SamplingMode
+{
+ enum Type
+ {
+ BOX, ///< Iteratively box filter to generate an image of 1/2, 1/4,
+ /// 1/8, etc width and height and approximately the desired
+ /// size. This is the default.
+ NEAREST, ///< For each output pixel, read one input pixel.
+ LINEAR, ///< For each output pixel, read a quad of four input pixels
+ /// and write a weighted average of them.
+ BOX_THEN_NEAREST, ///< Iteratively box filter to generate an image of 1/2, 1/4,
+ /// 1/8 etc width and height and approximately the desired
+ /// size, then for each output pixel, read one pixel from the
+ /// last level of box filtering.
+ BOX_THEN_LINEAR, ///< Iteratively box filter to almost the right size, then for
+ /// each output pixel, read four pixels from the last level of
+ /// box filtering and write their weighted average.
+ NO_FILTER, ///< No filtering is performed. If the SCALE_TO_FILL scaling mode
+ /// is enabled, the borders of the image may be trimmed to
+ /// match the aspect ratio of the desired dimensions.
+ DONT_CARE ///< For caching algorithms where a client strongly prefers a
+ /// cache-hit to reuse a cached image.
+ };
+ const Type DEFAULT = BOX;
+}
+
+} // namespace Dali
+
+#endif // __DALI_IMAGE_OPERATIONS_H__
#include <dali/public-api/images/nine-patch-image.h>
// INTERNAL INCLUDES
-#include <dali/public-api/images/image-attributes.h>
+#include <dali/internal/common/image-attributes.h>
#include <dali/public-api/math/vector2.h>
#include <dali/internal/event/images/nine-patch-image-impl.h>
NinePatchImage NinePatchImage::New( const std::string& filename )
{
- ImageAttributes defaultAttrs;
+ Internal::ImageAttributes defaultAttrs;
Internal::NinePatchImagePtr internal = Internal::NinePatchImage::New( filename, defaultAttrs, Image::NEVER );
return NinePatchImage(internal.Get());
#include <dali/public-api/images/resource-image.h>
// INTERNAL INCLUDES
-#include <dali/public-api/images/image-attributes.h>
-#include <dali/public-api/math/vector2.h>
+#include <dali/internal/common/image-attributes.h>
#include <dali/internal/event/images/resource-image-impl.h>
#include <dali/internal/event/common/thread-local-storage.h>
#include <dali/integration-api/platform-abstraction.h>
namespace Dali
{
-Vector2 ResourceImage::GetImageSize( const std::string& url )
+ImageDimensions ResourceImage::GetImageSize( const std::string& url )
{
- Vector2 size;
- Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().GetClosestImageSize( url, ImageAttributes::DEFAULT_ATTRIBUTES, size );
+ const Internal::ImageAttributes& attribs = Internal::ImageAttributes::DEFAULT_ATTRIBUTES;
+ const ImageDimensions desiredSize = ImageDimensions( attribs.GetWidth(), attribs.GetHeight() );
+ const ImageDimensions size = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().GetClosestImageSize( url, desiredSize, attribs.GetScalingMode(), attribs.GetFilterMode(), attribs.GetOrientationCorrection() );
return size;
}
return *this;
}
-ResourceImage ResourceImage::New( const std::string& url )
+ResourceImage ResourceImage::New( const std::string& url, bool orientationCorrection )
{
- Internal::ResourceImagePtr internal = Internal::ResourceImage::New( url,
- Dali::ImageAttributes::DEFAULT_ATTRIBUTES );
- return ResourceImage(internal.Get());
+ Internal::ImageAttributes attributes = Internal::ImageAttributes::DEFAULT_ATTRIBUTES;
+ attributes.SetOrientationCorrection( orientationCorrection );
+ return ResourceImage( Internal::ResourceImage::New( url, attributes ).Get() );
}
-ResourceImage ResourceImage::New( const std::string& url, LoadPolicy loadPol, ReleasePolicy releasePol )
+ResourceImage ResourceImage::New( const std::string& url, LoadPolicy loadPol, ReleasePolicy releasePol, bool orientationCorrection )
{
- Internal::ResourceImagePtr internal = Internal::ResourceImage::New( url,
- Dali::ImageAttributes::DEFAULT_ATTRIBUTES,
- loadPol, releasePol );
- return ResourceImage(internal.Get());
+ Internal::ImageAttributes attributes = Internal::ImageAttributes::DEFAULT_ATTRIBUTES;
+ attributes.SetOrientationCorrection( orientationCorrection );
+ return ResourceImage( Internal::ResourceImage::New( url, attributes, loadPol, releasePol ).Get() );
}
-ResourceImage ResourceImage::New( const std::string& url, const ImageAttributes& attributes )
+ResourceImage ResourceImage::New( const std::string& url, ImageDimensions size, FittingMode::Type scalingMode, SamplingMode::Type samplingMode, bool orientationCorrection )
{
- Internal::ResourceImagePtr internal = Internal::ResourceImage::New( url, attributes );
- return ResourceImage(internal.Get());
+ Internal::ImageAttributes attributes = Internal::ImageAttributes::DEFAULT_ATTRIBUTES;
+ attributes.SetSize( Size( size.GetWidth(), size.GetHeight() ) );
+ attributes.SetScalingMode( scalingMode );
+ attributes.SetFilterMode( samplingMode );
+ attributes.SetOrientationCorrection( orientationCorrection );
+ return ResourceImage( Internal::ResourceImage::New( url, attributes ).Get() );
}
-ResourceImage ResourceImage::New( const std::string& url, const ImageAttributes& attributes, LoadPolicy loadPol, ReleasePolicy releasePol )
+ResourceImage ResourceImage::New( const std::string& url, LoadPolicy loadPol, ReleasePolicy releasePol, ImageDimensions size, FittingMode::Type scalingMode, SamplingMode::Type samplingMode, bool orientationCorrection )
{
- Internal::ResourceImagePtr internal = Internal::ResourceImage::New( url, attributes, loadPol, releasePol );
- return ResourceImage(internal.Get());
+ Internal::ImageAttributes attributes = Internal::ImageAttributes::DEFAULT_ATTRIBUTES;
+ attributes.SetSize( Size( size.GetWidth(), size.GetHeight() ) );
+ attributes.SetScalingMode( scalingMode );
+ attributes.SetFilterMode( samplingMode );
+ attributes.SetOrientationCorrection( orientationCorrection );
+ return ResourceImage( Internal::ResourceImage::New( url, attributes, loadPol, releasePol ).Get() );
}
ResourceImage ResourceImage::DownCast( BaseHandle handle )
GetImplementation(*this).Reload();
}
-ImageAttributes ResourceImage::GetAttributes() const
-{
- return GetImplementation(*this).GetAttributes();
-}
-
ResourceImage::ResourceImageSignal& ResourceImage::LoadingFinishedSignal()
{
return GetImplementation(*this).LoadingFinishedSignal();
#include <dali/public-api/common/loading-state.h>
#include <dali/public-api/images/image.h>
#include <dali/public-api/signals/dali-signal.h>
+#include <dali/public-api/images/image-operations.h>
namespace Dali
{
-struct Vector2;
-class ImageAttributes;
namespace Internal DALI_INTERNAL
{
* the ResourceImage is created with IMMEDIATE loading policy or a compatible resource is found in cache.
* In case of loading images ON_DEMAND, resource loading will only be attempted if the associated ImageActor
* is put on Stage.
- * Custom loading requests can be made by providing an ImageAttributes object to ResourceImage::New().
+ * Scaling of images to a desired smaller size can be requested by providing desired dimensions,
+ * scaling mode and filter mode to to ResourceImage::New().
*
* <i>LoadPolicies</i>
* - IMMEDIATE: acquire image resource when creating ResourceImage.
* If the same image is created more than once with conflicting policies, LoadPolicy "IMMEDIATE" overrides "ON_DEMAND".
*
* <i>Custom load requests</i>
- * Size, scaling mode, orientation compensation can be set when requesting an image.
- * See ImageAttributes for more details.
+ * Size, scaling mode, filter mode, and orientation compensation can be set when requesting an image.
*
* <i>Compatible resources</i>
*
* Before loading a new ResourceImage the internal image resource cache is checked by dali.
* If there is an image already loaded in memory and is deemed "compatible" with the requested image,
* that resource is reused.
- * This happens for example if a loaded image exists with the same URL, and the difference between both
- * of the dimensions is less than 50%.
+ * This happens for example if a loaded image exists with the same URL, scaling and filtering modes,
+ * and the difference between both of the dimensions is less than a few pixels.
*
* <i>Reloading images</i>
*
* @param [in] url The URL of the image file.
* @return The width and height in pixels of the image.
*/
- static Vector2 GetImageSize( const std::string& url );
+ static ImageDimensions GetImageSize( const std::string& url );
/**
* @brief Constructor which creates an empty ResourceImage object.
*/
ResourceImage& operator=( const ResourceImage& rhs );
+ /**
+ * @name ResourceImageFactoryFunctions
+ * Create ResourceImage object instances using these functions.
+ */
+ ///@{
+
/**
* @brief Create an initialised ResourceImage object.
*
+ * Uses defaults for all options.
+ *
+ * @sa Dali::FittingMode::Type Dali::SamplingMode::Type
* @param [in] url The URL of the image file to use.
+ * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
* @return A handle to a newly allocated object
*/
- static ResourceImage New( const std::string& url );
+ static ResourceImage New( const std::string& url, bool orientationCorrection = true );
/**
* @brief Create an initialised ResourceImage object.
* @param [in] url The URL of the image file to use.
* @param [in] loadPol The LoadPolicy to apply when loading the image resource.
* @param [in] releasePol The ReleasePolicy to apply to Image.
+ * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
* @return A handle to a newly allocated object
*/
- static ResourceImage New( const std::string& url, LoadPolicy loadPol, ReleasePolicy releasePol );
+ static ResourceImage New( const std::string& url, LoadPolicy loadPol, ReleasePolicy releasePol, bool orientationCorrection = true );
/**
* @brief Create an initialised ResourceImage object.
*
* @param [in] url The URL of the image file to use.
- * @param [in] attributes Requested parameters for loading (size, scaling etc.).
+ * @param [in] size The width and height to fit the loaded image to.
+ * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
+ * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
+ * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
* @return A handle to a newly allocated object
*/
- static ResourceImage New( const std::string& url, const ImageAttributes& attributes );
+ static ResourceImage New( const std::string& url,
+ ImageDimensions size,
+ FittingMode::Type fittingMode = FittingMode::DEFAULT,
+ SamplingMode::Type samplingMode = SamplingMode::DEFAULT,
+ bool orientationCorrection = true );
/**
* @brief Create an initialised ResourceImage object.
*
* @param [in] url The URL of the image file to use.
- * @param [in] attributes Requested parameters for loading (size, scaling etc.).
* @param [in] loadPol The LoadPolicy to apply when loading the image resource.
* @param [in] releasePol The ReleasePolicy to apply to Image.
+ * @param [in] size The width and height to fit the loaded image to.
+ * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
+ * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
+ * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
* @return A handle to a newly allocated object
*/
- static ResourceImage New( const std::string& url, const ImageAttributes& attributes, LoadPolicy loadPol, ReleasePolicy releasePol );
+ static ResourceImage New( const std::string& url,
+ LoadPolicy loadPol,
+ ReleasePolicy releasePol,
+ ImageDimensions size,
+ FittingMode::Type fittingMode = FittingMode::DEFAULT,
+ SamplingMode::Type samplingMode = SamplingMode::DEFAULT,
+ bool orientationCorrection = true );
+
+ ///@}
/**
* @brief Downcast an Object handle to ResourceImage handle.
/**
* @brief Reload image from filesystem.
*
- * The set ImageAttributes are used when requesting the image again.
- * @note if Image is offstage and OnDemand policy is set, reload request is ignored.
+ * The original set of image loading attributes (requested dimensions, scaling
+ * mode and filter mode) are used when requesting the image again.
+ * @note If image is offstage and OnDemand policy is set, the reload request is
+ * ignored.
*/
void Reload();
- /**
- * @brief Get the attributes of an image.
- *
- * Only to be used after the image has finished loading.
- * (Ticket's LoadingSucceeded callback was called)
- * The returned value will reflect the true image dimensions once the asynchronous loading has finished.
- * Connect to SignalLoadingFinished or use GetLoadingState to make sure this value is actual.
- * @pre image should be loaded
- * @return a copy of the attributes
- */
- ImageAttributes GetAttributes() const;
-
public: // Signals
/**
--- /dev/null
+#ifndef __DALI_UINT_16_PAIR_H__
+#define __DALI_UINT_16_PAIR_H__
+
+/*
+ * Copyright (c) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <stdint.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+
+namespace Dali
+{
+
+/**
+ * @brief Simple class for passing around pairs of small unsigned integers.
+ *
+ * Use this for integer dimensions and points with limited range such as image
+ * sizes and pixel coordinates where a pair of floating point numbers is
+ * inefficient and illogical (i.e. the data is inherently integer).
+ * These are immutable. If you want to change a value, make a whole new object.
+ * One of these can be passed in a single 32 bit integer register on
+ * common architectures.
+ */
+class Uint16Pair
+{
+public:
+ /**
+ * @brief Default constructor for the (0, 0) vector.
+ */
+ Uint16Pair() : mData(0) {}
+
+ /**
+ * @brief Constructor taking separate x and y (width and height) parameters.
+ * @param[in] width The width or X dimension of the vector. Make sure it is less than 65536,
+ * @param[in] height The height or Y dimension of the vector. Make sure it is less than 65536,
+ */
+ Uint16Pair( uint32_t width, uint32_t height )
+ {
+ DALI_ASSERT_DEBUG( width < ( 1u << 16 ) && "Width parameter not representable." );
+ DALI_ASSERT_DEBUG( height < ( 1u << 16 ) && "Height parameter not representable." );
+
+ /* Do equivalent of the code below with one aligned memory access:
+ * mComponents[0] = width;
+ * mComponents[1] = height;
+ * Unit tests make sure this is equivalent.
+ **/
+ mData = (height << 16u) + width;
+ }
+
+ /**
+ * @brief Copy constructor.
+ */
+ Uint16Pair( const Uint16Pair& rhs )
+ {
+ mData = rhs.mData;
+ }
+
+ /**
+ * @returns the x dimension stored in this 2-tuple.
+ */
+ uint16_t GetWidth() const
+ {
+ return mComponents[0];
+ }
+
+ /**
+ * @returns the y dimension stored in this 2-tuple.
+ */
+ uint16_t GetHeight() const
+ {
+ return mComponents[1];
+ }
+
+ /**
+ * @returns the x dimension stored in this 2-tuple.
+ */
+ uint16_t GetX() const
+ {
+ return mComponents[0];
+ }
+
+ /**
+ * @returns the y dimension stored in this 2-tuple.
+ */
+ uint16_t GetY() const
+ {
+ return mComponents[1];
+ }
+
+ /**
+ * Equality operator.
+ */
+ bool operator==( const Uint16Pair& rhs ) const
+ {
+ return mData == rhs.mData;
+ }
+
+ /**
+ * Inequality operator.
+ */
+ bool operator!=( const Uint16Pair& rhs ) const
+ {
+ return mData != rhs.mData;
+ }
+
+ /**
+ * Less than comparison operator for storing in collections (not geometrically
+ * meaningful).
+ */
+ bool operator<( const Uint16Pair& rhs ) const
+ {
+ return mData < rhs.mData;
+ }
+
+ /**
+ * Greater than comparison operator for storing in collections (not
+ * geometrically meaningful).
+ */
+ bool operator>( const Uint16Pair& rhs ) const
+ {
+ return mData > rhs.mData;
+ }
+
+ /**
+ * @brief Create an instance by rounding a floating point vector to closest
+ * integers.
+ *
+ * Uses a template for loose coupling, to save a header include, and allow any
+ * vector type with .x and .y members to be converted.
+ */
+ template<typename FLOAT_VECTOR_N_TYPE>
+ static Uint16Pair FromFloatVec2( const FLOAT_VECTOR_N_TYPE& from )
+ {
+ DALI_ASSERT_DEBUG( from.x + 0.5f < 65536.0f );
+ DALI_ASSERT_DEBUG( from.y + 0.5f < 65536.0f );
+ return Uint16Pair( from.x + 0.5f, from.y + 0.5f );
+ }
+
+ /**
+ * @brief Create an instance by rounding a floating point array to closest
+ * integers.
+ *
+ * Uses a template to allow any vector type with operator [] to be converted
+ * in addition to plain arrays.
+ */
+ template<typename FLOAT_ARRAY>
+ static Uint16Pair FromFloatArray( const FLOAT_ARRAY& from )
+ {
+ DALI_ASSERT_DEBUG( from[0] + 0.5f < 65536.0f );
+ DALI_ASSERT_DEBUG( from[1] + 0.5f < 65536.0f );
+ return Uint16Pair( from[0] + 0.5f, from[1] + 0.5f );
+ }
+
+private:
+ union
+ {
+ // Addressable view of X and Y:
+ uint16_t mComponents[2];
+ // Packed view of X and Y to force alignment and allow a faster copy:
+ uint32_t mData;
+ };
+};
+
+} // namespace Dali
+
+#endif // __DALI_UINT_16_PAIR_H__
// INTERNAL INCLUDES
#include <dali/public-api/actors/actor.h>
#include <dali/public-api/images/resource-image.h>
-#include <dali/public-api/images/image-attributes.h>
#include <dali/public-api/object/type-registry.h>
+#include <dali/internal/common/image-attributes.h>
#include <dali/internal/event/images/resource-image-impl.h>
#include <dali/internal/event/images/frame-buffer-image-impl.h>
#include <dali/internal/event/images/buffer-image-impl.h>
{ "BGRA8888", Pixel::BGRA8888 },
{ "COMPRESSED_R11_EAC", Pixel::COMPRESSED_R11_EAC },
{ "COMPRESSED_SIGNED_R11_EAC", Pixel::COMPRESSED_SIGNED_R11_EAC },
- { "COMPRESSED_RG11_EAC", Pixel::COMPRESSED_RG11_EAC },
{ "COMPRESSED_SIGNED_RG11_EAC", Pixel::COMPRESSED_SIGNED_RG11_EAC },
+ { "COMPRESSED_RG11_EAC", Pixel::COMPRESSED_RG11_EAC },
{ "COMPRESSED_RGB8_ETC2", Pixel::COMPRESSED_RGB8_ETC2 },
{ "COMPRESSED_SRGB8_ETC2", Pixel::COMPRESSED_SRGB8_ETC2 },
{ "COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2", Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 },
};
const unsigned int PIXEL_FORMAT_TABLE_COUNT = sizeof( PIXEL_FORMAT_TABLE ) / sizeof( PIXEL_FORMAT_TABLE[0] );
-const StringEnum< ImageAttributes::ScalingMode > IMAGE_SCALING_MODE_TABLE[] =
+const StringEnum< FittingMode::Type > IMAGE_FITTING_MODE_TABLE[] =
+{
+ { "SHRINK_TO_FIT", FittingMode::SHRINK_TO_FIT },
+ { "SCALE_TO_FILL", FittingMode::SCALE_TO_FILL },
+ { "FIT_WIDTH", FittingMode::FIT_WIDTH },
+ { "FIT_HEIGHT", FittingMode::FIT_HEIGHT },
+};
+const unsigned int IMAGE_FITTING_MODE_TABLE_COUNT = sizeof( IMAGE_FITTING_MODE_TABLE ) / sizeof( IMAGE_FITTING_MODE_TABLE[0] );
+
+const StringEnum< SamplingMode::Type > IMAGE_SAMPLING_MODE_TABLE[] =
{
- { "SHRINK_TO_FIT", ImageAttributes::ShrinkToFit },
- { "SCALE_TO_FILL", ImageAttributes::ScaleToFill },
- { "FIT_WIDTH", ImageAttributes::FitWidth },
- { "FIT_HEIGHT", ImageAttributes::FitHeight },
+ { "BOX", SamplingMode::BOX },
+ { "NEAREST", SamplingMode::NEAREST },
+ { "LINEAR", SamplingMode::LINEAR },
+ { "BOX_THEN_NEAREST", SamplingMode::BOX_THEN_NEAREST },
+ { "BOX_THEN_LINEAR", SamplingMode::BOX_THEN_LINEAR },
+ { "NO_FILTER", SamplingMode::NO_FILTER },
+ { "DONT_CARE", SamplingMode::DONT_CARE },
};
-const unsigned int IMAGE_SCALING_MODE_TABLE_COUNT = sizeof( IMAGE_SCALING_MODE_TABLE ) / sizeof( IMAGE_SCALING_MODE_TABLE[0] );
+const unsigned int IMAGE_SAMPLING_MODE_TABLE_COUNT = sizeof( IMAGE_SAMPLING_MODE_TABLE ) / sizeof( IMAGE_SAMPLING_MODE_TABLE[0] );
} // unnamed namespace
std::string filename;
ResourceImage::LoadPolicy loadPolicy = Dali::Internal::IMAGE_LOAD_POLICY_DEFAULT;
Image::ReleasePolicy releasePolicy = Dali::Internal::IMAGE_RELEASE_POLICY_DEFAULT;
- ImageAttributes attributes = ImageAttributes::New();
+ Internal::ImageAttributes attributes = Internal::ImageAttributes::New();
if( Property::MAP == map.GetType() )
{
releasePolicy = GetEnumeration< Image::ReleasePolicy >( v.c_str(), IMAGE_RELEASE_POLICY_TABLE, IMAGE_RELEASE_POLICY_TABLE_COUNT );
}
- if( map.HasKey("width") && map.HasKey("height") )
+ // Width and height can be set individually. Dali derives the unspecified
+ // dimension from the aspect ratio of the raw image.
+ unsigned int width = 0, height = 0;
+
+ field = "width";
+ if( map.HasKey( field ) )
{
- Property::Value &value = map.GetValue("width");
- unsigned int w = 0, h = 0;
+ Property::Value &value = map.GetValue( field );
+
// handle floats and integer the same for json script
- if( value.GetType() == Property::FLOAT)
+ if( value.GetType() == Property::FLOAT )
{
- w = static_cast<unsigned int>( value.Get<float>() );
+ width = static_cast<unsigned int>( value.Get<float>() );
}
else
{
- DALI_ASSERT_ALWAYS(value.GetType() == Property::INTEGER && "Image width property is not a number" );
- w = value.Get<int>();
+ DALI_ASSERT_ALWAYS( value.GetType() == Property::INTEGER && "Image width property is not a number" );
+ width = value.Get<int>();
}
+ }
- value = map.GetValue("height");
- if( value.GetType() == Property::FLOAT)
+ field = "height";
+ if( map.HasKey( field ) )
+ {
+ Property::Value &value = map.GetValue( field );
+ if( value.GetType() == Property::FLOAT )
{
- h = static_cast<unsigned int>( value.Get<float>() );
+ height = static_cast<unsigned int>( value.Get<float>() );
}
else
{
- DALI_ASSERT_ALWAYS(value.GetType() == Property::INTEGER && "Image width property is not a number" );
- h = value.Get<int>();
+ DALI_ASSERT_ALWAYS( value.GetType() == Property::INTEGER && "Image width property is not a number" );
+ height = value.Get<int>();
}
-
- attributes.SetSize( w, h );
}
+ attributes.SetSize( width, height );
+
field = "pixel-format";
Pixel::Format pixelFormat = Pixel::RGBA8888;
if( map.HasKey(field) )
{
- DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image release-policy property is not a string" );
- std::string s(map.GetValue(field).Get<std::string>());
+ DALI_ASSERT_ALWAYS( map.GetValue(field).GetType() == Property::STRING && "Image release-policy property is not a string" );
+ std::string s( map.GetValue(field).Get<std::string>() );
pixelFormat = GetEnumeration< Pixel::Format >( s.c_str(), PIXEL_FORMAT_TABLE, PIXEL_FORMAT_TABLE_COUNT );
}
- field = "scaling-mode";
- if( map.HasKey(field) )
+ field = "fitting-mode";
+ if( map.HasKey( field ) )
{
- DALI_ASSERT_ALWAYS(map.GetValue(field).GetType() == Property::STRING && "Image release-policy property is not a string" );
- std::string s(map.GetValue(field).Get<std::string>());
- attributes.SetScalingMode( GetEnumeration< ImageAttributes::ScalingMode >( s.c_str(), IMAGE_SCALING_MODE_TABLE, IMAGE_SCALING_MODE_TABLE_COUNT ) );
+ Property::Value& value = map.GetValue( field );
+ DALI_ASSERT_ALWAYS( value.GetType() == Property::STRING && "Image fitting-mode property is not a string" );
+ std::string s( value.Get<std::string>() );
+ attributes.SetScalingMode( GetEnumeration< FittingMode::Type >( s.c_str(), IMAGE_FITTING_MODE_TABLE, IMAGE_FITTING_MODE_TABLE_COUNT ) );
+ }
+
+ field = "sampling-mode";
+ if( map.HasKey( field ) )
+ {
+ Property::Value& value = map.GetValue( field );
+ DALI_ASSERT_ALWAYS( value.GetType() == Property::STRING && "Image sampling-mode property is not a string" );
+ std::string s( value.Get<std::string>() );
+ attributes.SetFilterMode( GetEnumeration< SamplingMode::Type >( s.c_str(), IMAGE_SAMPLING_MODE_TABLE, IMAGE_SAMPLING_MODE_TABLE_COUNT ) );
+ }
+
+ field = "orientation";
+ if( map.HasKey( field ) )
+ {
+ Property::Value& value = map.GetValue( field );
+ DALI_ASSERT_ALWAYS( value.GetType() == Property::BOOLEAN && "Image orientation property is not a boolean" );
+ bool b = value.Get<bool>();
+ attributes.SetOrientationCorrection( b );
}
if( map.HasKey("type") )
}
else if("ResourceImage" == s)
{
- ret = ResourceImage::New(filename, attributes, loadPolicy, releasePolicy);
+ ret = ResourceImage::New( filename, loadPolicy, releasePolicy, ImageDimensions( attributes.GetSize().x, attributes.GetSize().y ), attributes.GetScalingMode(), attributes.GetFilterMode(), attributes.GetOrientationCorrection() );
}
else
{
}
else
{
- ret = ResourceImage::New(filename, attributes, loadPolicy, releasePolicy);
+ ret = ResourceImage::New( filename, loadPolicy, releasePolicy, ImageDimensions( attributes.GetSize().x, attributes.GetSize().y ), attributes.GetScalingMode(), attributes.GetFilterMode(), attributes.GetOrientationCorrection() );
}
}
{
map[ "filename" ] = resourceImage.GetUrl();
map[ "load-policy" ] = GetEnumerationName< ResourceImage::LoadPolicy >( resourceImage.GetLoadPolicy(), IMAGE_LOAD_POLICY_TABLE, IMAGE_LOAD_POLICY_TABLE_COUNT );
-
- ImageAttributes attributes( resourceImage.GetAttributes() );
- map[ "scaling-mode" ] = GetEnumerationName< ImageAttributes::ScalingMode >( attributes.GetScalingMode(), IMAGE_SCALING_MODE_TABLE, IMAGE_SCALING_MODE_TABLE_COUNT );
}
int width( image.GetWidth() );
* "width" type float
* "height" type float
* "pixel-format" type std::string (enum)
- * "scaling-mode" type std::string (enum)
+ * "fitting-mode" type std::string (enum)
+ * "sampling-mode" type std::string (enum)
+ * "orientation" type bool
* "type" type std::string (FrameBufferImage|BufferImage|ResourceImage(default))
* @endcode
* Some fields are optional and some only pertain to a specific type.