[dali_1.3.34] Merge branch 'devel/master' 17/185317/1
authorDavid Steele <david.steele@samsung.com>
Fri, 27 Jul 2018 11:43:34 +0000 (12:43 +0100)
committerDavid Steele <david.steele@samsung.com>
Fri, 27 Jul 2018 11:43:34 +0000 (12:43 +0100)
Change-Id: I8852f7401acd7308ea91d64f185654eed55a7151

18 files changed:
automated-tests/src/dali-toolkit/utc-Dali-Builder.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/devel-api/builder/base64-encoding.cpp [new file with mode: 0644]
dali-toolkit/devel-api/builder/base64-encoding.h [new file with mode: 0644]
dali-toolkit/devel-api/file.list
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp
dali-toolkit/internal/visuals/image-atlas-manager.cpp
dali-toolkit/internal/visuals/image-atlas-manager.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/third-party/base-n/basen.hpp [new file with mode: 0644]
packaging/dali-toolkit.spec

index 511d2ef..77439d4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 #include <iostream>
-#include <stdlib.h>
+#include <iterator>
+#include <vector>
+#include <algorithm>
+#include <cstdlib>
+
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/devel-api/builder/builder.h>
+#include <dali-toolkit/devel-api/builder/base64-encoding.h>
 #include <dali/integration-api/events/touch-event-integ.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <test-button.h>
 #include <test-animation-data.h>
 
+
 #define STRINGIFY(A)#A
 
 using namespace Dali;
@@ -1851,3 +1857,256 @@ int UtcDaliBuilderConfigurationP(void)
 
   END_TEST;
 }
