From 7386b0e7cc501917168284f388353dab660db58f Mon Sep 17 00:00:00 2001 From: Tom Robinson Date: Thu, 10 Nov 2016 15:33:03 +0000 Subject: [PATCH] Published the AsyncImageLoader and SyncImageLoader to the public API The AsyncImageLoader API allows asynchronous image loading via an internal thread. Multiple images can be loaded with one AsyncImageLoader. The load of each image returns an ID. This ID is returned, along with the pixel data in a signal once the load for each individual image has completed. The SyncImageLoader allows synchronous image loading. It consists of a set of Load functions mirroring the prototypes of the Load functions within the AsyncImageLoader. The loads are performed within the same thread (the thread is blocked whilst loading). Change-Id: If1d59bf5981de5f52371bd5838371b41031d1fd4 --- automated-tests/src/dali-toolkit/CMakeLists.txt | 1 + .../src/dali-toolkit/utc-Dali-AsyncImageLoader.cpp | 79 +++++------- .../src/dali-toolkit/utc-Dali-SyncImageLoader.cpp | 74 +++++++++++ build/tizen/dali-toolkit/Makefile.am | 4 +- build/tizen/docs/dali.doxy.in | 2 + dali-toolkit/dali-toolkit.h | 3 + dali-toolkit/devel-api/file.list | 2 - .../image-loader/async-image-loader-impl.cpp | 6 +- .../image-loader/async-image-loader-impl.h | 24 ++-- .../internal/image-loader/image-atlas-impl.h | 2 +- .../internal/image-loader/image-load-thread.cpp | 10 +- dali-toolkit/public-api/file.list | 6 + .../image-loader/async-image-loader.cpp | 26 ++-- .../image-loader/async-image-loader.h | 138 ++++++++++++++------- .../public-api/image-loader/sync-image-loader.cpp | 61 +++++++++ .../public-api/image-loader/sync-image-loader.h | 103 +++++++++++++++ 16 files changed, 417 insertions(+), 124 deletions(-) create mode 100644 automated-tests/src/dali-toolkit/utc-Dali-SyncImageLoader.cpp rename dali-toolkit/{devel-api => public-api}/image-loader/async-image-loader.cpp (70%) rename dali-toolkit/{devel-api => public-api}/image-loader/async-image-loader.h (52%) create mode 100644 dali-toolkit/public-api/image-loader/sync-image-loader.cpp create mode 100644 dali-toolkit/public-api/image-loader/sync-image-loader.h diff --git a/automated-tests/src/dali-toolkit/CMakeLists.txt b/automated-tests/src/dali-toolkit/CMakeLists.txt index 1c6f3c9..f30e3d1 100644 --- a/automated-tests/src/dali-toolkit/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit/CMakeLists.txt @@ -57,6 +57,7 @@ SET(TC_SOURCES utc-Dali-ImageAtlas.cpp utc-Dali-VideoView.cpp utc-Dali-AsyncImageLoader.cpp + utc-Dali-SyncImageLoader.cpp ) # Append list of test harness files (Won't get parsed for test cases) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AsyncImageLoader.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AsyncImageLoader.cpp index 3ee9a77..74dcc73 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-AsyncImageLoader.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-AsyncImageLoader.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include using namespace Dali; using namespace Dali::Toolkit; @@ -139,6 +139,28 @@ int UtcDaliAsyncImageLoaderAssignmentOperator(void) END_TEST; } +int UtcDaliAsyncImageLoaderDownCastP(void) +{ + AsyncImageLoader asyncImageLoader = AsyncImageLoader::New(); + BaseHandle object(asyncImageLoader); + + AsyncImageLoader asyncImageLoader2 = AsyncImageLoader::DownCast( object ); + + DALI_TEST_CHECK( asyncImageLoader2 ); + + END_TEST; +} + +int UtcDaliAsyncImageLoaderDownCastN(void) +{ + BaseHandle unInitializedObject; + AsyncImageLoader asyncImageLoader = AsyncImageLoader::DownCast( unInitializedObject ); + + DALI_TEST_CHECK( !asyncImageLoader ); + + END_TEST; +} + int UtcDaliAsyncImageLoaderLoadAndLoadedSignal(void) { ToolkitTestApplication application; @@ -169,6 +191,7 @@ int UtcDaliAsyncImageLoaderLoadAndLoadedSignal(void) END_TEST; } +// Note: This is not an ideal test, but we cannot guarantee we can call Cancel() before the image has finished loading. int UtcDaliAsyncImageLoaderCancel(void) { ToolkitTestApplication application; @@ -182,31 +205,28 @@ int UtcDaliAsyncImageLoaderCancel(void) uint32_t id02 = loader.Load( gImage_50_RGBA, ImageDimensions( 25, 25 ) ); uint32_t id03 = loader.Load( gImage_128_RGB, ImageDimensions( 100, 100 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, true ); - // cancel the loading of the second image - DALI_TEST_CHECK( loader.Cancel( id02 ) ); - EventThreadCallback* eventTrigger = EventThreadCallback::Get(); CallbackBase* callback = eventTrigger->GetCallback(); - eventTrigger->WaitingForTrigger( 2 );// waiting until first and third images are loaded + eventTrigger->WaitingForTrigger( 3 ); // waiting until images are loaded CallbackBase::Execute( *callback ); - DALI_TEST_CHECK( ! loader.Cancel( id03 ) ); // can not cancel a task that is already implemeted - application.SendNotification(); application.Render(); - DALI_TEST_CHECK( loadedSignalVerifier.LoadedImageCount() == 2 ); + DALI_TEST_CHECK( loadedSignalVerifier.LoadedImageCount() == 3 ); + + DALI_TEST_CHECK( !loader.Cancel( id03 ) ); // Cannot cancel a task that is already implemeted - DALI_TEST_CHECK( loadedSignalVerifier.Verify( id01, 34, 34 ) ); // first image is successfully loaded - DALI_TEST_CHECK( !loadedSignalVerifier.Verify( id02, 25, 25 ) ); // second image is not loaded - DALI_TEST_CHECK( loadedSignalVerifier.Verify( id03, 100, 100 ) ); // third image is successfully loaded + DALI_TEST_CHECK( loadedSignalVerifier.Verify( id01, 34, 34 ) ); // first image is loaded + DALI_TEST_CHECK( loadedSignalVerifier.Verify( id02, 25, 25 ) ); // second image is loaded + DALI_TEST_CHECK( loadedSignalVerifier.Verify( id03, 100, 100 ) ); // third image is loaded END_TEST; } -int UtcDaliAsncImageLoaderCancelAll01(void) +int UtcDaliAsyncImageLoaderCancelAll(void) { ToolkitTestApplication application; @@ -229,38 +249,3 @@ int UtcDaliAsncImageLoaderCancelAll01(void) END_TEST; } -int UtcDaliAsyncImageLoaderCancelAll02(void) -{ - ToolkitTestApplication application; - - AsyncImageLoader loader = AsyncImageLoader::New(); - ImageLoadedSignalVerifier loadedSignalVerifier; - - loader.ImageLoadedSignal().Connect( &loadedSignalVerifier, &ImageLoadedSignalVerifier::ImageLoaded ); - - loader.Load( gImage_34_RGBA, ImageDimensions( 34, 34 ) ); - uint32_t id02 = loader.Load( gImage_50_RGBA, ImageDimensions( 25, 25 ) ); - - // try to cancel the loading of the first and second image, however the cancellation of the first image is not guaranteed - loader.CancelAll(); - - uint32_t id03 = loader.Load( gImage_128_RGB, ImageDimensions( 100, 100 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, true ); - loader.Load( gImage_128_RGB, ImageDimensions( 128, 128 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, true ); - - EventThreadCallback* eventTrigger = EventThreadCallback::Get(); - CallbackBase* callback = eventTrigger->GetCallback(); - - eventTrigger->WaitingForTrigger( 2 );// waiting until the third images is loaded - - CallbackBase::Execute( *callback ); - - application.SendNotification(); - application.Render(); - - DALI_TEST_CHECK( !loadedSignalVerifier.Verify( id02, 25, 25 ) ); // second image is not loaded - DALI_TEST_CHECK( loadedSignalVerifier.Verify( id03, 100, 100 ) ); // third image is successfully loaded - - END_TEST; -} - - diff --git a/automated-tests/src/dali-toolkit/utc-Dali-SyncImageLoader.cpp b/automated-tests/src/dali-toolkit/utc-Dali-SyncImageLoader.cpp new file mode 100644 index 0000000..d37c5fc --- /dev/null +++ b/automated-tests/src/dali-toolkit/utc-Dali-SyncImageLoader.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016 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 +#include +#include +#include +#include + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace +{ + +// Resolution: 50*50, pixel format: RGBA8888 +static const char* gImage_50_RGBA = TEST_RESOURCE_DIR "/icon-delete.png"; + +// Resolution: 128*128, pixel format: RGB888 +static const char* gImage_128_RGB = TEST_RESOURCE_DIR "/gallery-small-1.jpg"; + + +void VerifyLoad( PixelData pixelData, uint32_t width, uint32_t height ) +{ + DALI_TEST_CHECK( pixelData ); + DALI_TEST_EQUALS( pixelData.GetWidth(), width, TEST_LOCATION ); + DALI_TEST_EQUALS( pixelData.GetHeight(), height, TEST_LOCATION ); +} + +} // anonymous namespace + + +int UtcDaliSyncImageLoaderLoad(void) +{ + PixelData pixelData = Toolkit::SyncImageLoader::Load( gImage_50_RGBA ); + + DALI_TEST_EQUALS( pixelData, true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliSyncImageLoaderLoadWithDimensions(void) +{ + PixelData pixelData = Toolkit::SyncImageLoader::Load( gImage_50_RGBA, ImageDimensions( 25, 25 ) ); + + VerifyLoad( pixelData, 25u, 25u ); + + END_TEST; +} + +int UtcDaliSyncImageLoaderLoadWithAllOptions(void) +{ + PixelData pixelData = Toolkit::SyncImageLoader::Load( gImage_128_RGB, ImageDimensions( 100, 100 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, true ); + + VerifyLoad( pixelData, 100u, 100u ); + + END_TEST; +} + + diff --git a/build/tizen/dali-toolkit/Makefile.am b/build/tizen/dali-toolkit/Makefile.am index fd09527..166feb4 100644 --- a/build/tizen/dali-toolkit/Makefile.am +++ b/build/tizen/dali-toolkit/Makefile.am @@ -111,7 +111,7 @@ develapiprogressbardir = $(develapicontrolsdir)/progress-bar develapishadowviewdir = $(develapicontrolsdir)/shadow-view develapisuperblurviewdir = $(develapicontrolsdir)/super-blur-view develapifocusmanagerdir = $(develapidir)/focus-manager -develapiimageloaderdir = $(develapidir)/image-loader +develapiimageloaderdir = $(develapidir)/image-loader develapiscriptingdir = $(develapidir)/scripting develapishadereffectsdir = $(develapidir)/shader-effects develapitransitioneffectsdir = $(develapidir)/transition-effects @@ -146,6 +146,7 @@ develapitextselectionpopup_HEADERS = $(devel_api_text_controls_header_files) # public api source publicapidir = $(topleveldir)/public-api publicapicontrolsdir = $(publicapidir)/controls +publicapiimageloaderdir = $(publicapidir)/image-loader publicapiaccessibilitymanagerdir = $(publicapidir)/accessibility-manager publicapialignmentdir = $(publicapicontrolsdir)/alignment publicapibuttonsdir = $(publicapicontrolsdir)/buttons @@ -169,6 +170,7 @@ publicapivisualsdir = $(publicapidir)/visuals # public api headers publicapi_HEADERS = $(public_api_header_files) publicapicontrols_HEADERS = $(public_api_controls_header_files) +publicapiimageloader_HEADERS = $(public_api_image_loader_header_files) publicapiaccessibilitymanager_HEADERS = $(public_api_accessibility_manager_header_files) publicapialignment_HEADERS = $(public_api_alignment_header_files) publicapibuttons_HEADERS = $(public_api_buttons_header_files) diff --git a/build/tizen/docs/dali.doxy.in b/build/tizen/docs/dali.doxy.in index 6cdabe4..6007065 100644 --- a/build/tizen/docs/dali.doxy.in +++ b/build/tizen/docs/dali.doxy.in @@ -351,6 +351,7 @@ ALIASES += SINCE_1_2_2="@since 1.2.2" ALIASES += SINCE_1_2_4="@since 1.2.4" ALIASES += SINCE_1_2_5="@since 1.2.5" ALIASES += SINCE_1_2_10="@since 1.2.10" +ALIASES += SINCE_1_2_14="@since 1.2.14" ALIASES += DEPRECATED_1_0="@deprecated Deprecated since 1.0" ALIASES += DEPRECATED_1_1="@deprecated Deprecated since 1.1" @@ -375,6 +376,7 @@ ALIASES += REMARK_INTERNET="" #ALIASES += SINCE_1_2_4="\par Since:\n 3.0, DALi version 1.2.4" #ALIASES += SINCE_1_2_5="\par Since:\n 3.0, DALi version 1.2.5" #ALIASES += SINCE_1_2_10="\par Since:\n 3.0, DALi version 1.2.10" +#ALIASES += SINCE_1_2_14="\par Since:\n 3.0, DALi version 1.2.14" ## DALi has no deprecated API in Tizen 2.4 because it's DALi's first release. ## Thus deprecated APIs in DALi 1.0.xx will be deprecated in Tizen 3.0. diff --git a/dali-toolkit/dali-toolkit.h b/dali-toolkit/dali-toolkit.h index be46ddd..ba7e85b 100644 --- a/dali-toolkit/dali-toolkit.h +++ b/dali-toolkit/dali-toolkit.h @@ -47,6 +47,9 @@ #include #include +#include +#include + #include #include diff --git a/dali-toolkit/devel-api/file.list b/dali-toolkit/devel-api/file.list index 78e96e5..8af4766 100755 --- a/dali-toolkit/devel-api/file.list +++ b/dali-toolkit/devel-api/file.list @@ -21,7 +21,6 @@ devel_api_src_files = \ $(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.cpp \ $(devel_api_src_dir)/controls/tool-bar/tool-bar.cpp \ $(devel_api_src_dir)/focus-manager/keyinput-focus-manager.cpp \ - $(devel_api_src_dir)/image-loader/async-image-loader.cpp \ $(devel_api_src_dir)/image-loader/atlas-upload-observer.cpp \ $(devel_api_src_dir)/image-loader/image-atlas.cpp \ $(devel_api_src_dir)/scripting/script.cpp \ @@ -88,7 +87,6 @@ devel_api_focus_manager_header_files = \ $(devel_api_src_dir)/focus-manager/keyinput-focus-manager.h devel_api_image_loader_header_files = \ - $(devel_api_src_dir)/image-loader/async-image-loader.h \ $(devel_api_src_dir)/image-loader/atlas-upload-observer.h \ $(devel_api_src_dir)/image-loader/image-atlas.h diff --git a/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp b/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp index d25ea5c..06065b7 100644 --- a/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp +++ b/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp @@ -34,7 +34,7 @@ namespace Internal AsyncImageLoader::AsyncImageLoader() : mLoadedSignal(), mLoadThread( new EventThreadCallback( MakeCallback( this, &AsyncImageLoader::ProcessLoadedImage ) ) ), - mLoadTaskId( 0 ), + mLoadTaskId( 0u ), mIsLoadThreadStarted( false ) { } @@ -51,7 +51,7 @@ IntrusivePtr AsyncImageLoader::New() } uint32_t AsyncImageLoader::Load( const std::string& url, - ImageDimensions size, + ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection ) @@ -62,7 +62,7 @@ uint32_t AsyncImageLoader::Load( const std::string& url, mIsLoadThreadStarted = true; } - BitmapLoader loader = BitmapLoader::New( url, size, fittingMode, samplingMode, orientationCorrection ); + BitmapLoader loader = BitmapLoader::New( url, dimensions, fittingMode, samplingMode, orientationCorrection ); mLoadThread.AddTask( new LoadingTask( ++mLoadTaskId, loader ) ); diff --git a/dali-toolkit/internal/image-loader/async-image-loader-impl.h b/dali-toolkit/internal/image-loader/async-image-loader-impl.h index cb0311c..92a1652 100644 --- a/dali-toolkit/internal/image-loader/async-image-loader-impl.h +++ b/dali-toolkit/internal/image-loader/async-image-loader-impl.h @@ -1,5 +1,5 @@ -#ifndef DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H__ -#define DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H__ +#ifndef DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H +#define DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -22,7 +22,7 @@ #include // INTERNAL INCLUDES -#include +#include #include namespace Dali @@ -49,10 +49,10 @@ public: static IntrusivePtr New(); /** - * @copydoc Toolkit::AsyncImageLoader::Load( const std::string&, ImageDimensions,FittingMode::Type, SamplingMode::Type, bool ) + * @copydoc Toolkit::AsyncImageLoader::Load( const std::string&, ImageDimensions, FittingMode::Type, SamplingMode::Type, bool ) */ uint32_t Load( const std::string& url, - ImageDimensions size, + ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection ); @@ -97,20 +97,20 @@ private: } // namespace Internal -inline const Internal::AsyncImageLoader& GetImplementation( const Toolkit::AsyncImageLoader& loader ) +inline const Internal::AsyncImageLoader& GetImplementation( const Toolkit::AsyncImageLoader& handle ) { - DALI_ASSERT_ALWAYS( loader && "AsyncImageLoader handle is empty" ); + DALI_ASSERT_ALWAYS( handle && "AsyncImageLoader handle is empty" ); - const BaseObject& object = loader.GetBaseObject(); + const BaseObject& object = handle.GetBaseObject(); return static_cast( object ); } -inline Internal::AsyncImageLoader& GetImplementation( Toolkit::AsyncImageLoader& loader ) +inline Internal::AsyncImageLoader& GetImplementation( Toolkit::AsyncImageLoader& handle ) { - DALI_ASSERT_ALWAYS( loader && "AsyncImageLoader handle is empty" ); + DALI_ASSERT_ALWAYS( handle && "AsyncImageLoader handle is empty" ); - BaseObject& object = loader.GetBaseObject(); + BaseObject& object = handle.GetBaseObject(); return static_cast( object ); } @@ -119,4 +119,4 @@ inline Internal::AsyncImageLoader& GetImplementation( Toolkit::AsyncImageLoader& } // namespace Dali -#endif /* DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H__ */ +#endif // DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H diff --git a/dali-toolkit/internal/image-loader/image-atlas-impl.h b/dali-toolkit/internal/image-loader/image-atlas-impl.h index a773ea7..4f735ef 100644 --- a/dali-toolkit/internal/image-loader/image-atlas-impl.h +++ b/dali-toolkit/internal/image-loader/image-atlas-impl.h @@ -27,8 +27,8 @@ // INTERNAL INCLUDES #include -#include #include +#include namespace Dali { diff --git a/dali-toolkit/internal/image-loader/image-load-thread.cpp b/dali-toolkit/internal/image-loader/image-load-thread.cpp index a27db14..11e251a 100644 --- a/dali-toolkit/internal/image-loader/image-load-thread.cpp +++ b/dali-toolkit/internal/image-loader/image-load-thread.cpp @@ -50,7 +50,7 @@ ImageLoadThread::~ImageLoadThread() void ImageLoadThread::Run() { - while( LoadingTask* task = NextTaskToProcess()) + while( LoadingTask* task = NextTaskToProcess() ) { task->loader.Load(); AddCompletedTask( task ); @@ -68,7 +68,7 @@ void ImageLoadThread::AddTask( LoadingTask* task ) mLoadQueue.PushBack( task ); } - if( wasEmpty) + if( wasEmpty ) { // wake up the image loading thread mConditionalWait.Notify(); @@ -97,7 +97,7 @@ bool ImageLoadThread::CancelTask( uint32_t loadingTaskId ) // Lock while remove task from the queue ConditionalWait::ScopedLock lock( mConditionalWait ); - for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); iter++ ) + for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); ++iter ) { if( (*iter)->id == loadingTaskId ) { @@ -116,9 +116,9 @@ void ImageLoadThread::CancelAll() // Lock while remove task from the queue ConditionalWait::ScopedLock lock( mConditionalWait ); - for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); iter++ ) + for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); ++iter ) { - delete (*iter); + delete ( *iter ); } mLoadQueue.Clear(); } diff --git a/dali-toolkit/public-api/file.list b/dali-toolkit/public-api/file.list index 3734525..a4e4e56 100755 --- a/dali-toolkit/public-api/file.list +++ b/dali-toolkit/public-api/file.list @@ -26,6 +26,8 @@ public_api_src_files = \ $(public_api_src_dir)/controls/text-controls/text-label.cpp \ $(public_api_src_dir)/controls/text-controls/text-field.cpp \ $(public_api_src_dir)/controls/video-view/video-view.cpp \ + $(public_api_src_dir)/image-loader/async-image-loader.cpp \ + $(public_api_src_dir)/image-loader/sync-image-loader.cpp \ $(public_api_src_dir)/styling/style-manager.cpp \ $(public_api_src_dir)/accessibility-manager/accessibility-manager.cpp \ $(public_api_src_dir)/focus-manager/keyboard-focus-manager.cpp \ @@ -68,6 +70,10 @@ public_api_item_view_header_files = \ $(public_api_src_dir)/controls/scrollable/item-view/item-view-declarations.h \ $(public_api_src_dir)/controls/scrollable/item-view/item-view.h +public_api_image_loader_header_files = \ + $(public_api_src_dir)/image-loader/async-image-loader.h \ + $(public_api_src_dir)/image-loader/sync-image-loader.h + public_api_scrollable_header_files = \ $(public_api_src_dir)/controls/scrollable/scrollable.h diff --git a/dali-toolkit/devel-api/image-loader/async-image-loader.cpp b/dali-toolkit/public-api/image-loader/async-image-loader.cpp similarity index 70% rename from dali-toolkit/devel-api/image-loader/async-image-loader.cpp rename to dali-toolkit/public-api/image-loader/async-image-loader.cpp index a20ece1..c1e23ee 100644 --- a/dali-toolkit/devel-api/image-loader/async-image-loader.cpp +++ b/dali-toolkit/public-api/image-loader/async-image-loader.cpp @@ -36,7 +36,8 @@ AsyncImageLoader::~AsyncImageLoader() AsyncImageLoader::AsyncImageLoader( Internal::AsyncImageLoader* impl ) : BaseHandle( impl ) -{} +{ +} AsyncImageLoader::AsyncImageLoader( const AsyncImageLoader& handle ) : BaseHandle( handle ) @@ -45,10 +46,15 @@ AsyncImageLoader::AsyncImageLoader( const AsyncImageLoader& handle ) AsyncImageLoader& AsyncImageLoader::operator=( const AsyncImageLoader& handle ) { - BaseHandle::operator=(handle); + BaseHandle::operator=( handle ); return *this; } +AsyncImageLoader AsyncImageLoader::DownCast( BaseHandle handle ) +{ + return AsyncImageLoader( dynamic_cast( handle.GetObjectPtr() ) ); +} + AsyncImageLoader AsyncImageLoader::New() { IntrusivePtr internal = Internal::AsyncImageLoader::New(); @@ -57,36 +63,36 @@ AsyncImageLoader AsyncImageLoader::New() uint32_t AsyncImageLoader::Load( const std::string& url ) { - return GetImplementation(*this).Load( url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true ); + return GetImplementation( *this ).Load( url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true ); } -uint32_t AsyncImageLoader::Load( const std::string& url, ImageDimensions size ) +uint32_t AsyncImageLoader::Load( const std::string& url, ImageDimensions dimensions ) { - return GetImplementation(*this).Load( url, size, FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true ); + return GetImplementation( *this ).Load( url, dimensions, FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true ); } uint32_t AsyncImageLoader::Load( const std::string& url, - ImageDimensions size, + ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection ) { - return GetImplementation(*this).Load( url, size, fittingMode, samplingMode, orientationCorrection ); + return GetImplementation(*this).Load( url, dimensions, fittingMode, samplingMode, orientationCorrection ); } -bool AsyncImageLoader::Cancel( uint32_t loadingTaskId) +bool AsyncImageLoader::Cancel( uint32_t loadingTaskId ) { return GetImplementation(*this).Cancel( loadingTaskId ); } void AsyncImageLoader::CancelAll() { - GetImplementation(*this).CancelAll(); + GetImplementation( *this ).CancelAll(); } AsyncImageLoader::ImageLoadedSignalType& AsyncImageLoader::ImageLoadedSignal() { - return GetImplementation(*this).ImageLoadedSignal(); + return GetImplementation( *this ).ImageLoadedSignal(); } } // namespace Toolkit diff --git a/dali-toolkit/devel-api/image-loader/async-image-loader.h b/dali-toolkit/public-api/image-loader/async-image-loader.h similarity index 52% rename from dali-toolkit/devel-api/image-loader/async-image-loader.h rename to dali-toolkit/public-api/image-loader/async-image-loader.h index 82a2079..844d758 100644 --- a/dali-toolkit/devel-api/image-loader/async-image-loader.h +++ b/dali-toolkit/public-api/image-loader/async-image-loader.h @@ -1,5 +1,5 @@ -#ifndef __DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H__ -#define __DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H__ +#ifndef DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H +#define DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -36,27 +36,38 @@ class AsyncImageLoader; } /** - *@brief The AysncImageLoader is used to load pixel data from the URL asynchronously. + * @brief The AsyncImageLoader is used to load pixel data from a URL asynchronously. * * The images are loaded in a worker thread to avoid blocking the main event thread. * - * Each load call is assigned with an ID, connect to the ImageLoadedSignal and receive the corresponding pixel data by comparing the ID. + * To keep track of the loading images, each load call is assigned an ID (which is returned by the Load() call). + * To know when the Load has completed, connect to the ImageLoadedSignal. + * This signal should be connected before Load is called (in case the signal is emitted immediately). + * + * Load errors can be detected by checking the PixelData object is valid from within the signal handler. + + * Note: The PixelData object will automatically be destroyed when it leaves its scope. + * + * Example: * - * To make sure the signal is always received, the signal should get connected before invoking the load call. * @code * class MyClass : public ConnectionTracker * { - * public: + * public: * - * MyCallback( uint32_t id, PixelData pixelData) + * MyCallback( uint32_t loadedTaskId, PixelData pixelData ) * { - * if(id == mId1) + * // First check if the image loaded correctly. + * if( pixelData ) * { - * // use the loaded pixel data from the first image - * } - * else if( id == mId2 ) - * { - * // use the loaded pixel data from the second image + * if( loadedTaskId == mId1 ) + * { + * // use the loaded pixel data from the first image + * } + * else if( loadedTaskId == mId2 ) + * { + * // use the loaded pixel data from the second image + * } * } * } * @@ -66,11 +77,13 @@ class AsyncImageLoader; * * MyClass myObject; * AsyncImageLoader imageLoader = AsyncImageLoader::New(); - * // connect the signal here + * + * // Connect the signal here. * imageLoader.ImageLoadedSignal().Connect( &myObject, &MyClass::MyCallback ); - * // then invoke the load calls - * testCallback.mId1 = imageLoader.Load( "first_image_url.jpg" ); - * testCallback.mId2 = imageLoader.Load( "second_image_url.jpg" ); + * + * // Invoke the load calls (must do this after connecting the signal to guarantee callbacks occur). + * myObject.mId1 = imageLoader.Load( "first_image_url.jpg" ); + * myObject.mId2 = imageLoader.Load( "second_image_url.jpg" ); * * @endcode */ @@ -78,17 +91,13 @@ class DALI_IMPORT_API AsyncImageLoader : public BaseHandle { public: - /** - * @brief Type of signal for image loading finished. - * - * The signal is emit with the load ID and its corresponding loaded pixel data - */ - typedef Signal< void( uint32_t, PixelData ) > ImageLoadedSignalType; + typedef Signal< void( uint32_t, PixelData ) > ImageLoadedSignalType; ///< Image loaded signal type @SINCE_1_2_14 public: /** * @brief Constructor which creates an empty AsyncImageLoader handle. + * @SINCE_1_2_14 * * Use AsyncImageLoader::New() to create an initialised object. */ @@ -96,6 +105,7 @@ public: /** * @brief Destructor + * @SINCE_1_2_14 * * This is non-virtual since derived Handle types must not contain data or virtual methods. */ @@ -103,68 +113,99 @@ public: /** * @brief This copy constructor is required for (smart) pointer semantics. + * @SINCE_1_2_14 * - * @param [in] handle A reference to the copied handle + * @param[in] handle A reference to the copied handle */ AsyncImageLoader( const AsyncImageLoader& handle ); /** * @brief This assignment operator is required for (smart) pointer semantics. + * @SINCE_1_2_14 * - * @param [in] handle A reference to the copied handle + * @param[in] handle A reference to the copied handle * @return A reference to this */ AsyncImageLoader& operator=( const AsyncImageLoader& handle ); - /* - * @brief Create a new loader to load the image asynchronously in a worker thread. - * - * @return The image loader. - */ + /** + * @brief Create a new loader to load the image asynchronously in a worker thread. + * @SINCE_1_2_14 + * + * @return The image loader. + */ static AsyncImageLoader New(); /** - * @brief Start a image loading task. + * @brief Downcast a handle to AsyncImageLoader handle. + * + * If the handle points to an AsyncImageLoader object the downcast produces + * a valid handle. If not, the returned handle is left uninitialized. + * + * @SINCE_1_2_14 + * @param[in] handle A handle to an object + * @return A handle to a AsyncImageLoader object or an uninitialized handle + */ + static AsyncImageLoader DownCast( BaseHandle handle ); + + /** + * @brief Start an image loading task. + * Note: When using this method, the following defaults will be used: + * fittingMode = FittingMode::DEFAULT + * samplingMode = SamplingMode::BOX_THEN_LINEAR + * orientationCorrection = true + * + * @SINCE_1_2_14 * * @param[in] url The URL of the image file to load. * @return The loading task id. */ uint32_t Load( const std::string& url ); - /* - * @brief Start a image loading task. + + /** + * @brief Start an image loading task. + * Note: When using this method, the following defaults will be used: + * fittingMode = FittingMode::DEFAULT + * samplingMode = SamplingMode::BOX_THEN_LINEAR + * orientationCorrection = true + * + * @SINCE_1_2_14 * * @param[in] url The URL of the image file to load. - * @param[in] size The width and height to fit the loaded image to. + * @param[in] dimensions The width and height to fit the loaded image to. * @return The loading task id. */ - uint32_t Load( const std::string& url, ImageDimensions size ); + uint32_t Load( const std::string& url, ImageDimensions dimensions ); - /* - * @brief Start a image loading task. + /** + * @brief Start an image loading task. + * @SINCE_1_2_14 * * @param[in] url The URL of the image file to load. - * @param[in] size The width and height to fit the loaded image to. + * @param[in] dimensions 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 The loading task id. */ uint32_t Load( const std::string& url, - ImageDimensions size, + ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection ); /** - * @brief Cancel a image loading task if it is still queuing in the work thread. + * @brief Cancel a image loading task if it is still queueing in the work thread. + * @SINCE_1_2_14 * * @param[in] loadingTaskId The task id returned when invoking the load call. * @return If true, the loading task is removed from the queue, otherwise the loading is already implemented and unable to cancel anymore */ - bool Cancel( uint32_t loadingTaskId); + bool Cancel( uint32_t loadingTaskId ); /** * @brief Cancel all the loading tasks in the queue + * @SINCE_1_2_14 */ void CancelAll(); @@ -175,14 +216,25 @@ public: * @code * void YourCallbackName( uint32_t id, PixelData pixelData ); * @endcode + * @SINCE_1_2_14 * - * @return A signal object to Connect() with. + * @return A reference to a signal object to Connect() with. */ ImageLoadedSignalType& ImageLoadedSignal(); public: // Not intended for developer use + /// @cond internal + /** + * @brief Allows the creation of a AsyncImageLoader handle from an internal pointer. + * + * @note Not intended for application developers + * @SINCE_1_2_14 + * + * @param[in] impl A pointer to the object. + */ explicit DALI_INTERNAL AsyncImageLoader( Internal::AsyncImageLoader* impl ); + /// @endcond }; @@ -190,4 +242,4 @@ public: // Not intended for developer use } // namespace Dali -#endif /* __DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H__ */ +#endif // DALI_TOOLKIT_ASYNC_IMAGE_LOADER_H diff --git a/dali-toolkit/public-api/image-loader/sync-image-loader.cpp b/dali-toolkit/public-api/image-loader/sync-image-loader.cpp new file mode 100644 index 0000000..de489dc --- /dev/null +++ b/dali-toolkit/public-api/image-loader/sync-image-loader.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016 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 "sync-image-loader.h" +#include + + +namespace Dali +{ + +namespace Toolkit +{ + +namespace SyncImageLoader +{ + + +PixelData Load( const std::string& url ) +{ + return Load( url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true ); +} + +PixelData Load( const std::string& url, ImageDimensions dimensions ) +{ + return Load( url, dimensions, FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true ); +} + +PixelData Load( const std::string& url, + ImageDimensions dimensions, + FittingMode::Type fittingMode, + SamplingMode::Type samplingMode, + bool orientationCorrection ) +{ + BitmapLoader loader = BitmapLoader::New( url, dimensions, fittingMode, samplingMode, orientationCorrection ); + + // Load the image synchronously (block the thread here). + loader.Load(); + + return loader.GetPixelData(); +} + + +} // namespace SyncImageLoader + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/public-api/image-loader/sync-image-loader.h b/dali-toolkit/public-api/image-loader/sync-image-loader.h new file mode 100644 index 0000000..3450ba9 --- /dev/null +++ b/dali-toolkit/public-api/image-loader/sync-image-loader.h @@ -0,0 +1,103 @@ +#ifndef DALI_TOOLKIT_SYNC_IMAGE_LOADER_H +#define DALI_TOOLKIT_SYNC_IMAGE_LOADER_H + +/* + * Copyright (c) 2016 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 +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace SyncImageLoader +{ + +/** + * @brief The methods in the SyncImageLoader namespace are used to load pixel data from a URL synchronously. + * + * Example: + * + * @code + * PixelData pixelData = Toolkit::SyncImageLoader::Load( "image_url.jpg" ); + * + * // Check the image was loaded without error. + * if( pixelData ) + * { + * // Do work... + * } + * + * @endcode + */ + +/** + * @brief Load an image synchronously. + * Note: When using this method, the following defaults will be used: + * fittingMode = FittingMode::DEFAULT + * samplingMode = SamplingMode::BOX_THEN_LINEAR + * orientationCorrection = true + * + * @SINCE_1_2_14 + * + * @param[in] url The URL of the image file to load. + * @return A PixelData object containing the image, or an invalid object on failure. + */ +PixelData Load( const std::string& url ); + +/** + * @brief Load an image synchronously by specifying the target dimensions. + * Note: When using this method, the following defaults will be used: + * fittingMode = FittingMode::DEFAULT + * samplingMode = SamplingMode::BOX_THEN_LINEAR + * orientationCorrection = true + * + * @SINCE_1_2_14 + * + * @param[in] url The URL of the image file to load. + * @param[in] dimensions The width and height to fit the loaded image to. + * @return A PixelData object containing the image, or an invalid object on failure. + */ +PixelData Load( const std::string& url, ImageDimensions dimensions ); + +/** + * @brief Load an image synchronously by specifying the target dimensions and options. + * @SINCE_1_2_14 + * + * @param[in] url The URL of the image file to load. + * @param[in] dimensions 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 PixelData object containing the image, or an invalid object on failure. + */ +PixelData Load( const std::string& url, + ImageDimensions dimensions, + FittingMode::Type fittingMode, + SamplingMode::Type samplingMode, + bool orientationCorrection ); + +} // namespace SyncImageLoader + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_SYNC_IMAGE_LOADER_H -- 2.7.4