Tizen 2.1 base
[platform/framework/native/image.git] / src / FMedia_ImageBufferImpl.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_ImageBufferImpl.cpp
20  * @brief  This file contains the implementation of ImageBuffer's impl layer.
21  */
22
23 #include <unique_ptr.h>
24 #include <FBaseColArrayListT.h>
25 #include <FMediaImageBuffer.h>
26 #include <FBaseInternalTypes.h>
27 #include <FBaseSysLog.h>
28 #include <FApp_AppInfo.h>
29 #include <FMedia_MediaUtil.h>
30 #include <FMediaImageTypes.h>
31 #include "FMedia_ImageBufferImpl.h"
32 #include "FMedia_ImageUtil.h"
33 #include "FMedia_ImageUtilImpl.h"
34 #include "FMedia_ImageDecoder.h"
35 #include "FMedia_ImageEncoder.h"
36 #include "FMedia_ColorConverter.h"
37 #include "FMedia_ExifUtil.h"
38
39 using namespace Tizen::Graphics;
40 using namespace Tizen::Base;
41 using namespace Tizen::Base::Collection;
42 using namespace Tizen::Io;
43 using namespace Tizen::App;
44
45 namespace Tizen { namespace Media
46 {
47
48 #define ISSUPPORTED(x)                                                                                                                  \
49     ((x == MEDIA_PIXEL_FORMAT_YUV420P) || (x == MEDIA_PIXEL_FORMAT_BGRA8888) || \
50         (x == MEDIA_PIXEL_FORMAT_RGB565LE) || (x == MEDIA_PIXEL_FORMAT_GRAY))
51
52 enum _ExifOrientation
53 {
54         EXIF_ORIENTATION_TOP_LEFT = 0x01,    /**< The row #0 is top, column #0 is left */
55         EXIF_ORIENTATION_TOP_RIGHT,      /**< The row #0 is top, column #0 is right */
56         EXIF_ORIENTATION_BOTTOM_RIGHT,   /**< The row #0 is bottom, column #0 is right */
57         EXIF_ORIENTATION_BOTTOM_LEFT,    /**< The row #0 is bottom, column #0 is left */
58         EXIF_ORIENTATION_LEFT_TOP,       /**< The row #0 is left, column #0 is top */
59         EXIF_ORIENTATION_RIGHT_TOP,      /**< The row #0 is right, column #0 is top */
60         EXIF_ORIENTATION_RIGHT_BOTTOM,   /**< The row #0 is right, column #0 is bottom */
61         EXIF_ORIENTATION_LEFT_BOTTOM,    /**< The row #0 is left, column #0 is bottom */
62 };
63
64 typedef struct {
65         ImageRotationType rotateType;
66         ImageFlipType flipType;
67         bool dimensionSwitch;
68 } _ImageExifInfo;
69
70 static const _ImageExifInfo _IMAGE_ROTATE_FLIP_MAP[] = {
71         { IMAGE_ROTATION_0,   IMAGE_FLIP_NONE,       false }, /* NONE         */
72         { IMAGE_ROTATION_0,   IMAGE_FLIP_NONE,       false }, /* TOP_LEFT     */
73         { IMAGE_ROTATION_0,   IMAGE_FLIP_VERTICAL,   false }, /* TOP_RIGHT    */
74         { IMAGE_ROTATION_180, IMAGE_FLIP_NONE,       false }, /* BOTTOM_RIGHT */
75         { IMAGE_ROTATION_0,   IMAGE_FLIP_HORIZONTAL, false }, /* BOTTOM_LEFT  */
76         { IMAGE_ROTATION_90,  IMAGE_FLIP_VERTICAL,   true  }, /* LEFT_TOP     */
77         { IMAGE_ROTATION_90,  IMAGE_FLIP_NONE,       true  }, /* RIGHT_TOP    */
78         { IMAGE_ROTATION_90,  IMAGE_FLIP_HORIZONTAL, true  }, /* RIGHT_BOTTOM */
79         { IMAGE_ROTATION_270, IMAGE_FLIP_NONE,       true  }  /* LEFT_BOTTOM  */
80 };
81
82 static const MediaPixelFormat _IMAGE_BUFFER_PIXEL_FORMATS[] =
83 {
84         MEDIA_PIXEL_FORMAT_RGB565LE,
85         MEDIA_PIXEL_FORMAT_BGRA8888,
86         MEDIA_PIXEL_FORMAT_YUV420P
87 };
88
89 _ImageBufferImpl::_ImageBufferImpl(void)
90         : __pBuffer(null)
91         , __width(0)
92         , __height(0)
93         , __pixelFormat(MEDIA_PIXEL_FORMAT_NONE)
94         , __isLocked(false)
95 {
96 }
97
98 _ImageBufferImpl::~_ImageBufferImpl(void)
99 {
100 }
101
102 result
103 _ImageBufferImpl::Construct(int width, int height, MediaPixelFormat pixelFormat)
104 {
105         result r = E_SUCCESS;
106         int length = 0;
107
108         __width = width;
109         __height = height;
110         __pixelFormat = pixelFormat;
111
112         SysTryReturn(NID_MEDIA, IsSupportedPixelFormat(pixelFormat) == true , null, E_UNSUPPORTED_FORMAT,
113                 "[E_UNSUPPORTED_FORMAT] The specified pixelFormat is not supported.")
114
115         length = _ImageUtil::GetBufferSize(__pixelFormat, __width, __height);
116         SysTryReturn(NID_MEDIA, length > 0, E_INVALID_ARG, E_INVALID_ARG,
117                 "[E_INVALID_ARG] Check inputs: (%d x %d), pixel format (%d).",
118                 __width, __height, __pixelFormat);
119
120         __pBuffer.reset(new (std::nothrow) ByteBuffer);
121         SysTryReturn(NID_MEDIA, __pBuffer.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
122                 "[E_OUT_OF_MEMORY] Construct instance failed.");
123
124         r = __pBuffer->Construct(length);
125         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
126                 "[%s] Construct instance failed.", GetErrorMessage(r));
127
128         return r;
129 }
130
131 result
132 _ImageBufferImpl::Construct(int width, int height, MediaPixelFormat pixelFormat,
133         const byte* pData, int length)
134 {
135         result r = E_SUCCESS;
136         int reqBufferSize = 0;
137
138         SysTryReturn(NID_MEDIA, IsSupportedPixelFormat(pixelFormat) == true , E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
139                 "[E_UNSUPPORTED_FORMAT] The specified pixelFormat is not supported.")
140
141         SysTryReturn(NID_MEDIA, (width > 0) && (height > 0), E_INVALID_ARG, E_INVALID_ARG,
142                 "[E_INVALID_ARG] Dimensions should be greater than zero : (%d x %d).", width, height);
143
144         SysTryReturn(NID_MEDIA, ISSUPPORTED(pixelFormat) == true, E_INVALID_ARG, E_INVALID_ARG,
145                 "[E_INVALID_ARG] Pixelformat is not supported : %d.", pixelFormat);
146
147         reqBufferSize = _ImageUtil::GetBufferSize(pixelFormat, width, height);
148
149         if (pData != null)
150         {
151                 SysTryReturn(NID_MEDIA, reqBufferSize <= length, E_INVALID_ARG, E_INVALID_ARG,
152                         "[E_INVALID_ARG] Check length. Required for (%d x %d) in %d format is %d : arg = %d.",
153                         width, height, pixelFormat, length);
154         }
155
156         __width = width;
157         __height = height;
158         __pixelFormat = pixelFormat;
159
160         __pBuffer.reset(new (std::nothrow) ByteBuffer);
161         SysTryReturn(NID_MEDIA, __pBuffer.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
162                 "[E_OUT_OF_MEMORY] Construct instance failed.");
163
164         r = __pBuffer->Construct(reqBufferSize);
165         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
166                 "[%s] Construct instance failed.", GetErrorMessage(r));
167
168         if (pData != null)
169         {
170                 r = __pBuffer->SetArray(pData, 0, reqBufferSize);
171                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
172                         "[%s] SetArray  for buffer %x of length %d failed.", GetErrorMessage(r),
173                         pData, reqBufferSize);
174         }
175         __pBuffer->Flip();
176         return r;
177 }
178
179 result
180 _ImageBufferImpl::Construct(const Tizen::Base::String &srcImagePath, const Rectangle *pDecodingRegion, bool autoRotate)
181 {
182         result r = E_SUCCESS;
183
184         std::unique_ptr<ByteBuffer> pBuf;
185         pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
186         SysTryReturn(NID_MEDIA, pBuf.get() != null, GetLastResult(), GetLastResult(),
187                            "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
188         r = Construct(*pBuf.get(), pDecodingRegion, autoRotate);
189         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] ImageBuffer construct failed.", GetErrorMessage(r));
190         return r;
191 }
192
193 result
194 _ImageBufferImpl::Construct(const Tizen::Base::ByteBuffer &srcImageBuf, const Tizen::Graphics::Rectangle *pDecodingRegion, bool autoRotate)
195 {
196
197         result r = E_SUCCESS;
198
199         _ImageDecoder dec;
200         std::unique_ptr<ByteBuffer> pDstBuf;
201         Tizen::Graphics::Rectangle transformRegion;
202         int orientationInfo = 0;
203
204         r = dec.Construct(srcImageBuf);
205         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
206
207         __pixelFormat = dec.GetPixelFormat();
208         r = GetLastResult();
209         SysTryReturn(NID_MEDIA, __pixelFormat != MEDIA_PIXEL_FORMAT_NONE, r, r,
210                 "[%s] GetPixelFormat failed.", GetErrorMessage(r));
211
212         if(autoRotate == true)
213         {
214                 _ExifUtil imgExif;
215                 imgExif.Construct(srcImageBuf.GetPointer(), srcImageBuf.GetCapacity());
216                 imgExif.GetValue(EXIF_TAG_IMAGE_ORIENTATION, orientationInfo);
217                 // imgExif.GetValue() will return "r = E_OBJ_NOT_FOUND" if it could not be found exif infomation.
218                 // However, the result should be decided by result of construct in this function.
219                 SetLastResult(E_SUCCESS);
220         }
221
222         if (pDecodingRegion != null)
223         {
224                 int imgWidth = 0;
225                 int imgHeight = 0;
226                 ImageRotationType rotateType = _IMAGE_ROTATE_FLIP_MAP[orientationInfo].rotateType;
227                 ImageFlipType flipType = _IMAGE_ROTATE_FLIP_MAP[orientationInfo].flipType;
228
229                 r = dec.GetDimension(imgWidth, imgHeight);
230                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] dec.GetDimension", GetErrorMessage(r));
231
232                 if (rotateType == IMAGE_ROTATION_90 || rotateType == IMAGE_ROTATION_270)
233                 {
234                         SysTryReturn(NID_MEDIA, imgHeight >= (pDecodingRegion->x + pDecodingRegion->width)
235                                 && imgWidth >= (pDecodingRegion->y + pDecodingRegion->height),
236                                 E_INVALID_ARG, E_INVALID_ARG,
237                                 "[E_INVALID_ARG] imageWidth = %d, imageHeight = %d, x = %d, y = %d, width = %d, height = %d",
238                                 imgHeight, imgWidth, pDecodingRegion->x, pDecodingRegion->y,
239                                 pDecodingRegion->width, pDecodingRegion->height);
240                 }
241                 else
242                 {
243                 SysTryReturn(NID_MEDIA, imgWidth >= (pDecodingRegion->x + pDecodingRegion->width)
244                                 && imgHeight >= (pDecodingRegion->y + pDecodingRegion->height),
245                                 E_INVALID_ARG, E_INVALID_ARG,
246                                 "[E_INVALID_ARG] imageWidth = %d, imageHeight = %d, x = %d, y = %d, width = %d, height = %d",
247                                 imgWidth, imgHeight, pDecodingRegion->x, pDecodingRegion->y,
248                                 pDecodingRegion->width, pDecodingRegion->height);
249                 }
250
251                 if(autoRotate == true)
252                 {
253                         if (rotateType == IMAGE_ROTATION_90)
254                         {
255                                 transformRegion.x =  pDecodingRegion->y;
256                                 transformRegion.y =  imgHeight-(pDecodingRegion->width+pDecodingRegion->x);
257                                 transformRegion.width  = pDecodingRegion->height;
258                                 transformRegion.height = pDecodingRegion->width;
259                         }
260                         else if (rotateType == IMAGE_ROTATION_180)
261                         {
262                                 transformRegion.x =  imgWidth-(pDecodingRegion->width+pDecodingRegion->x);
263                                 transformRegion.y =  imgHeight-(pDecodingRegion->height+pDecodingRegion->y);
264                                 transformRegion.width  = pDecodingRegion->width;
265                                 transformRegion.height = pDecodingRegion->height;
266                         }
267                         else if (rotateType == IMAGE_ROTATION_270)
268                         {
269                                 transformRegion.x =  imgWidth-(pDecodingRegion->height+pDecodingRegion->y);
270                                 transformRegion.y =  pDecodingRegion->x;
271                                 transformRegion.width  = pDecodingRegion->height;
272                                 transformRegion.height = pDecodingRegion->width;
273                         }
274                         else
275                         {
276                                 transformRegion.x =  pDecodingRegion->x;
277                                 transformRegion.y =  pDecodingRegion->y;
278                                 transformRegion.width  = pDecodingRegion->width;
279                                 transformRegion.height = pDecodingRegion->height;
280                         }
281
282                         if (flipType == IMAGE_FLIP_VERTICAL)
283                         {
284                                 transformRegion.x = imgWidth-(transformRegion.width+transformRegion.x);
285                         }
286                         else if (flipType == IMAGE_FLIP_HORIZONTAL)
287                         {
288                                 transformRegion.y = imgHeight-(transformRegion.height+transformRegion.y);
289                         }
290                 }
291                 else
292                 {
293                         transformRegion.x =  pDecodingRegion->x;
294                         transformRegion.y =  pDecodingRegion->y;
295                         transformRegion.width  = pDecodingRegion->width;
296                         transformRegion.height = pDecodingRegion->height;
297                 }
298
299                 r = dec.SetDecodingRegion(transformRegion.x, transformRegion.y,
300                         transformRegion.width, transformRegion.height);
301
302                 SysTryReturn(NID_MEDIA, r == E_SUCCESS || r == E_UNSUPPORTED_OPERATION, r, r,
303                         "[%s] dec.SetDecodingRegion:%d %d %d %d", GetErrorMessage(r),
304                         pDecodingRegion->x, pDecodingRegion->y, pDecodingRegion->width, pDecodingRegion->height);
305
306                 __width = transformRegion.width;
307                 __height = transformRegion.height;
308
309                 if (r == E_SUCCESS)
310                 {
311                         __pBuffer.reset(dec.DecodeN());
312                         r = GetLastResult();
313                         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] DecodeN failed.",
314                                 GetErrorMessage(r));
315                         SysTryReturn(NID_MEDIA, __pBuffer.get() != null, r, r,
316                                 "[%s] DecodeN returned empty buffer.", GetErrorMessage(r));
317                 }
318                 else if (r == E_UNSUPPORTED_OPERATION)
319                 {
320                         // crop image
321                         ByteBuffer *pTmpBuf = null;
322
323                         __pBuffer.reset(dec.DecodeN());
324                         r = GetLastResult();
325                         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
326
327                         pTmpBuf = _ImageUtil::CropN(*__pBuffer.get(), __pixelFormat, imgWidth, imgHeight,
328                                 transformRegion.x, transformRegion.y, transformRegion.width, transformRegion.height);
329                         SysTryReturn(NID_MEDIA, pTmpBuf != null, GetLastResult(), GetLastResult(),
330                                 "[%s] Crop:%x %d %d %d %d %d %d %d", GetErrorMessage(GetLastResult()), __pBuffer->GetPointer(),
331                         __pixelFormat, imgWidth, imgHeight, pDecodingRegion->x, pDecodingRegion->y,
332                                 pDecodingRegion->width, pDecodingRegion->height);
333
334                         __pBuffer.reset(pTmpBuf);
335                 }
336         }
337         else
338         {
339                 r = dec.GetDimension(__width, __height);
340                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] GetDimension failed.",
341                         GetErrorMessage(r));
342
343                 __pBuffer.reset(dec.DecodeN());
344                 r = GetLastResult();
345                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] DecodeN failed.",
346                         GetErrorMessage(r));
347                 SysTryReturn(NID_MEDIA, __pBuffer.get() != null, r, r,
348                         "[%s] DecodeN returned empty buffer.", GetErrorMessage(r));
349         }
350
351         if (autoRotate == true)
352         {
353                 ByteBuffer *pTmpBuf = null;
354                 int tempWidth = 0;
355                 int length = 0;
356
357                 if (orientationInfo == EXIF_ORIENTATION_TOP_LEFT || orientationInfo == 0)
358                 {
359                         return E_SUCCESS;
360                 }
361
362                 if (orientationInfo > EXIF_ORIENTATION_LEFT_BOTTOM || orientationInfo  < EXIF_ORIENTATION_TOP_LEFT)
363                 {
364                         return E_SUCCESS;
365                 }
366
367                 pDstBuf.reset(new (std::nothrow) ByteBuffer());
368                 SysTryReturn(NID_MEDIA, pDstBuf.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
369
370                 length = _ImageUtil::GetBufferSize(__pixelFormat, __width, __height);
371
372                 pDstBuf->Construct(length);
373                 pDstBuf->SetLimit(length);
374                 pDstBuf->SetPosition(0);
375
376                 ImageRotationType rotateType = _IMAGE_ROTATE_FLIP_MAP[orientationInfo].rotateType;
377                 ImageFlipType flipType = _IMAGE_ROTATE_FLIP_MAP[orientationInfo].flipType;
378
379                 r = _ImageUtil::Rotate(*__pBuffer.get(), __pixelFormat, __width, __height, *pDstBuf.get(), rotateType);
380                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] _ImageUtil:Resize", GetErrorMessage(r));
381                 if(_IMAGE_ROTATE_FLIP_MAP[orientationInfo].dimensionSwitch == true)
382                 {
383                         tempWidth = __width;
384                         __width = __height;
385                         __height =  tempWidth;
386                 }
387
388                 __pBuffer.swap(pDstBuf);
389
390                 if (flipType != IMAGE_FLIP_NONE)
391                 {
392                         r = _ImageUtil::Flip(*__pBuffer.get(), __pixelFormat, __width, __height, *pDstBuf, flipType);
393                         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] _ImageUtil:Flip", GetErrorMessage(r));
394                         __pBuffer.swap(pDstBuf);
395                 }
396         }
397         return r;
398 }
399
400 result
401 _ImageBufferImpl::Construct(const Bitmap &srcBitmap)
402 {
403         BufferInfo info;
404         Bitmap *pTmpBmp = null;
405         int bpp = 0;
406         int length = 0;
407         result r = E_SUCCESS;
408
409         pTmpBmp = (const_cast<Bitmap*>(&srcBitmap));
410         SysTryReturn(NID_MEDIA, pTmpBmp != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
411                 "[E_OUT_OF_MEMORY] Construct instance failed.");
412
413         r = pTmpBmp->Lock(info);
414         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Bitmap.Lock failed.",
415                 GetErrorMessage(r));
416
417         __width = info.width;
418         __height = info.height;
419         bpp = info.bitsPerPixel / 8;
420         length = __width * __height * bpp;
421
422         __pixelFormat = _ImageUtilImpl::ToMediaPixelFormat(srcBitmap.GetPixelColorFormat());
423
424         __pBuffer.reset(new (std::nothrow) ByteBuffer);
425         SysTryCatch(NID_MEDIA, __pBuffer.get(), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
426                 "[E_OUT_OF_MEMORY] Construct instance failed.");
427
428         r = __pBuffer->Construct(length);
429         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
430                 "[%s] Construct instance failed.", GetErrorMessage(r));
431         r = __pBuffer->SetArray((byte*)info.pPixels, 0, length);
432         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r));
433
434         r = pTmpBmp->Unlock();
435         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Bitmap.Unlock failed.", GetErrorMessage(r));
436
437         __pBuffer->Flip();
438
439         return r;
440
441 CATCH:
442         pTmpBmp->Unlock();
443
444         return r;
445 }
446
447 bool
448 _ImageBufferImpl::Equals(ImageBuffer* pRhs) const
449 {
450         _ImageBufferImpl* pRhsImpl = null;
451         byte* pRawOther = null;
452         int lengthOther = 0;
453         MediaPixelFormat pixFmtOther = MEDIA_PIXEL_FORMAT_NONE;
454
455         byte* pRawThis = null;
456         int lengthThis = 0;
457         MediaPixelFormat pixFmtThis = MEDIA_PIXEL_FORMAT_NONE;
458
459         bool out = false;
460         result r = E_SUCCESS;
461
462         if (pRhs == null)
463         {
464                 out = false;
465         }
466         else
467         {
468                 pRhsImpl = GetInstance(*pRhs);
469                 if (pRhsImpl == null)
470                 {
471                         out = false;
472                 }
473                 else if (pRhsImpl == this)
474                 {
475                         out = true;
476                 }
477                 else
478                 {
479                         // Compare dimensions.
480                         if ((__height != pRhsImpl->GetHeight()) || (__width != pRhsImpl->GetWidth()))
481                         {
482                                 out = false;
483                         }
484                         else
485                         {
486                                 r = const_cast<_ImageBufferImpl*>(pRhsImpl)->Lock(pRawOther, lengthOther, pixFmtOther);
487                                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, false, r,
488                                         "[%s] Could not lock RHS ImageBuffer contents.", GetErrorMessage(r));
489
490                                 r = const_cast<_ImageBufferImpl *>(this)->Lock(pRawThis, lengthThis, pixFmtThis);
491                                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, false, r,
492                                         "[%s] Could not lock this ImageBuffer contents.", GetErrorMessage(r));
493
494                                 // Check if contents are equal.
495                                 if ((__pixelFormat != pixFmtOther) || (__pBuffer->GetCapacity() != lengthOther))
496                                 {
497                                         out = false;
498                                 }
499                                 else
500                                 {
501                                         if (memcmp(pRawOther, pRawThis, lengthOther) == 0)
502                                         {
503                                                 out = true;
504                                         }
505                                         else
506                                         {
507                                                 out = false;
508                                         }
509                                 }
510                         }
511                 }
512         }
513
514         return out;
515 }
516
517 int
518 _ImageBufferImpl::GetHashCode() const
519 {
520         int hashCode = 0;
521
522         hashCode = __pBuffer->GetHashCode();
523
524         hashCode = (hashCode ^ (__width * __height)) | (hashCode & __pixelFormat);
525
526         return hashCode;
527 }
528
529 int
530 _ImageBufferImpl::GetHeight() const
531 {
532         return __height;
533 }
534
535 int
536 _ImageBufferImpl::GetWidth() const
537 {
538         return __width;
539 }
540
541 MediaPixelFormat
542 _ImageBufferImpl::GetPixelFormat() const
543 {
544         return __pixelFormat;
545 }
546
547 result
548 _ImageBufferImpl::Lock(byte* &data, int &length, MediaPixelFormat &pixelFormat)
549 {
550         result r = E_SUCCESS;
551
552         SysTryReturn(NID_MEDIA, __isLocked != true, E_INVALID_STATE, E_INVALID_STATE,
553                 "[E_INVALID_STATE] Instance is locked. Unlock to use.");
554
555         data = const_cast<byte *>(__pBuffer->GetPointer());
556         length = _ImageUtil::GetBufferSize(__pixelFormat, __width, __height);
557         pixelFormat = __pixelFormat;
558
559         __isLocked = true;
560
561         return r;
562 }
563
564 result
565 _ImageBufferImpl::Unlock()
566 {
567         result r = E_SUCCESS;
568
569         SysTryReturn(NID_MEDIA, __isLocked, E_INVALID_STATE, E_INVALID_STATE,
570                 "[E_INVALID_STATE] Instance is not locked.");
571
572         __isLocked = false;
573
574         return r;
575 }
576
577 ByteBuffer*
578 _ImageBufferImpl::EncodeToBufferN(ImageFormat destImageFormat, int quality) const
579 {
580         result r = E_SUCCESS;
581         int inLength = 0;
582         ByteBuffer* pBuf = null;
583
584         SysTryReturn(NID_MEDIA, !__isLocked, null, E_INVALID_STATE,
585                 "[E_INVALID_STATE] Instance is locked. Unlock to use.");
586
587         inLength = _ImageUtil::GetBufferSize(__pixelFormat, __width, __height);
588         pBuf = _ImageEncoder::EncodeN(destImageFormat, (const byte*)__pBuffer->GetPointer(), inLength, __width, __height,
589                 __pixelFormat, quality);
590         SysTryReturn(NID_MEDIA, pBuf != null, null, GetLastResult(), "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
591
592         SetLastResult(r);
593         return pBuf;
594 }
595
596 result
597 _ImageBufferImpl::EncodeToFile(const String &destImagePath, ImageFormat destImageFormat,
598         bool overwrite, int quality) const
599 {
600         result r = E_SUCCESS;
601         std::unique_ptr<ByteBuffer> pBuf;
602
603         SysTryReturn(NID_MEDIA, !__isLocked, E_INVALID_STATE, E_INVALID_STATE,
604                 "[E_INVALID_STATE] Instance is locked. Unlock to use.");
605
606         pBuf.reset(this->EncodeToBufferN(destImageFormat, quality));
607         SysTryReturn(NID_MEDIA, pBuf.get() != null, GetLastResult(), GetLastResult(),
608                 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
609
610         r = _MediaUtil::BufferToFile(*pBuf.get(), destImagePath, overwrite);
611         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
612
613         return r;
614 }
615
616 Bitmap*
617 _ImageBufferImpl::GetBitmapN(BitmapPixelFormat pixelFormat, BufferScaling bufferScaling) const
618 {
619         result r = E_SUCCESS;
620         std::unique_ptr<Bitmap> pOutBitmap;
621         std::unique_ptr<ByteBuffer> pConverted;
622         MediaPixelFormat inPixelFormat = MEDIA_PIXEL_FORMAT_NONE;
623
624         SysTryReturn(NID_MEDIA, !__isLocked, null, E_INVALID_STATE,
625                 "[E_INVALID_STATE] Instance is locked. Unlock to use.");
626
627         inPixelFormat = _ImageUtilImpl::ToMediaPixelFormat(pixelFormat);
628         SysTryReturn(NID_MEDIA, inPixelFormat != MEDIA_PIXEL_FORMAT_NONE, null, E_INVALID_ARG,
629                 "[E_INVALID_ARG] Pixel format is %d, invalid or not supported.", pixelFormat);
630
631         if (inPixelFormat != __pixelFormat)
632         {
633                 // Convert raw data to the required pixel format.
634                 pConverted.reset(GetByteBufferN(inPixelFormat));
635                 r = GetLastResult();
636                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
637         }
638
639         pOutBitmap.reset(new (std::nothrow) Bitmap);
640         SysTryReturn(NID_MEDIA, pOutBitmap.get() != null, null, E_OUT_OF_MEMORY,
641                 "[E_OUT_OF_MEMORY] Propagated.");
642
643         if (inPixelFormat != __pixelFormat)
644         {
645                 r = pOutBitmap->Construct(*pConverted.get(), Dimension(__width, __height), pixelFormat, bufferScaling);
646         }
647         else
648         {
649                 r = pOutBitmap->Construct(*__pBuffer, Dimension(__width, __height), pixelFormat, bufferScaling);
650         }
651
652         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.",
653                 GetErrorMessage(r));
654         return pOutBitmap.release();
655 }
656
657 ByteBuffer*
658 _ImageBufferImpl::GetByteBufferN(MediaPixelFormat inPixelFormat) const
659 {
660         result r = E_SUCCESS;
661         std::unique_ptr<ByteBuffer> pOutBuf;
662
663         SysTryReturn(NID_MEDIA, !__isLocked, null, E_INVALID_STATE,
664                 "[E_INVALID_STATE] Instance is locked. Unlock to use.");
665
666         SysTryReturn(NID_MEDIA, (inPixelFormat > MEDIA_PIXEL_FORMAT_NONE) && (inPixelFormat <= MEDIA_PIXEL_FORMAT_YUYV422),
667                 null, E_INVALID_ARG, "[E_INVALID_ARG] Pixel format is invalid.", inPixelFormat);
668
669         SysTryReturn(NID_MEDIA, IsSupportedPixelFormat(inPixelFormat) == true , null, E_UNSUPPORTED_FORMAT,
670                 "[E_UNSUPPORTED_FORMAT] The specified pixelFormat is not supported.")
671
672         if (inPixelFormat != __pixelFormat)
673         {
674                 // Convert raw data to the required pixel format.
675                 _ColorConverter cvt;
676
677                 r = cvt.Construct(__pixelFormat, __width, __height,
678                         inPixelFormat, __width, __height);
679                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
680
681                 pOutBuf.reset(cvt.ConvertN(*__pBuffer));
682                 r = GetLastResult();
683                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
684         }
685         else
686         {
687                 pOutBuf.reset(new (std::nothrow) ByteBuffer);
688                 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
689                         "[E_OUT_OF_MEMORY] Propagated.");
690
691                 r = pOutBuf->Construct(*__pBuffer);
692                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
693                         "[%s] Propagated.", GetErrorMessage(r));
694         }
695
696         SetLastResult(r);
697         return pOutBuf.release();
698 }
699
700 ImageBuffer*
701 _ImageBufferImpl::CloneN() const
702 {
703         std::unique_ptr<ImageBuffer> pImgBuffer;
704         _ImageBufferImpl* pImgBufferImpl = null;
705         result r = E_SUCCESS;
706         byte* pData = null;
707         int length = 0;
708         MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
709
710         r = const_cast<_ImageBufferImpl *>(this)->Lock(pData, length, pixFmt);
711         SysTryReturn(NID_MEDIA, r == E_SUCCESS, pImgBuffer.get(), r, "[%s] Propagated.", GetErrorMessage(r));
712
713         pImgBuffer.reset(new (std::nothrow) ImageBuffer);
714         SysTryReturn(NID_MEDIA, pImgBuffer.get() != null, null, E_OUT_OF_MEMORY,
715                 "[E_OUT_OF_MEMORY] Could not create new instance.")
716
717         r = pImgBuffer->Construct(__width, __height, pixFmt, pData, length);
718         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
719                 "[%s] Failed to construct the cloned ImageBuffer.", GetErrorMessage(r));
720
721         const_cast<_ImageBufferImpl *>(this)->Unlock();
722
723         SetLastResult(r);
724         return pImgBuffer.release();
725 }
726
727 ImageBuffer*
728 _ImageBufferImpl::ConvertPixelFormatN(MediaPixelFormat pixelFormat) const
729 {
730         std::unique_ptr<ImageBuffer> pImgBuffer;
731         _ImageBufferImpl* pImgBufferImpl = null;
732         result r = E_SUCCESS;
733         byte* pData = null;
734         std::unique_ptr<byte[]> pDataConvert;
735         int length = 0;
736         int dstLength = 0;
737         MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
738
739         SysTryReturn(NID_MEDIA, ISSUPPORTED(pixelFormat) == true, pImgBuffer.get(), E_INVALID_ARG,
740                 "[E_INVALID_ARG] Pixel format %d is not supported.", pixelFormat);
741
742         if (pixelFormat != __pixelFormat)
743         {
744                 _ColorConverter cvt;
745
746                 r = cvt.Construct(__pixelFormat, __width, __height,
747                         pixelFormat, __width, __height);
748                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated.", GetErrorMessage(r));
749
750                 r = const_cast<_ImageBufferImpl *>(this)->Lock(pData, length, pixFmt);
751                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
752                         "[%s] Lock failed. Propagated.", GetErrorMessage(r));
753
754                 pDataConvert.reset(cvt.ConvertN(pData, length, dstLength));
755                 r = GetLastResult();
756                 SysTryCatch(NID_MEDIA, (r == E_SUCCESS) && (pDataConvert.get() != null), , r,
757                         "[%s] Failed to convert data to required pixelformat.", GetErrorMessage(r));
758
759                 const_cast<_ImageBufferImpl *>(this)->Unlock();
760
761                 pImgBuffer.reset(new (std::nothrow) ImageBuffer);
762                 SysTryCatch(NID_MEDIA, pImgBuffer.get() != null, , E_OUT_OF_MEMORY,
763                         "[E_OUT_OF_MEMORY] Could not create new instance.")
764
765                 r = pImgBuffer->Construct(__width, __height, pixelFormat, pDataConvert.get(), dstLength);
766                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
767                         "[%s] Failed to construct the converted ImageBuffer.", GetErrorMessage(r));
768         }
769         else
770         {
771                 pImgBuffer.reset(CloneN());
772         }
773
774         SetLastResult(r);
775         return pImgBuffer.release();
776
777 CATCH:
778         const_cast<_ImageBufferImpl *>(this)->Unlock();
779         SetLastResult(r);
780         return null;
781 }
782
783 ImageBuffer*
784 _ImageBufferImpl::ResizeN(int width, int height) const
785 {
786         std::unique_ptr<ImageBuffer> pImgBuffer;
787         _ImageBufferImpl* pImgBufferImpl = null;
788         result r = E_SUCCESS;
789         byte* pData = null;
790         std::unique_ptr<byte[]> pDataResized;
791         int length = 0;
792         int dstLength = 0;
793         MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
794
795         SysTryReturn(NID_MEDIA, (width > 0) && (height > 0), pImgBuffer.get(), E_INVALID_ARG,
796                 "[E_INVALID_ARG] Dimensions should be greater than zero: (%d x %d)", width, height);
797
798         if ((width != __width) && (height != __height))
799         {
800                 dstLength = _ImageUtil::GetBufferSize(__pixelFormat, width, height);
801                 SysTryReturn(NID_MEDIA, dstLength > 0, pImgBuffer.get(), GetLastResult(),
802                         "[%s] Failed to get valid buffer length for (%d x %d), pixel format %d.",
803                         GetErrorMessage(GetLastResult()), width, height, __pixelFormat);
804
805                 pDataResized.reset(new (std::nothrow) byte[dstLength]);
806                 SysTryReturn(NID_MEDIA, pDataResized.get() != null, pImgBuffer.get(), E_OUT_OF_MEMORY,
807                         "[E_OUT_OF_MEMORY] Failed to allocate %d bytes.", dstLength);
808
809                 r = const_cast<_ImageBufferImpl *>(this)->Lock(pData, length, pixFmt);
810                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
811                         "[%s] Lock failed. Propagated.", GetErrorMessage(r));
812
813                 r = _ImageUtil::ResizeBuffer(pData, __pixelFormat, __width, __height,
814                         pDataResized.get(), width, height);
815                 SysTryCatch(NID_MEDIA, (r == E_SUCCESS) && (pDataResized.get() != null), , r,
816                         "[%s] Could not resize buffer.", GetErrorMessage(r));
817
818                 const_cast<_ImageBufferImpl *>(this)->Unlock();
819
820                 pImgBuffer.reset(new (std::nothrow) ImageBuffer);
821                 SysTryCatch(NID_MEDIA, pImgBuffer.get() != null, , E_OUT_OF_MEMORY,
822                         "[E_OUT_OF_MEMORY] Could not create new instance.")
823
824                 r = pImgBuffer->Construct(width, height, __pixelFormat, pDataResized.get(), dstLength);
825                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
826                         "[%s] Failed to construct the resized ImageBuffer.", GetErrorMessage(r));
827         }
828         else
829         {
830                 pImgBuffer.reset(CloneN());
831         }
832
833         SetLastResult(r);
834         return pImgBuffer.release();
835
836 CATCH:
837
838         const_cast<_ImageBufferImpl *>(this)->Unlock();
839         SetLastResult(r);
840         return null;
841 }
842
843 ImageBuffer*
844 _ImageBufferImpl::FlipN(ImageFlipType flipType) const
845 {
846         std::unique_ptr<ImageBuffer> pImgBuffer;
847         _ImageBufferImpl* pImgBufferImpl = null;
848         result r = E_SUCCESS;
849         byte* pData = null;
850         std::unique_ptr<byte[]> pDataFlip;
851         int length = 0;
852         MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
853
854         SysTryReturn(NID_MEDIA, (flipType >= IMAGE_FLIP_NONE) && (flipType <= IMAGE_FLIP_VERTICAL),
855                 pImgBuffer.get(), E_INVALID_ARG, "[E_INVALID_ARG] Flip type is not valid: %d.", flipType);
856
857         if (flipType != IMAGE_FLIP_NONE)
858         {
859                 r = const_cast<_ImageBufferImpl *>(this)->Lock(pData, length, pixFmt);
860                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pImgBuffer.get(), r,
861                         "[%s] Lock failed. Propagated.", GetErrorMessage(r));
862
863                 pDataFlip.reset(new (std::nothrow) byte[length]);
864                 SysTryCatch(NID_MEDIA, pDataFlip.get() != null, , E_OUT_OF_MEMORY,
865                         "[E_OUT_OF_MEMORY] Could not allocate %d bytes for flipped output.", length);
866
867                 r = _ImageUtil::FlipBuffer(pData, __pixelFormat, __width, __height, pDataFlip.get(), flipType);
868                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
869                         "[%s] Could not flip the data.", GetErrorMessage(r));
870                 
871                 const_cast<_ImageBufferImpl *>(this)->Unlock();
872
873                 pImgBuffer.reset(new (std::nothrow) ImageBuffer);
874                 SysTryCatch(NID_MEDIA, pImgBuffer.get() != null, , E_OUT_OF_MEMORY,
875                         "[E_OUT_OF_MEMORY] Could not create new instance.")
876
877                 r = pImgBuffer->Construct(__width, __height, __pixelFormat, pDataFlip.get(), length);
878                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
879                         "[%s] Failed to construct the fliped ImageBuffer.", GetErrorMessage(r));
880         }
881         else
882         {
883                 pImgBuffer.reset(CloneN());
884         }
885
886         SetLastResult(r);
887         return pImgBuffer.release();
888
889 CATCH:
890
891         const_cast<_ImageBufferImpl *>(this)->Unlock();
892
893         SetLastResult(r);
894         return null;
895 }
896
897 ImageBuffer*
898 _ImageBufferImpl::RotateN(ImageRotationType rotationType) const
899 {
900         std::unique_ptr<ImageBuffer> pImgBuffer;
901         _ImageBufferImpl* pImgBufferImpl = null;
902         result r = E_SUCCESS;
903         byte* pData = null;
904         std::unique_ptr<byte[]> pDataRotate;
905         int length = 0;
906         int rotatedWidth= 0;
907         int rotatedHeight = 0;
908         MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
909
910         SysTryReturn(NID_MEDIA, (rotationType >= IMAGE_ROTATION_0) && (rotationType <= IMAGE_ROTATION_270),
911                 pImgBuffer.get(), E_INVALID_ARG, "[E_INVALID_ARG] Rotation type is not valid: %d.", rotationType);
912
913         if (rotationType != IMAGE_ROTATION_0)
914         {
915                 r = const_cast<_ImageBufferImpl *>(this)->Lock(pData, length, pixFmt);
916                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pImgBuffer.get(), r,
917                         "[%s] Lock failed. Propagated.", GetErrorMessage(r));
918
919                 pDataRotate.reset(new (std::nothrow) byte[length]);
920                 SysTryCatch(NID_MEDIA, pDataRotate.get() != null, , E_OUT_OF_MEMORY,
921                         "[E_OUT_OF_MEMORY] Could not allocate %d bytes for rotated output.", length);
922
923                 r = _ImageUtil::RotateBuffer(pData, __pixelFormat, __width, __height, pDataRotate.get(),
924                         rotatedWidth, rotatedHeight, rotationType);
925                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
926                         "[%s] Could not rotate the data.", GetErrorMessage(r));
927
928                 const_cast<_ImageBufferImpl *>(this)->Unlock();
929
930                 pImgBuffer.reset(new (std::nothrow) ImageBuffer);
931                 SysTryCatch(NID_MEDIA, pImgBuffer.get() != null, , E_OUT_OF_MEMORY,
932                         "[E_OUT_OF_MEMORY] Could not create new instance.")
933
934                 r = pImgBuffer->Construct(rotatedWidth, rotatedHeight, __pixelFormat, pDataRotate.get(), length);
935                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
936                         "[%s] Failed to construct the rotated ImageBuffer.", GetErrorMessage(r));
937         }
938         else
939         {
940                 pImgBuffer.reset(CloneN());
941         }
942
943         SetLastResult(r);
944         return pImgBuffer.release();
945
946 CATCH:
947
948         const_cast<_ImageBufferImpl *>(this)->Unlock();
949
950         SetLastResult(r);
951         return null;
952 }
953
954 ImageBuffer*
955 _ImageBufferImpl::CropN(int x, int y, int width, int height) const
956 {
957         std::unique_ptr<ImageBuffer> pImgBuffer;
958         _ImageBufferImpl* pImgBufferImpl = null;
959         result r = E_SUCCESS;
960         byte* pData = null;
961         std::unique_ptr<byte[]> pDataCropped;
962         int length = 0;
963         int dstLength = 0;
964         MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
965
966         SysTryReturn(NID_MEDIA, (x >= 0) && (y >= 0) && (x <= __width) && (y <= __height),
967                 pImgBuffer.get(), E_INVALID_ARG,
968                 "[E_INVALID_ARG] Origin should lie within image: (%d, %d) is outside (0, 0) - (%d, %d).",
969                 x, y, __width, __height);
970
971         SysTryReturn(NID_MEDIA, (width > 0) && (height > 0),
972                 pImgBuffer.get(), E_INVALID_ARG,
973                 "[E_INVALID_ARG] Dimensions of cropped region should greater than zero: (%d, %d).",
974                 width, height);
975
976         SysTryReturn(NID_MEDIA, (x + width <= __width) && (y + height <= __height),
977                 pImgBuffer.get(), E_INVALID_ARG,
978                 "[E_INVALID_ARG] End of cropped region should lie within image: (%d, %d) is outside (0, 0) - (%d, %d).",
979                 x + width, y + height, __width, __height);
980
981         SysTryReturn(NID_MEDIA, _ImageUtil::IsValidDimension(__pixelFormat, width, height) == true,
982                 pImgBuffer.get(), E_INVALID_ARG,
983                 "[E_INVALID_ARG] Current pixel format does not support odd dimensions (%d, %d).",
984                 width, height);
985
986         if ((x != 0) || (y != 0) || (width != __width) || (height != __height))
987         {
988                 r = const_cast<_ImageBufferImpl *>(this)->Lock(pData, length, pixFmt);
989                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pImgBuffer.get(), r,
990                         "[%s] Lock failed. Propagated.", GetErrorMessage(r));
991
992                 dstLength = _ImageUtil::GetBufferSize(__pixelFormat, width, height);
993                 SysTryCatch(NID_MEDIA, dstLength > 0, , GetLastResult(),
994                         "[%s] Could not get output buffer size.", GetErrorMessage(GetLastResult()));
995
996                 pDataCropped.reset(new (std::nothrow) byte[dstLength]);
997                 SysTryCatch(NID_MEDIA, pDataCropped.get() != null, , E_OUT_OF_MEMORY,
998                         "[E_OUT_OF_MEMORY] Could not allocate %d bytes for cropped output.", dstLength);
999
1000                 r = _ImageUtil::CropBuffer(pData, __pixelFormat, __width, __height,
1001                         pDataCropped.get(), x, y, width, height);
1002                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
1003                         "[%s] Could not Crop the data.", GetErrorMessage(r));
1004
1005                 const_cast<_ImageBufferImpl *>(this)->Unlock();
1006
1007                 pImgBuffer.reset(new (std::nothrow) ImageBuffer);
1008                 SysTryCatch(NID_MEDIA, pImgBuffer.get() != null, , E_OUT_OF_MEMORY,
1009                         "[E_OUT_OF_MEMORY] Could not create new instance.")
1010
1011                 r = pImgBuffer->Construct(width, height, __pixelFormat, pDataCropped.get(), dstLength);
1012                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
1013                         "[%s] Failed to construct the croped ImageBuffer.", GetErrorMessage(r));
1014         }
1015         else
1016         {
1017                 pImgBuffer.reset(CloneN());
1018         }
1019
1020         SetLastResult(r);
1021         return pImgBuffer.release();
1022
1023 CATCH:
1024
1025         const_cast<_ImageBufferImpl *>(this)->Unlock();
1026
1027         SetLastResult(r);
1028         return null;
1029 }
1030
1031 result
1032 _ImageBufferImpl::GetImageInfo(const String& srcImagePath, ImageFormat& imageFormat,
1033         int &width, int &height)
1034 {
1035         result r = E_SUCCESS;
1036
1037         std::unique_ptr<ByteBuffer> pSrcBuf(_MediaUtil::FileToBufferN(srcImagePath, 0));
1038         SysTryReturn(NID_MEDIA, pSrcBuf.get() != null, GetLastResult(), GetLastResult(),
1039                 "[%s] Propagated.", GetErrorMessage(GetLastResult()));
1040
1041         r = GetImageInfo(*pSrcBuf.get(), imageFormat, width, height);
1042
1043         return r;
1044 }
1045
1046 result
1047 _ImageBufferImpl::GetImageInfo(const ByteBuffer& srcImageBuf, ImageFormat& imageFormat,
1048         int &width, int &height)
1049 {
1050         result r = E_SUCCESS;
1051         _ImageDecoder dec;
1052
1053         r = dec.Construct(srcImageBuf, MEDIA_PIXEL_FORMAT_RGB565LE);
1054         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] dec.Construct", GetErrorMessage(r));
1055         imageFormat = dec.GetImageFormat();
1056         r = dec.GetDimension(width, height);
1057         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] dec.GetDimension", GetErrorMessage(r));
1058
1059         return r;
1060 }
1061
1062 bool
1063 _ImageBufferImpl::IsSupportedPixelFormat(MediaPixelFormat pixelFormat)
1064 {
1065         for (int i = 0; i < sizeof(_IMAGE_BUFFER_PIXEL_FORMATS)/sizeof(_IMAGE_BUFFER_PIXEL_FORMATS[0]) ; i++)
1066         {
1067                 if(pixelFormat == _IMAGE_BUFFER_PIXEL_FORMATS[i])
1068                 {
1069                         return true;
1070                 }
1071         }
1072         return false;
1073 }
1074
1075 IListT<MediaPixelFormat>*
1076 _ImageBufferImpl::GetSupportedPixelFormatListN()
1077 {
1078         result r = E_SUCCESS;
1079         std::unique_ptr<ArrayListT<MediaPixelFormat> > pList(new (std::nothrow) ArrayListT<MediaPixelFormat>());
1080         SysTryReturn(NID_MEDIA, pList.get() != null, null, E_OUT_OF_MEMORY,
1081                 "[E_OUT_OF_MEMORY] Could not allocate memory for output.");
1082
1083         // TODO update list later for supported color formats in color converter?.
1084         for (int i=0; i<sizeof(_IMAGE_BUFFER_PIXEL_FORMATS)/sizeof(_IMAGE_BUFFER_PIXEL_FORMATS[0]); i++)
1085         {
1086                 r = pList->Add(_IMAGE_BUFFER_PIXEL_FORMATS[i]);
1087                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
1088                                         "[%s] Adding elements to list failed. List is not complete.", GetErrorMessage(r));
1089         }
1090
1091         SetLastResult(r);
1092         return pList.release();
1093 }
1094
1095 _ImageBufferImpl*
1096 _ImageBufferImpl::GetInstance(ImageBuffer& a)
1097 {
1098         return a.__pImpl;
1099 }
1100
1101 const _ImageBufferImpl*
1102 _ImageBufferImpl::GetInstance(const ImageBuffer& a)
1103 {
1104         return a.__pImpl;
1105 }
1106
1107 }} // Tizen::Media
1108