+
+
+int UtcDaliBase64EncodingP(void)
+{
+  std::vector<uint32_t> data = { 0, 1, 2, 3, 4, 5, std::numeric_limits<uint32_t>::min(), std::numeric_limits<uint32_t>::max()  };
+
+  Property::Value value;
+  EncodeBase64PropertyData( value, data );
+
+  std::cout << "Max uint32_t:" << std::numeric_limits<uint32_t>::max() << std::endl;
+  std::cout << "Input data:  ";
+  std::ostream_iterator<uint32_t> out_it (std::cout,", ");
+  std::copy ( data.begin(), data.end(), out_it );
+  std::cout << std::endl;
+
+  std::string output;
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output, "AAAAAAEAAAACAAAAAwAAAAQAAAAFAAAAAAAAAP////8", TEST_LOCATION );
+
+  std::cout << "Output data:  " << output << std::endl;
+
+  END_TEST;
+}
+
+int UtcDaliBase64EncodingN(void)
+{
+  tet_infoline( "Test encoding an empty vector returns empty string" );
+  std::vector<uint32_t> data;
+
+  Property::Value value;
+  EncodeBase64PropertyData( value, data );
+
+  std::string output;
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), true, TEST_LOCATION );
+
+  END_TEST;
+}
+
+template <typename T>
+int b64l(std::vector<T>&data)
+{
+  auto lengthInBytes = 4*data.size();
+  return ceil( lengthInBytes * 1.33333f );
+}
+
+int UtcDaliBase64EncodingP02(void)
+{
+  tet_infoline( "Test encoding vectors of lengths m .. m+4 encode and decode back to the same length vectors" );
+
+  std::vector<uint32_t> testData;
+  for(int i=0; i<8; ++i ) // 8 chosen to stay within single string output
+  {
+    testData.push_back(i);
+  }
+  Property::Value value;
+  EncodeBase64PropertyData( value, testData );
+
+  std::string output;
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+  std::vector<uint32_t> outData;
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+  DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+  // n+1
+  testData.push_back( 12345 );
+  EncodeBase64PropertyData( value, testData );
+
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+  outData.clear();
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+  DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+  // n+2
+  testData.push_back( 67890 );
+  EncodeBase64PropertyData( value, testData );
+
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+  outData.clear();
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+  DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+  // n+3
+  testData.push_back( -1 );
+  EncodeBase64PropertyData( value, testData );
+
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+  outData.clear();
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+  DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+
+  END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP03(void)
+{
+  tet_infoline( "Test encoding a vector of length 12 has output within single string" );
+
+  std::vector<uint32_t> testData;
+  for(int i=0; i<12; ++i )
+  {
+    testData.push_back(i);
+  }
+  Property::Value value;
+  EncodeBase64PropertyData( value, testData );
+
+  std::string output;
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+  std::vector<uint32_t> outData;
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP04(void)
+{
+  tet_infoline( "Test encoding a vector of length 13 has output split over 2 strings" );
+
+  std::vector<uint32_t> testData;
+  for(int i=0; i<13; ++i )
+  {
+    testData.push_back(i);
+  }
+  Property::Value value;
+  EncodeBase64PropertyData( value, testData );
+
+  auto array = value.GetArray();
+  DALI_TEST_CHECK( array );
+
+  DALI_TEST_EQUALS( array->Count(), 2, TEST_LOCATION );
+
+  std::vector<uint32_t> outData;
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP05(void)
+{
+  tet_infoline( "Test encoding a vector of length 24 has output split over 2 strings" );
+
+  std::vector<uint32_t> testData;
+  for(int i=0; i<24; ++i )
+  {
+    testData.push_back(i);
+  }
+  Property::Value value;
+  EncodeBase64PropertyData( value, testData );
+
+  auto array = value.GetArray();
+  DALI_TEST_CHECK( array );
+
+  DALI_TEST_EQUALS( array->Count(), 2, TEST_LOCATION );
+
+  std::vector<uint32_t> outData;
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP06(void)
+{
+  tet_infoline( "Test encoding a vector of arbitrary length decodes OK." );
+
+  std::vector<uint32_t> testData;
+  for(int i=0; i<97; ++i )
+  {
+    testData.push_back(i);
+  }
+  Property::Value value;
+  EncodeBase64PropertyData( value, testData );
+
+  auto array = value.GetArray();
+  DALI_TEST_CHECK( array );
+
+  std::vector<uint32_t> outData;
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBase64DecodingN01(void)
+{
+  tet_infoline( "Test decoding empty string results in empty data" );
+
+  Property::Value value("");
+  std::vector<uint32_t> outputData;
+  DecodeBase64PropertyData( value, outputData);
+  DALI_TEST_EQUALS( outputData.size(), 0, TEST_LOCATION );
+  END_TEST;
+}
+
+
+int UtcDaliBase64DecodingN02(void)
+{
+  tet_infoline( "Test decoding array with non-string values results in empty data" );
+
+  Property::Array array;
+  array.Resize(2);
+  array[0] = "Stuff, things";
+  array[1] = 1;
+  Property::Value value(array);
+
+  std::vector<uint32_t> outputData;
+  DecodeBase64PropertyData( value, outputData);
+  DALI_TEST_EQUALS( outputData.size(), 0, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliBase64DecodingP01(void)
+{
+  tet_infoline( "Test decoding string of known data gives expected result");
+
+  std::string testInput("//////7+/v4DAgEA");
+  std::vector<uint32_t> expectedResults = { 0xffffffff, 0xfefefefe, 0x00010203 };
+
+  std::vector<uint32_t> outputData;
+  DecodeBase64PropertyData(Property::Value(testInput), outputData);
+
+  DALI_TEST_EQUALS( std::equal( expectedResults.begin(), expectedResults.end(), outputData.begin() ), true,
+                    TEST_LOCATION );
+
+  END_TEST;
+}
index 02446a0..77121d5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1708,3 +1708,70 @@ int UtcDaliImageViewPaddingProperty02(void)
 
   END_TEST;
 }
+
+int UtcDaliImageViewUsingAtlasAndGetNaturalSize(void)
+{
+  ToolkitTestApplication application;
+
+  // Check ImageView with background and main image, to ensure both visuals are marked as loaded
+  ImageView imageView = ImageView::New();
+  Property::Map imageMap;
+  imageMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE;
+  imageMap[ Toolkit::ImageVisual::Property::URL ] = gImage_34_RGBA;
+  imageMap[ Toolkit::ImageVisual::Property::ATLASING ] = true;
+  imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, imageMap );
+  Stage::GetCurrent().Add( imageView );
+
+  // Trigger a potential relayout
+  application.SendNotification();
+  application.Render();
+
+  Vector3 naturalSize = imageView.GetNaturalSize();
+
+  DALI_TEST_EQUALS( naturalSize.width, 34.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( naturalSize.height, 34.0f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliImageViewFillMode(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline( "Create an ImageVisual without padding and set the fill-mode to fill" );
+  tet_infoline( "  There should be no need to change the transform, our size-policy should be relative and size shoudl be [1,1]");
+
+  ImageView imageView = ImageView::New();
+  Property::Map imageMap;
+  imageMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE );
+  imageMap.Add( Toolkit::ImageVisual::Property::URL, gImage_600_RGB );
+  imageMap.Add( DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FittingMode::FILL );
+
+  imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, imageMap );
+
+  Stage::GetCurrent().Add( imageView );
+
+  // Trigger a potential relayout
+  application.SendNotification();
+  application.Render();
+
+  Toolkit::Visual::Base visual = DevelControl::GetVisual( Toolkit::Internal::GetImplementation( imageView ), Toolkit::ImageView::Property::IMAGE );
+  Property::Map returnedMap;
+  visual.CreatePropertyMap( returnedMap );
+
+  Property::Value* value = returnedMap.Find( Toolkit::Visual::Property::TRANSFORM );
+  DALI_TEST_CHECK( value );
+  Property::Map* map = value->GetMap();
+  DALI_TEST_CHECK( map );
+
+  // If there's
+  value = map->Find( Toolkit::Visual::Transform::Property::SIZE );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get< Vector2 >(), Vector2::ONE, TEST_LOCATION ); // Relative size so will take up 100%
+
+  value = map->Find( Toolkit::Visual::Transform::Property::SIZE_POLICY );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get< int >() == Toolkit::Visual::Transform::Policy::RELATIVE );
+
+  END_TEST;
+}
diff --git a/dali-toolkit/devel-api/builder/base64-encoding.cpp b/dali-toolkit/devel-api/builder/base64-encoding.cpp
new file mode 100644 (file)
index 0000000..2799430
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <sstream>
+#include <iterator>
+
+#include <dali/public-api/object/property-value.h>
+#include <dali/public-api/object/property-array.h>
+#include <dali-toolkit/devel-api/builder/base64-encoding.h>
+#include <dali-toolkit/third-party/base-n/basen.hpp>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace
+{
+const int MAX_PROPERTY_STRING_LENGTH(64); // Cuts larger strings into blocks of this size.
+
+bool GetStringFromProperty( const Property::Value& value, std::string& output )
+{
+  bool extracted = false;
+  if( value.Get( output ) )
+  {
+    extracted = true;
+  }
+  else
+  {
+    Property::Array* array = value.GetArray();
+    if( array )
+    {
+      const unsigned int arraySize = array->Size();
+      for( unsigned int i = 0; i < arraySize; ++i )
+      {
+        std::string element;
+        if( array->GetElementAt( i ).Get( element ) )
+        {
+          extracted = true;
+          output += element;
+        }
+        else
+        {
+          // If property in array is anything other than a string, then it is invalid so break and clear output.
+          output.clear();
+          extracted = false;
+          break;
+        }
+      }
+    }
+  }
+  return extracted;
+}
+
+}//anonymous namespace
+
+bool DecodeBase64PropertyData( const Property::Value& value, std::vector<uint32_t>& outputData )
+{
+  bool decoded = false;
+  std::string encodedString;
+
+
+  if( GetStringFromProperty( value, encodedString ) )
+  {
+    std::vector<unsigned char> outputTmpData;
+    outputTmpData.reserve( ceil( encodedString.size() * 0.75f ) );
+    bn::decode_b64( encodedString.begin(), encodedString.end(), std::back_inserter(outputTmpData) );
+
+    outputData.clear();
+    outputData.resize( outputTmpData.size() / sizeof(uint32_t) );
+    // Treat as a block of data
+    memcpy( &outputData[0], &outputTmpData[0], outputTmpData.size() );
+
+    decoded = true;
+  }
+  return decoded;
+}
+
+void EncodeBase64PropertyData( Property::Value& value, const std::vector<uint32_t>& inputData )
+{
+  std::ostringstream oss;
+
+  bn::encode_b64( reinterpret_cast<const char*>(&inputData[0]),
+                  reinterpret_cast<const char*>(&inputData[0]+inputData.size()),
+                  std::ostream_iterator<unsigned char>(oss, "") );
+
+
+  std::string encodedString = oss.str();
+  if( encodedString.length() > MAX_PROPERTY_STRING_LENGTH)
+  {
+    // cut string up into blocks of MAX_PROPERTY_STRING_LENGTH and store to an array
+    auto numStrings = encodedString.length() / MAX_PROPERTY_STRING_LENGTH +
+                      ((encodedString.length() % MAX_PROPERTY_STRING_LENGTH) != 0);
+
+    Property::Array array;
+    for(auto i=0u; i<numStrings; ++i)
+    {
+      array.PushBack( encodedString.substr( i*MAX_PROPERTY_STRING_LENGTH, MAX_PROPERTY_STRING_LENGTH));
+    }
+    value = array;
+  }
+  else
+  {
+    value = encodedString;
+  }
+}
+
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/builder/base64-encoding.h b/dali-toolkit/devel-api/builder/base64-encoding.h
new file mode 100644 (file)
index 0000000..6a691a9
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef DALI_TOOLKIT_BASE64_ENCODING_H
+#define DALI_TOOLKIT_BASE64_ENCODING_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <dali/public-api/object/property.h>
+#include <dali/public-api/common/vector-wrapper.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+/**
+ * @brief Parses a Property::STRING or Property::ARRAY of STRINGS to
+ * retrieve a block of uint32_t data.
+ *
+ * Data can be encoded using the base64 encoding scheme to allow it to be used
+ * in JSON (The property system maps to JSON types).
+ *
+ * @param[in] value The property value to decode
+ * @param[out] outputData The output data block
+ * @return True if a data block was decoded successfully.
+ */
+bool DecodeBase64PropertyData( const Property::Value& value, std::vector<uint32_t>& outputData );
+
+/**
+ * @brief Convert a block of uint32_t data into a Property::STRING or ARRAY of STRINGs
+ * encoded using base64. This allows the data to be mapped to JSON easily.
+ *
+ * @param[out] value The value to write data into (to avoid copying).
+ * @param[in] inputData The input
+ */
+void EncodeBase64PropertyData( Property::Value& value, const std::vector<uint32_t>& inputData );
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+
+#endif // DALI_TOOLKIT_BASE64_ENCODING_H
index 411afe1..e974720 100755 (executable)
@@ -1,6 +1,7 @@
 # Add local source files here
 
 devel_api_src_files = \
+  $(devel_api_src_dir)/builder/base64-encoding.cpp \
   $(devel_api_src_dir)/builder/builder.cpp \
   $(devel_api_src_dir)/builder/json-parser.cpp \
   $(devel_api_src_dir)/builder/tree-node.cpp \
@@ -73,6 +74,7 @@ devel_api_buttons_header_files = \
   $(devel_api_src_dir)/controls/buttons/toggle-button.h
 
 devel_api_builder_header_files = \
+  $(devel_api_src_dir)/builder/base64-encoding.h \
   $(devel_api_src_dir)/builder/builder.h \
   $(devel_api_src_dir)/builder/json-parser.h \
   $(devel_api_src_dir)/builder/tree-node.h
index 11d5389..f709559 100755 (executable)
@@ -271,45 +271,50 @@ void ImageView::OnRelayout( const Vector2& size, RelayoutContainer& container )
     Property::Map transformMap = Property::Map();
 
     Extents padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
+    const Visual::FittingMode fittingMode = Toolkit::GetImplementation(mVisual).GetFittingMode();
 
-    Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
-          Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
-
-    if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
+    if( ( padding != Extents() ) || // If padding is not zero
+        ( fittingMode == Visual::FittingMode::FIT_KEEP_ASPECT_RATIO ) )
     {
-      std::swap( padding.start, padding.end );
-    }
+      Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
+            Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
 
-    auto finalOffset = Vector2( padding.start, padding.top );
+      if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
+      {
+        std::swap( padding.start, padding.end );
+      }
 
-    // remove padding from the size to know how much is left for the visual
-    auto finalSize = size - Vector2( padding.start + padding.end, padding.top + padding.bottom );
+      auto finalOffset = Vector2( padding.start, padding.top );
 
-    // Should provide a transform that handles aspect ratio according to image size
-    if( Toolkit::GetImplementation(mVisual).GetFittingMode() == Visual::FittingMode::FIT_KEEP_ASPECT_RATIO )
-    {
-      auto availableVisualSize = finalSize;
+      // remove padding from the size to know how much is left for the visual
+      auto finalSize = size - Vector2( padding.start + padding.end, padding.top + padding.bottom );
 
-      Vector2 naturalSize;
-      mVisual.GetNaturalSize( naturalSize );
+      // Should provide a transform that handles aspect ratio according to image size
+      if( fittingMode == Visual::FittingMode::FIT_KEEP_ASPECT_RATIO )
+      {
+        auto availableVisualSize = finalSize;
 
-      // scale to fit the padded area
-      finalSize = naturalSize * std::min( ( naturalSize.width  ? ( availableVisualSize.width  / naturalSize.width  ) : 0 ),
-                                          ( naturalSize.height ? ( availableVisualSize.height / naturalSize.height ) : 0 ) );
+        Vector2 naturalSize;
+        mVisual.GetNaturalSize( naturalSize );
 
-      // calculate final offset within the padded area
-      finalOffset += ( availableVisualSize - finalSize ) * .5f;
-    }
+        // scale to fit the padded area
+        finalSize = naturalSize * std::min( ( naturalSize.width  ? ( availableVisualSize.width  / naturalSize.width  ) : 0 ),
+                                            ( naturalSize.height ? ( availableVisualSize.height / naturalSize.height ) : 0 ) );
 
-    // populate the transform map
-    transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, finalOffset )
-                .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY,
-                    Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
-                .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
-                .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN )
-                .Add( Toolkit::Visual::Transform::Property::SIZE, finalSize )
-                .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY,
-                    Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
+        // calculate final offset within the padded area
+        finalOffset += ( availableVisualSize - finalSize ) * .5f;
+      }
+
+      // populate the transform map
+      transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, finalOffset )
+                  .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY,
+                      Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
+                  .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
+                  .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN )
+                  .Add( Toolkit::Visual::Transform::Property::SIZE, finalSize )
+                  .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY,
+                      Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
+    }
 
     mVisual.SetTransformAndSize( transformMap, size );
   }
