Added transparency support in RGB565 bitmap outputs, for gif decoder.
[framework/osp/image-core.git] / src / FMedia_WbmpDecoder.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file   FMedia_WbmpDecoder.c
20  * @brief  This file contains the implementation of _WbmpDecoder class.
21  *
22  */
23 #include <unique_ptr.h>
24 #include <Ecore.h>
25 #include <Evas.h>
26 #include <Ecore_Evas.h>
27 #include <FMediaImageTypes.h>
28 #include <FBaseSysLog.h>
29 #include "FMedia_WbmpDecoder.h"
30
31 namespace Tizen { namespace Media
32 {
33
34 _WbmpDecoder::_WbmpDecoder(void)
35         : __pEvas(null)
36         , __pEcoreEvas(null)
37         , __pImageObj(null)
38 {
39         // Initialize Evas.
40         ecore_evas_init();
41 }
42
43 _WbmpDecoder::~_WbmpDecoder(void)
44 {
45         if (__pImageObj)
46         {
47                 evas_object_image_file_set(__pImageObj, NULL, NULL);
48         }
49         __pImageObj = null;
50
51         if (__pEcoreEvas)
52         {
53                 ecore_evas_free(__pEcoreEvas);
54         }
55
56         ecore_evas_shutdown();
57 }
58
59 result
60 _WbmpDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
61 {
62         result r = E_SUCCESS;
63         Evas_Load_Error evas_error = EVAS_LOAD_ERROR_NONE;
64
65         SysTryReturnResult(NID_MEDIA, __pImageObj == null, E_INVALID_STATE,
66                 "Already constructed");
67         SysTryReturnResult(NID_MEDIA, buffer != null, E_INVALID_ARG,
68                 "Input buffer is null");
69         SysTryReturnResult(NID_MEDIA, length > 0, E_INVALID_ARG,
70                 "Length (%d) should be greater than zero", length);
71
72         // Create new instance of ecore evas.
73         __pEcoreEvas = ecore_evas_new(NULL, 0, 0, 0, 0, NULL);
74         SysTryCatch(NID_MEDIA, __pEcoreEvas, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
75                 "[E_OUT_OF_MEMORY] Failed to create ecore_evas.");
76
77         // Get the instance of ecore's evas
78         __pEvas = ecore_evas_get(__pEcoreEvas);
79         SysTryCatch(NID_MEDIA, __pEvas, r = E_SYSTEM, E_SYSTEM,
80                 "[E_SYSTEM] Failed to get evas.");
81
82         // Create evas object handle to which image will be added.
83         __pImageObj = evas_object_image_add(__pEvas);
84         SysTryCatch(NID_MEDIA, __pImageObj, r = E_SYSTEM, E_SYSTEM,
85                 "[E_SYSTEM] Failed to add object to evas.");
86
87         // Set the canvas colorspace to ARGB8888.
88         evas_object_image_colorspace_set(__pImageObj, EVAS_COLORSPACE_ARGB8888);
89
90         // Set the buffer to be decoded.
91         evas_object_image_memfile_set(__pImageObj, (void*) buffer, length, NULL, NULL);
92         // Check for error in the previous step.
93         evas_error = evas_object_image_load_error_get(__pImageObj);
94         SysTryCatch(NID_MEDIA, evas_error == EVAS_LOAD_ERROR_NONE, r = E_UNSUPPORTED_FORMAT,
95                 E_UNSUPPORTED_FORMAT, "[E_SYSTEM] Failed to add path to evas object, error: %s.",
96                 evas_load_error_str(evas_error));
97
98         return r;
99
100 CATCH:
101         if (__pImageObj)
102         {
103                 evas_object_image_file_set(__pImageObj, NULL, NULL);
104                 __pImageObj = null;
105         }
106
107         if (__pEcoreEvas)
108         {
109                 ecore_evas_free(__pEcoreEvas);
110                 __pEcoreEvas = null;
111         }
112
113         return r;
114 }
115
116 byte*
117 _WbmpDecoder::DecodeN(int& outLength)
118 {
119         Evas_Colorspace colorSpace = EVAS_COLORSPACE_YCBCR420TM12601_PL;
120         int width = 0;
121         int height = 0;
122         byte* pEvasOutBuf = null;
123         std::unique_ptr<byte[]> pOutBuf;
124
125         SysTryReturn(NID_MEDIA, __pImageObj, null, E_INVALID_STATE,
126                 "Not yet constructed");
127
128         // Calculate size of output from dimensions and color format
129         evas_object_image_size_get(__pImageObj, &width, &height);
130
131         SysTryReturn(NID_MEDIA, (width && height), null, E_INVALID_DATA,
132                 "[E_INVALID_DATA] Evas returned invalid dimensions %d x %d.", width, height);
133
134         outLength = width * height * 4; // 4 because cs is set to EVAS_COLORSPACE_ARGB8888
135
136         pOutBuf.reset(new (std::nothrow) byte[outLength]);
137         SysTryReturn(NID_MEDIA, pOutBuf.get(), null, E_OUT_OF_MEMORY,
138                 "[E_OUT_OF_MEMORY] Failed to allocate %d bytes for decoder output.", outLength);
139
140         pEvasOutBuf = (byte*) evas_object_image_data_get(__pImageObj, true);
141         SysTryReturn(NID_MEDIA, pEvasOutBuf, null, E_SYSTEM,
142                 "[E_SYSTEM] Evas returned empty buffer.");
143         colorSpace = evas_object_image_colorspace_get(__pImageObj);
144
145         memcpy(pOutBuf.get(), pEvasOutBuf, outLength);
146
147         SetLastResult(E_SUCCESS);
148         return pOutBuf.release();
149 }
150
151 result
152 _WbmpDecoder::SetDecodingRegion(int x, int y, int width, int height)
153 {
154         return E_UNSUPPORTED_OPERATION;
155 }
156
157 result
158 _WbmpDecoder::GetDimension(int& width, int& height)
159 {
160         SysTryReturnResult(NID_MEDIA, __pImageObj, E_INVALID_STATE, "Not yet constructed");
161         evas_object_image_size_get(__pImageObj, &width, &height);
162
163         return E_SUCCESS;
164 }
165
166 MediaPixelFormat
167 _WbmpDecoder::GetPixelFormat(void)
168 {
169         MediaPixelFormat pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
170
171         SysTryReturn(NID_MEDIA, __pImageObj, MEDIA_PIXEL_FORMAT_NONE, E_INVALID_STATE, "[E_INVALID_STATE]");
172
173         pixelFormat = MEDIA_PIXEL_FORMAT_RGBA8888;
174
175         SetLastResult(E_SUCCESS);
176
177         return pixelFormat;
178 }
179 }} // Tizen::Media