[dali_2.3.24] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / environment-map-loader.cpp
index 306d3b2..619732d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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 <dali-scene3d/public-api/loader/environment-map-loader.h>
 
 // EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/integration-api/pixel-data-integ.h>
 #include <string.h>
 #include <cmath>
 #include <filesystem>
 
 // INTERNAL INCLUDES
+#include <dali-scene3d/internal/common/image-resource-loader.h>
 #include <dali-scene3d/public-api/loader/ktx-loader.h>
 
+#include <dali/integration-api/debug.h>
+
 namespace Dali
 {
 namespace
@@ -74,39 +77,54 @@ uint8_t* GetCroppedBuffer(uint8_t* sourceBuffer, uint32_t bytesPerPixel, uint32_
   uint32_t byteSize   = bytesPerPixel * xFaceSize * yFaceSize;
   uint8_t* destBuffer = reinterpret_cast<uint8_t*>(malloc(byteSize + 4u));
 
-  int32_t srcStride  = width * bytesPerPixel;
-  int32_t destStride = xFaceSize * bytesPerPixel;
-  int32_t srcOffset  = xOffset * bytesPerPixel + yOffset * srcStride;
-  int32_t destOffset = 0;
-  for(uint16_t row = yOffset; row < yOffset + yFaceSize; ++row)
+  if(DALI_LIKELY(destBuffer))
+  {
+    int32_t srcStride  = width * bytesPerPixel;
+    int32_t destStride = xFaceSize * bytesPerPixel;
+    int32_t srcOffset  = xOffset * bytesPerPixel + yOffset * srcStride;
+    int32_t destOffset = 0;
+    for(uint16_t row = yOffset; row < yOffset + yFaceSize; ++row)
+    {
+      memcpy(destBuffer + destOffset, sourceBuffer + srcOffset, destStride);
+      srcOffset += srcStride;
+      destOffset += destStride;
+    }
+  }
+  else
   {
-    memcpy(destBuffer + destOffset, sourceBuffer + srcOffset, destStride);
-    srcOffset += srcStride;
-    destOffset += destStride;
+    DALI_LOG_ERROR("malloc is failed. request malloc size : %u\n", byteSize + 4u);
   }
 
   return destBuffer;
 }
 
-PixelData GetCubeFace(Devel::PixelBuffer pixelBuffer, uint32_t faceIndex, CubeType cubeType, float faceWidth, float faceHeight)
+PixelData GetCubeFace(Dali::PixelData cubePixelData, uint32_t faceIndex, CubeType cubeType, float faceWidth, float faceHeight)
 {
-  PixelData pixelData;
+  PixelData cubeFacePixelData;
   if(cubeType != NONE)
   {
-    uint8_t* imageBuffer   = pixelBuffer.GetBuffer();
-    uint32_t bytesPerPixel = Pixel::GetBytesPerPixel(pixelBuffer.GetPixelFormat());
-    uint32_t imageWidth    = pixelBuffer.GetWidth();
-    uint32_t imageHeight   = pixelBuffer.GetHeight();
-
-    uint32_t xOffset = CUBEMAP_INDEX_X[cubeType][faceIndex] * static_cast<uint32_t>(faceWidth);
-    uint32_t yOffset = CUBEMAP_INDEX_Y[cubeType][faceIndex] * static_cast<uint32_t>(faceHeight);
-
-    uint32_t finalFaceWidth  = (xOffset + static_cast<uint32_t>(faceWidth) < imageWidth) ? static_cast<uint32_t>(faceWidth) : imageWidth - xOffset;
-    uint32_t finalFaceHeight = (yOffset + static_cast<uint32_t>(faceHeight) < imageHeight) ? static_cast<uint32_t>(faceHeight) : imageHeight - yOffset;
-    uint8_t* tempImageBuffer = GetCroppedBuffer(imageBuffer, bytesPerPixel, imageWidth, imageHeight, xOffset, yOffset, finalFaceWidth, finalFaceHeight);
-    pixelData                = PixelData::New(tempImageBuffer, finalFaceWidth * finalFaceHeight * bytesPerPixel, finalFaceWidth, finalFaceHeight, pixelBuffer.GetPixelFormat(), PixelData::FREE);
+    auto imagePixelFormat = cubePixelData.GetPixelFormat();
+    if(!Dali::Pixel::IsCompressed(imagePixelFormat))
+    {
+      uint8_t* imageBuffer   = Dali::Integration::GetPixelDataBuffer(cubePixelData).buffer;
+      uint32_t bytesPerPixel = Pixel::GetBytesPerPixel(imagePixelFormat);
+      uint32_t imageWidth    = cubePixelData.GetWidth();
+      uint32_t imageHeight   = cubePixelData.GetHeight();
+
+      uint32_t xOffset = CUBEMAP_INDEX_X[cubeType][faceIndex] * static_cast<uint32_t>(faceWidth);
+      uint32_t yOffset = CUBEMAP_INDEX_Y[cubeType][faceIndex] * static_cast<uint32_t>(faceHeight);
+
+      uint32_t finalFaceWidth  = (xOffset + static_cast<uint32_t>(faceWidth) < imageWidth) ? static_cast<uint32_t>(faceWidth) : imageWidth - xOffset;
+      uint32_t finalFaceHeight = (yOffset + static_cast<uint32_t>(faceHeight) < imageHeight) ? static_cast<uint32_t>(faceHeight) : imageHeight - yOffset;
+      uint8_t* tempImageBuffer = GetCroppedBuffer(imageBuffer, bytesPerPixel, imageWidth, imageHeight, xOffset, yOffset, finalFaceWidth, finalFaceHeight);
+
+      if(DALI_LIKELY(tempImageBuffer))
+      {
+        cubeFacePixelData = Dali::Integration::NewPixelDataWithReleaseAfterUpload(tempImageBuffer, finalFaceWidth * finalFaceHeight * bytesPerPixel, finalFaceWidth, finalFaceHeight, 0u, imagePixelFormat, PixelData::FREE);
+      }
+    }
   }
-  return pixelData;
+  return cubeFacePixelData;
 }
 
 /**
@@ -124,12 +142,12 @@ bool LoadEnvironmentMapData(const std::string& environmentMapUrl, Scene3D::Loade
     return false;
   }
 
-  Devel::PixelBuffer pixelBuffer = LoadImageFromFile(environmentMapUrl);
-  if(pixelBuffer)
+  Dali::PixelData pixelData = Dali::Scene3D::Internal::ImageResourceLoader::GetCachedPixelData(environmentMapUrl);
+  if(pixelData)
   {
     CubeType cubeType    = NONE;
-    uint32_t imageWidth  = pixelBuffer.GetWidth();
-    uint32_t imageHeight = pixelBuffer.GetHeight();
+    uint32_t imageWidth  = pixelData.GetWidth();
+    uint32_t imageHeight = pixelData.GetHeight();
     /**
      * If the environment map type is not EQUIRECTANGULAR,
      * The type should be defined internally.
@@ -167,19 +185,29 @@ bool LoadEnvironmentMapData(const std::string& environmentMapUrl, Scene3D::Loade
       }
       for(uint32_t i = 0; i < 6; ++i)
       {
-        environmentMapData.mPixelData[i][0] = GetCubeFace(pixelBuffer, i, cubeType, faceWidth, faceHeight);
+        environmentMapData.mPixelData[i][0] = GetCubeFace(pixelData, i, cubeType, faceWidth, faceHeight);
       }
-      uint32_t mipmap = static_cast<uint32_t>(1 + std::floor(std::log2(std::max(environmentMapData.mPixelData[0][0].GetWidth(), environmentMapData.mPixelData[0][0].GetHeight()))));
-      environmentMapData.SetMipmapLevels(mipmap);
       environmentMapData.SetEnvironmentMapType(Scene3D::EnvironmentMapType::CUBEMAP);
     }
     else
     {
       environmentMapData.mPixelData.resize(1);
       environmentMapData.mPixelData[0].resize(1);
-      environmentMapData.mPixelData[0][0] = Devel::PixelBuffer::Convert(pixelBuffer);
+      environmentMapData.mPixelData[0][0] = pixelData;
       environmentMapData.SetEnvironmentMapType(Scene3D::EnvironmentMapType::EQUIRECTANGULAR);
     }
+
+    if(!environmentMapData.mPixelData.empty() && !environmentMapData.mPixelData[0].empty() && environmentMapData.mPixelData[0][0])
+    {
+      const uint32_t pixelDataWidth  = environmentMapData.mPixelData[0][0].GetWidth();
+      const uint32_t pixelDataHeight = environmentMapData.mPixelData[0][0].GetHeight();
+
+      if(pixelDataWidth > 0u && pixelDataHeight > 0u)
+      {
+        uint32_t mipmap = static_cast<uint32_t>(1 + std::floor(std::log2(std::min(pixelDataWidth, pixelDataHeight))));
+        environmentMapData.SetMipmapLevels(mipmap);
+      }
+    }
     return true;
   }
   return false;
@@ -197,7 +225,6 @@ bool LoadEnvironmentMap(const std::string& environmentMapUrl, EnvironmentMapData
   std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
 
   bool successed = (extension == KTX_EXTENSION) ? Dali::Scene3D::Loader::LoadKtxData(environmentMapUrl, environmentMapData) : LoadEnvironmentMapData(environmentMapUrl, environmentMapData);
-
   return successed;
 }