Added transparency support in RGB565 bitmap outputs, for gif decoder.
[platform/framework/native/image.git] / src / FMedia_GifDecoderImpl.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_GifDecoder.cpp
20 // @brief  This file has implementatoin details of GifDecoder class .
21 //
22 #include <unique_ptr.h>
23 #include <FGrpDimension.h>
24 #include <FGrpBitmap.h>
25 #include <FBaseLong.h>
26 #include <FBaseSysLog.h>
27 #include <FMediaTypes.h>
28 #include "FMedia_MediaUtil.h"
29 #include "FMedia_GifDecoder.h"
30 #include "FMedia_GifDecoderImpl.h"
31
32 using namespace Tizen::Base;
33 using namespace Tizen::Graphics;
34
35 namespace Tizen { namespace Media
36 {
37
38
39 _GifDecoderImpl::_GifDecoderImpl()
40 {
41 }
42
43 _GifDecoderImpl::~_GifDecoderImpl()
44 {
45 }
46
47 result
48 _GifDecoderImpl::Construct(const Tizen::Base::String& filePath, MediaPixelFormat pixelFormat)
49 {
50         result r = E_SUCCESS;
51         std::unique_ptr<ByteBuffer> pByteBuffer;
52
53         SysTryReturnResult(NID_MEDIA, __pGifDecoder.get() == null, E_INVALID_STATE, "Already constructed");
54         __pGifDecoder.reset(new (std::nothrow) _GifDecoder);
55         SysTryReturnResult(NID_MEDIA, __pGifDecoder.get(), E_OUT_OF_MEMORY, "could not create _GifDecoder");
56
57         SysTryReturnResult(NID_MEDIA, (pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888 || pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE),
58                         E_INVALID_ARG, "Invalid Pixel Format");
59
60         pByteBuffer.reset(_MediaUtil::FileToBufferN(filePath, 0));
61         r = GetLastResult();
62         SysTryReturn(NID_MEDIA, pByteBuffer.get() != null, r, r, "FiltToeBufferN:%S", filePath.GetPointer());
63         r = __pGifDecoder->Construct(pByteBuffer->GetPointer(), pByteBuffer->GetLimit(), pixelFormat);
64         if (r != E_SUCCESS)
65         {
66                 SysLogException(NID_MEDIA, r, "_GifDecoder::Construct failed");
67         }
68         return r;
69 }
70
71 result
72 _GifDecoderImpl::Construct(const Tizen::Base::ByteBuffer& srcBuf, MediaPixelFormat pixelFormat)
73 {
74         result r = E_SUCCESS;
75         SysTryReturnResult(NID_MEDIA, __pGifDecoder.get() == null, E_INVALID_STATE, "Already constructed");
76         __pGifDecoder.reset(new (std::nothrow) _GifDecoder);
77         SysTryReturnResult(NID_MEDIA, __pGifDecoder, E_OUT_OF_MEMORY, "could not create _GifDecoder");
78
79         SysTryReturnResult(NID_MEDIA, (pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888 || pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE),
80                         E_INVALID_ARG, "Invalid Pixel Format");
81         r = __pGifDecoder->Construct(srcBuf.GetPointer(), srcBuf.GetLimit(), pixelFormat);
82         if (r != E_SUCCESS)
83         {
84                 SysLogException(NID_MEDIA, r, "_GifDecoder::Construct failed");
85         }
86         return r;
87 }
88
89 int
90 _GifDecoderImpl::GetWidth()const
91 {
92         Dimension dim;
93         result r = E_SUCCESS;
94         SysTryReturnResult(NID_MEDIA, __pGifDecoder.get(), E_INVALID_STATE, "not constructed");
95         r = __pGifDecoder->GetDimension(dim.width, dim.height);
96         SysTryReturn(NID_MEDIA, r == E_SUCCESS, 0, r, "[%s] propagated", GetErrorMessage(r));
97         return dim.width;
98 }
99
100 int
101 _GifDecoderImpl::GetHeight()const
102 {
103         Dimension dim;
104         result r = E_SUCCESS;
105         SysTryReturnResult(NID_MEDIA, __pGifDecoder.get(), E_INVALID_STATE, "not constructed");
106         r = __pGifDecoder->GetDimension(dim.width, dim.height);
107         SysTryReturn(NID_MEDIA, r == E_SUCCESS, 0, r, "[%s] propagated", GetErrorMessage(r));
108         return dim.height;
109 }
110
111 Tizen::Base::ByteBuffer*
112 _GifDecoderImpl::GetNextFrameN(long& duration)
113 {
114         result r = E_SUCCESS;
115         std::unique_ptr<ByteBuffer> pBuf;
116         std::unique_ptr<byte[]> pOutBuf;
117         int outLength = 0;
118         Long longValue;
119
120         SysTryReturn(NID_MEDIA, __pGifDecoder.get(), null, E_INVALID_STATE, "not constructed");
121         pOutBuf.reset(__pGifDecoder->DecodeN(outLength));
122         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
123         if (!pOutBuf.get())
124         {
125                 SetLastResult(E_SUCCESS);
126                 return null;
127         }
128         pBuf.reset(new (std::nothrow) ByteBuffer());
129         SysTryReturn(NID_MEDIA, pBuf.get(), null, GetLastResult(),
130                         "new ByteBuffer:%s", GetErrorMessage(GetLastResult()));
131         r = pBuf.get()->Construct(outLength);
132         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
133                         "[%s] buf.Construct. %d", GetErrorMessage(r), outLength);
134         r = pBuf.get()->SetArray(pOutBuf.get(), 0, outLength);
135         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
136         pBuf.get()->Flip();
137
138         r = __pGifDecoder->GetValue(L"duration", longValue);
139         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
140                            "[%s] dec.GetValue(duration)", GetErrorMessage(r));
141         duration = longValue.ToLong();
142         SetLastResult(E_SUCCESS);
143         return pBuf.release();
144 }
145
146 Tizen::Graphics::Bitmap*
147 _GifDecoderImpl::GetNextBitmapN(long& duration, Tizen::Graphics::BufferScaling bufferScaling)
148 {
149         std::unique_ptr<Bitmap> pBitmap;
150         std::unique_ptr<ByteBuffer> pByteBuffer;
151         BitmapPixelFormat pixelFormat = BITMAP_PIXEL_FORMAT_MIN;
152         Dimension dim;
153         result r = E_SUCCESS;
154
155         SysTryReturn(NID_MEDIA, __pGifDecoder.get(), null, E_INVALID_STATE, "not constructed");
156         pByteBuffer.reset(GetNextFrameN(duration));
157         SysTryReturn(NID_MEDIA, GetLastResult() == E_SUCCESS, null, GetLastResult(), "GetNextFameN failed ");
158
159         if (pByteBuffer.get())
160         {
161                 pBitmap.reset(new (std::nothrow) Bitmap);
162                 SysTryReturn(NID_MEDIA, pBitmap.get(), pBitmap.get(), E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] could not allocate memory to bitmap");
163                 __pGifDecoder->GetDimension(dim.width, dim.height);
164                 pixelFormat = (__pGifDecoder->GetPixelFormat() == MEDIA_PIXEL_FORMAT_RGB565LE)
165                                         ? BITMAP_PIXEL_FORMAT_RGB565 : BITMAP_PIXEL_FORMAT_ARGB8888;
166                 r = pBitmap->Construct(*pByteBuffer.get(), dim, pixelFormat, bufferScaling);
167                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null,r, "pBmp->Construct:%s", GetErrorMessage(r));
168         }
169         SetLastResult(E_SUCCESS);
170         return pBitmap.release();
171 }
172
173 }} // Tizen::Media