index dd06d31..2fbfee1 100644 (file)
@@ -116,12 +116,13 @@ void FixedImageCache::LoadBatch()
     AtlasUploadObserver* atlasObserver = nullptr;
     ImageAtlasManagerPtr imageAtlasManager = nullptr;
     Vector4 textureRect;
+    Dali::ImageDimensions textureRectSize;
     auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
     mTextureManager.LoadTexture(
       url, ImageDimensions(), FittingMode::SCALE_TO_FILL,
       SamplingMode::BOX_THEN_LINEAR, maskInfo,
-      synchronousLoading, mImageUrls[ mUrlIndex ].mTextureId, textureRect,
+      synchronousLoading, mImageUrls[ mUrlIndex ].mTextureId, textureRect, textureRectSize,
       atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
       Dali::WrapMode::Type::DEFAULT, this,
       atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED,
index 9f9e623..4854076 100644 (file)
@@ -151,12 +151,13 @@ void RollingGifImageCache::LoadBatch()
       AtlasUploadObserver* atlasObserver = nullptr;
       ImageAtlasManagerPtr imageAtlasManager = nullptr;
       Vector4 textureRect;
+      Dali::ImageDimensions textureRectSize;
       auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
       mTextureManager.LoadTexture(
         mImageUrls[ imageFrame.mFrameNumber ].mUrl, ImageDimensions(), FittingMode::SCALE_TO_FILL,
         SamplingMode::BOX_THEN_LINEAR, maskInfo,
-        synchronousLoading, mImageUrls[ imageFrame.mFrameNumber ].mTextureId, textureRect,
+        synchronousLoading, mImageUrls[ imageFrame.mFrameNumber ].mTextureId, textureRect, textureRectSize,
         atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
         Dali::WrapMode::Type::DEFAULT, NULL,
         atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply );
index bee7234..596ff88 100644 (file)
@@ -151,12 +151,13 @@ void RollingImageCache::LoadBatch()
     AtlasUploadObserver* atlasObserver = nullptr;
     ImageAtlasManagerPtr imageAtlasManager = nullptr;
     Vector4 textureRect;
+    Dali::ImageDimensions textureRectSize;
     auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
     mTextureManager.LoadTexture(
       url, ImageDimensions(), FittingMode::SCALE_TO_FILL,
       SamplingMode::BOX_THEN_LINEAR, maskInfo,
-      synchronousLoading, mImageUrls[ imageFrame.mUrlIndex ].mTextureId, textureRect,
+      synchronousLoading, mImageUrls[ imageFrame.mUrlIndex ].mTextureId, textureRect, textureRectSize,
       atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
       Dali::WrapMode::Type::DEFAULT, this,
       atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED,
index d959c1a..2e4dfb4 100644 (file)
@@ -49,7 +49,7 @@ ImageAtlasManager::~ImageAtlasManager()
 
 TextureSet ImageAtlasManager::Add( Vector4& textureRect,
                                  const std::string& url,
-                                 ImageDimensions size,
+                                 ImageDimensions& size,
                                  FittingMode::Type fittingMode,
                                  bool orientationCorrection,
                                  AtlasUploadObserver* atlasUploadObserver )
@@ -68,6 +68,7 @@ TextureSet ImageAtlasManager::Add( Vector4& textureRect,
   {
     return TextureSet();
   }
+  size = dimensions;
 
   unsigned int i = 0;
   for( AtlasContainer::iterator iter = mAtlasList.begin(); iter != mAtlasList.end(); ++iter)
index 5907ca2..05ed3a5 100644 (file)
@@ -64,7 +64,7 @@ public:
    *
    * @param [out] textureRect The texture area of the resource image in the atlas.
    * @param [in] url The URL of the resource image file to use.
-   * @param [in] size The width and height to fit the loaded image to.
+   * @param [in, out] 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] orientationCorrection Reorient the image to respect any orientation metadata in its header.
    * @param [in] atlasUploadObserver The object to observe the uploading state inside ImageAtlas.
@@ -72,7 +72,7 @@ public:
    */
   TextureSet Add( Vector4& textureRect,
                   const std::string& url,
-                  ImageDimensions size = ImageDimensions(),
+                  ImageDimensions& size,
                   FittingMode::Type fittingMode = FittingMode::DEFAULT,
                   bool orientationCorrection = true,
                   AtlasUploadObserver* atlasUploadObserver = NULL );
index 0e4f018..faeeaec 100644 (file)
@@ -268,6 +268,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
   mLoadPolicy( Toolkit::ImageVisual::LoadPolicy::ATTACHED ),
   mReleasePolicy( Toolkit::ImageVisual::ReleasePolicy::DETACHED ),
   mAtlasRect( 0.0f, 0.0f, 0.0f, 0.0f ),
+  mAtlasRectSize( 0, 0 ),
   mAttemptAtlasing( false ),
   mLoading( false ),
   mOrientationCorrection( true )
@@ -588,8 +589,14 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize )
   }
   else if( mImpl->mRenderer ) // Check if we have a loaded image
   {
-    auto textureSet = mImpl->mRenderer.GetTextures();
+    if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED )
+    {
+      naturalSize.x = mAtlasRectSize.GetWidth();
+      naturalSize.y = mAtlasRectSize.GetHeight();
+      return;
+    }
 
