2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "pixmap-image-impl.h"
23 #include <Ecore_Wayland.h>
24 #include <dali/integration-api/debug.h>
25 #include <render-surface.h>
28 #include <gl/egl-image-extensions.h>
29 #include <gl/egl-factory.h>
30 #include <adaptor-impl.h>
32 // Allow this to be encoded and saved:
33 #include <platform-abstractions/slp/resource-loader/resource-loader.h>
34 #include <platform-abstractions/slp/resource-loader/loader-jpeg.h>
35 #include <platform-abstractions/slp/resource-loader/loader-png.h>
45 using Dali::Integration::PixelBuffer;
47 // Pieces needed to save compressed images (temporary location while plumbing):
52 * Simple function to tell intended image file format from filename
54 FileFormat GetFormatFromFileName( const std::string& filename )
56 if (filename.length() < 5)
58 DALI_LOG_WARNING("Invalid (short) filename.");
60 FileFormat format(INVALID_FORMAT);
62 const std::size_t filenameSize = filename.length();
64 if(filenameSize >= 4){ // Avoid throwing out_of_range or failing silently if exceptions are turned-off on the compare(). (http://www.cplusplus.com/reference/string/string/compare/)
65 if( !filename.compare( filenameSize - 4, 4, ".jpg" )
66 || !filename.compare( filenameSize - 4, 4, ".JPG" ) )
70 else if( !filename.compare( filenameSize - 4, 4, ".png" )
71 || !filename.compare( filenameSize - 4, 4, ".PNG" ) )
75 else if( !filename.compare( filenameSize - 4, 4, ".bmp" )
76 || !filename.compare( filenameSize - 4, 4, ".BMP" ) )
80 else if( !filename.compare( filenameSize - 4, 4, ".gif" )
81 || !filename.compare( filenameSize - 4, 4, ".GIF" ) )
85 else if( !filename.compare( filenameSize - 4, 4, ".ico" )
86 || !filename.compare( filenameSize - 4, 4, ".ICO" ) )
90 else if(filenameSize >= 5){
91 if( !filename.compare( filenameSize - 5, 5, ".jpeg" )
92 || !filename.compare( filenameSize - 5, 5, ".JPEG" ) )
102 bool EncodeToFormat( const PixelBuffer* pixelBuffer, std::vector< unsigned char >& encodedPixels, FileFormat formatEncoding, std::size_t width, std::size_t height, Pixel::Format pixelFormat )
104 switch( formatEncoding )
108 return SlpPlatform::EncodeToJpeg( pixelBuffer, encodedPixels, width, height, pixelFormat );
113 return SlpPlatform::EncodeToPng( pixelBuffer, encodedPixels, width, height, pixelFormat );
118 DALI_LOG_ERROR("Format not supported for image encoding (supported formats are PNG and JPEG)");
125 bool EncodeToFile(const PixelBuffer * const pixelBuffer, const std::string& filename, const Pixel::Format pixelFormat, const std::size_t width, const std::size_t height)
127 DALI_ASSERT_DEBUG(pixelBuffer != 0 && filename.size() > 4 && width > 0 && height > 0);
128 std::vector< unsigned char > pixbufEncoded;
129 const FileFormat format = GetFormatFromFileName( filename );
130 const bool encodeResult = EncodeToFormat( pixelBuffer, pixbufEncoded, format, width, height, pixelFormat );
133 DALI_LOG_ERROR("Encoding pixels failed");
136 return SlpPlatform::ResourceLoader::SaveFile( filename, pixbufEncoded );
140 PixmapImage* PixmapImage::New(unsigned int width, unsigned int height, Dali::PixmapImage::ColorDepth depth, Dali::Adaptor& adaptor, Any pixmap )
142 PixmapImage* image = new PixmapImage( width, height, depth, adaptor, pixmap );
143 DALI_ASSERT_DEBUG( image && "PixmapImage allocation failed." );
145 // 2nd phase construction
146 if(image) //< Defensive in case we ever compile without exceptions.
154 PixmapImage::PixmapImage(unsigned int width, unsigned int height, Dali::PixmapImage::ColorDepth depth, Dali::Adaptor& adaptor, Any pixmap)
158 mPixelFormat(Pixel::RGB888),
160 mAdaptor(Internal::Adaptor::Adaptor::GetImplementation(adaptor)),
165 void PixmapImage::Initialize()
169 PixmapImage::~PixmapImage()
171 // Lost the opportunity to call GlExtensionDestroy() if Adaptor is destroyed first
172 if( Adaptor::IsAvailable() )
174 // GlExtensionDestroy() called from GLCleanup on the render thread. Checking this is done here.
175 // (mEglImageKHR is now read/written from different threads although ref counted destruction
176 // should mean this isnt concurrent)
177 DALI_ASSERT_ALWAYS( NULL == mEglImageKHR && "NativeImage GL resources have not been properly cleaned up" );
181 Any PixmapImage::GetPixmap(Dali::PixmapImage::PixmapAPI api) const
186 Any PixmapImage::GetDisplay() const
191 bool PixmapImage::GetPixels(std::vector<unsigned char>& pixbuf, unsigned& width, unsigned& height, Pixel::Format& pixelFormat) const
196 bool PixmapImage::EncodeToFile(const std::string& filename) const
198 std::vector< unsigned char > pixbuf;
199 unsigned int width(0), height(0);
200 Pixel::Format pixelFormat;
202 if(GetPixels(pixbuf, width, height, pixelFormat))
204 return Dali::Internal::Adaptor::EncodeToFile(&pixbuf[0], filename, pixelFormat, width, height);
209 bool PixmapImage::GlExtensionCreate()
214 void PixmapImage::GlExtensionDestroy()
216 EglImageExtensions* eglImageExtensions = GetEglImageExtensions();
218 eglImageExtensions->DestroyImageKHR(mEglImageKHR);
223 unsigned int PixmapImage::TargetTexture()
225 EglImageExtensions* eglImageExtensions = GetEglImageExtensions();
227 eglImageExtensions->TargetTextureKHR(mEglImageKHR);
232 int PixmapImage::GetPixelDepth(Dali::PixmapImage::ColorDepth depth) const
236 case Dali::PixmapImage::COLOR_DEPTH_8:
240 case Dali::PixmapImage::COLOR_DEPTH_16:
244 case Dali::PixmapImage::COLOR_DEPTH_24:
248 case Dali::PixmapImage::COLOR_DEPTH_32:
254 DALI_ASSERT_DEBUG(0 && "unknown color enum");
260 void PixmapImage::SetPixelFormat(int depth)
262 // store the pixel format based on the depth
267 mPixelFormat = Pixel::A8;
272 mPixelFormat = Pixel::RGB565;
277 mPixelFormat = Pixel::RGBA8888;
283 mPixelFormat = Pixel::RGB888;
289 void PixmapImage::GetPixmapDetails()
293 EglImageExtensions* PixmapImage::GetEglImageExtensions() const
295 EglFactory& factory = mAdaptor.GetEGLFactory();
296 EglImageExtensions* egl = factory.GetImageExtensions();
297 DALI_ASSERT_DEBUG( egl && "EGL Image Extensions not initialized" );
301 } // namespace Adaptor
303 } // namespace internal