+    auto textureSet = mImpl->mRenderer.GetTextures();
     if( textureSet )
     {
       auto texture = textureSet.GetTexture(0);
@@ -768,7 +775,7 @@ void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& t
 
   textures = textureManager.LoadTexture( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode,
                                          mMaskingData, IsSynchronousResourceLoading(), mTextureId,
-                                         atlasRect, atlasing, mLoading, mWrapModeU,
+                                         atlasRect, mAtlasRectSize, atlasing, mLoading, mWrapModeU,
                                          mWrapModeV, textureObserver, atlasUploadObserver, atlasManager,
                                          mOrientationCorrection, forceReload, preMultiplyOnLoad);
 
index 6e48997..dd63c16 100644 (file)
@@ -374,6 +374,7 @@ private:
   Dali::Toolkit::ImageVisual::LoadPolicy::Type mLoadPolicy;
   Dali::Toolkit::ImageVisual::ReleasePolicy::Type mReleasePolicy;
   Vector4 mAtlasRect;
+  Dali::ImageDimensions mAtlasRectSize;
   bool mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture
   bool mLoading;  ///< True if the texture is still loading.
   bool mOrientationCorrection; ///< true if the image will have it's orientation corrected.
index a08b2c5..c617a51 100644 (file)
@@ -134,8 +134,8 @@ TextureSet TextureManager::LoadTexture(
   const VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode,
   Dali::SamplingMode::Type samplingMode, const MaskingDataPointer& maskInfo,
   bool synchronousLoading, TextureManager::TextureId& textureId, Vector4& textureRect,
-  bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU,
-  Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
+  Dali::ImageDimensions& textureRectSize, bool& atlasingStatus, bool& loadingStatus,
+  Dali::WrapMode::Type wrapModeU, Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
   AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager, bool orientationCorrection,
   TextureManager::ReloadPolicy reloadPolicy, TextureManager::MultiplyOnLoad& preMultiplyOnLoad )
 {
@@ -205,6 +205,11 @@ TextureSet TextureManager::LoadTexture(
         textureSet = TextureSet::New();
         textureSet.SetTexture( 0u, texture );
       }
+      else
+      {
+        textureRectSize.SetWidth(data.GetWidth());
+        textureRectSize.SetHeight(data.GetHeight());
+      }
     }
   }
   else
@@ -212,7 +217,7 @@ TextureSet TextureManager::LoadTexture(
     loadingStatus = true;
     if( atlasingStatus )
     {
-      textureSet = imageAtlasManager->Add( textureRect, url.GetUrl(), desiredSize, fittingMode, true, atlasObserver );
+      textureSet = imageAtlasManager->Add( textureRect, url.GetUrl(), desiredSize, fittingMode, true, atlasObserver);
     }
     if( !textureSet ) // big image, no atlasing or atlasing failed
     {
@@ -245,6 +250,10 @@ TextureSet TextureManager::LoadTexture(
         textureSet = GetTextureSet( textureId );
       }
     }
+    else
+    {
+      textureRectSize = desiredSize;
+    }
   }
 
   if( ! atlasingStatus && textureSet )
index e56fec4..59d191e 100644 (file)
@@ -175,7 +175,10 @@ public:
    * @param[in] maskInfo              Mask info structure
    * @param[in] synchronousLoading    true if the URL should be loaded synchronously
    * @param[out] textureId,           The textureId of the URL
-   * @param[out] textureRect          The rectangle within the texture atlas that this URL occupies
+   * @param[out] textureRect          The rectangle within the texture atlas that this URL occupies,
+   *                                  this is the rectangle in normalized coordinates.
+   * @param[out] textureRectSize      The rectangle within the texture atlas that this URL occupies,
+   *                                  this is the same rectangle in pixels.
    * @param[in,out] atlasingStatus    Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
    *                                  be loaded, and marked successful, but this will be set to false.
    *                                  If atlasing succeeds, this will be set to true.
@@ -203,6 +206,7 @@ public:
                           bool                         synchronousLoading,
                           TextureManager::TextureId&   textureId,
                           Vector4&                     textureRect,
+                          Dali::ImageDimensions&       textureRectSize,
                           bool&                        atlasingStatus,
                           bool&                        loadingStatus,
                           Dali::WrapMode::Type         wrapModeU,
index 70e33f9..b13f65b 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 3;
-const unsigned int TOOLKIT_MICRO_VERSION = 33;
+const unsigned int TOOLKIT_MICRO_VERSION = 34;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
diff --git a/dali-toolkit/third-party/base-n/basen.hpp b/dali-toolkit/third-party/base-n/basen.hpp
new file mode 100644 (file)
index 0000000..3ed31e8
--- /dev/null
@@ -0,0 +1,289 @@
+/**
+ * base-n, 1.0
+ * Copyright (C) 2012 Andrzej Zawadzki (azawadzki@gmail.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+**/
+#ifndef BASEN_HPP
+#define BASEN_HPP
+
+#include <algorithm>
+#include <cctype>
+#include <cassert>
+#include <cstring>
+
+namespace bn
+{
+
+template<class Iter1, class Iter2>
+void encode_b16(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void encode_b32(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void encode_b64(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void decode_b16(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void decode_b32(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void decode_b64(Iter1 start, Iter1 end, Iter2 out);
+
+namespace impl
+{
+
+const int Error = -1;
+
+namespace {
+
+char extract_partial_bits(char value, size_t start_bit, size_t bits_count)
+{
+    assert(start_bit + bits_count < 8);
+    // shift extracted bits to the beginning of the byte
+    char t1 = value >> (8 - bits_count - start_bit);
+    // mask out bits on the left
+    char t2 = t1 & ~(0xff << bits_count);
+    return t2;
+}
+
+char extract_overlapping_bits(char previous, char next, size_t start_bit, size_t bits_count)
+{
+    assert(start_bit + bits_count < 16);
+    size_t bits_count_in_previous = 8 - start_bit;
+    size_t bits_count_in_next = bits_count - bits_count_in_previous;
+    char t1 = previous << bits_count_in_next;
+    char t2 = next >> (8 - bits_count_in_next) & ~(0xff << bits_count_in_next) ;
+    return (t1 | t2) & ~(0xff << bits_count);
+}
+
+}
+
+struct b16_conversion_traits
+{
+    static size_t group_length()
+    {
+       return 4;
+    }
+
+    static char encode(unsigned int index)
+    {
+        const char* const dictionary = "0123456789ABCDEF";
+        assert(index < strlen(dictionary));
+        return dictionary[index];
+    }
+
+    static char decode(char c)
+    {
+        if (c >= '0' && c <= '9') {
+            return c - '0';
+        } else if (c >= 'A' && c <= 'F') {
+            return c - 'A' + 10;
+        }
+        return Error;
+    }
+};
+
+struct b32_conversion_traits
+{
+    static size_t group_length()
+    {
+       return 5;
+    }
+
+    static char encode(unsigned int index)
+    {
+        const char * dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+        assert(index < strlen(dictionary));
+        return dictionary[index];
+    }
+
+    static char decode(char c)
+    {
+        if (c >= 'A' && c <= 'Z') {
+            return c - 'A';
+        } else if (c >= '2' && c <= '7') {
+            return c - '2' + 26;
+        }
+        return Error;
+    }
+};
+
+struct b64_conversion_traits
+{
+    static size_t group_length()
+    {
+       return 6;
+    }
+
+    static char encode(unsigned int index)
+    {
+        const char* const dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+        assert(index < strlen(dictionary));
+        return dictionary[index];
+    }
+
+    static char decode(char c)
+    {
+        const int alph_len = 26;
+        if (c >= 'A' && c <= 'Z') {
+            return c - 'A';
+        } else if (c >= 'a' && c <= 'z') {
+            return c - 'a' + alph_len * 1;
+        } else if (c >= '0' && c <= '9') {
+            return c - '0' + alph_len * 2;
+        } else if (c == '+') {
+            return c - '+' + alph_len * 2 + 10;
+        } else if (c == '/') {
+            return c - '/' + alph_len * 2 + 11;
+        }
+        return Error;
+    }
+};
+
+template<class ConversionTraits, class Iter1, class Iter2>
+void decode(Iter1 start, Iter1 end, Iter2 out)
+{
+    Iter1 iter = start;
+    size_t output_current_bit = 0;
+    char buffer = 0;
+
+    while (iter != end) {
+        if (std::isspace(*iter)) {
+            ++iter;
+            continue;
+        }
+        char value = ConversionTraits::decode(*iter);
+        if (value == Error) {
+            // malformed data, but let's go on...
+            ++iter;
+            continue;
+        }
+        size_t bits_in_current_byte = std::min<size_t>(output_current_bit + ConversionTraits::group_length(), 8) - output_current_bit;
+        if (bits_in_current_byte == ConversionTraits::group_length()) {
+            // the value fits within current byte, so we can extract it directly
+            buffer |= value << (8 - output_current_bit - ConversionTraits::group_length());
+            output_current_bit += ConversionTraits::group_length();
+            // check if we filled up current byte completely; in such case we flush output and continue
+            if (output_current_bit == 8) {
+                *out++ = buffer;
+                buffer = 0;
+                output_current_bit = 0;
+            }
+        } else {
+            // the value spans across the current and the next byte
+            size_t bits_in_next_byte = ConversionTraits::group_length() - bits_in_current_byte;
+            // fill the current byte and flush it to our output
+            buffer |= value >> bits_in_next_byte;
+            *out++ = buffer;
+            buffer = 0;
+            // save the remainder of our value in the buffer; it will be flushed
+            // during next iterations
+            buffer |= value << (8 - bits_in_next_byte);
+            output_current_bit = bits_in_next_byte;
+        }
+        ++iter;
+    }
+}
+
+template<class ConversionTraits, class Iter1, class Iter2>
+void encode(Iter1 start, Iter1 end, Iter2 out)
+{
+    Iter1 iter = start;
+    size_t start_bit = 0;
+    bool has_backlog = false;
+    char backlog = 0;
+
+    while (has_backlog || iter != end) {
+        if (!has_backlog) {
+            if (start_bit + ConversionTraits::group_length() < 8) {
+                // the value fits within single byte, so we can extract it
+                // directly
+                char v = extract_partial_bits(*iter, start_bit, ConversionTraits::group_length());
+                *out++ = ConversionTraits::encode(v);
+                // since we know that start_bit + ConversionTraits::group_length() < 8 we don't need to go
+                // to the next byte
+                start_bit += ConversionTraits::group_length();
+            } else {
+                // our bits are spanning across byte border; we need to keep the
+                // starting point and move over to next byte.
+                backlog = *iter++;
+                has_backlog = true;
+            }
+        } else {
+            // encode value which is made from bits spanning across byte
+            // boundary
+            char v;
+            if (iter == end)
+                 v = extract_overlapping_bits(backlog, 0, start_bit, ConversionTraits::group_length());
+            else
+                 v = extract_overlapping_bits(backlog, *iter, start_bit, ConversionTraits::group_length());
+            *out++ = ConversionTraits::encode(v);
+            has_backlog = false;
+            start_bit = (start_bit + ConversionTraits::group_length()) % 8;
+        }
+    }
+}
+
+} // impl
+
+using namespace bn::impl;
+
+template<class Iter1, class Iter2>
+void encode_b16(Iter1 start, Iter1 end, Iter2 out)
+{
+    encode<b16_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void encode_b32(Iter1 start, Iter1 end, Iter2 out)
+{
+    encode<b32_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void encode_b64(Iter1 start, Iter1 end, Iter2 out)
+{
+    encode<b64_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void decode_b16(Iter1 start, Iter1 end, Iter2 out)
+{
+    decode<b16_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void decode_b32(Iter1 start, Iter1 end, Iter2 out)
+{
+    decode<b32_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void decode_b64(Iter1 start, Iter1 end, Iter2 out)
+{
+    decode<b64_conversion_traits>(start, end, out);
+}
+
+} // bn
+
+#endif // BASEN_HPP
index ab7c82f..82a9ed9 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.3.33
+Version:    1.3.34
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT