2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file FMedia_ImageBufferImpl.cpp
20 * @brief This file contains the implementation of ImageBuffer's impl layer.
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"
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;
45 namespace Tizen { namespace Media
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))
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 */
65 ImageRotationType rotateType;
66 ImageFlipType flipType;
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 */
82 static const MediaPixelFormat _IMAGE_BUFFER_PIXEL_FORMATS[] =
84 MEDIA_PIXEL_FORMAT_RGB565LE,
85 MEDIA_PIXEL_FORMAT_BGRA8888,
86 MEDIA_PIXEL_FORMAT_YUV420P
89 _ImageBufferImpl::_ImageBufferImpl(void)
93 , __pixelFormat(MEDIA_PIXEL_FORMAT_NONE)
98 _ImageBufferImpl::~_ImageBufferImpl(void)
103 _ImageBufferImpl::Construct(int width, int height, MediaPixelFormat pixelFormat)
105 result r = E_SUCCESS;
110 __pixelFormat = pixelFormat;
112 SysTryReturn(NID_MEDIA, IsSupportedPixelFormat(pixelFormat) == true , null, E_UNSUPPORTED_FORMAT,
113 "[E_UNSUPPORTED_FORMAT] The specified pixelFormat is not supported.")
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);
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.");
124 r = __pBuffer->Construct(length);
125 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
126 "[%s] Construct instance failed.", GetErrorMessage(r));
132 _ImageBufferImpl::Construct(int width, int height, MediaPixelFormat pixelFormat,
133 const byte* pData, int length)
135 result r = E_SUCCESS;
136 int reqBufferSize = 0;
138 SysTryReturn(NID_MEDIA, IsSupportedPixelFormat(pixelFormat) == true , E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
139 "[E_UNSUPPORTED_FORMAT] The specified pixelFormat is not supported.")
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);
144 SysTryReturn(NID_MEDIA, ISSUPPORTED(pixelFormat) == true, E_INVALID_ARG, E_INVALID_ARG,
145 "[E_INVALID_ARG] Pixelformat is not supported : %d.", pixelFormat);
147 reqBufferSize = _ImageUtil::GetBufferSize(pixelFormat, width, height);
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);
158 __pixelFormat = pixelFormat;
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.");
164 r = __pBuffer->Construct(reqBufferSize);
165 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
166 "[%s] Construct instance failed.", GetErrorMessage(r));
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);
180 _ImageBufferImpl::Construct(const Tizen::Base::String &srcImagePath, const Rectangle *pDecodingRegion, bool autoRotate)
182 result r = E_SUCCESS;
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));
194 _ImageBufferImpl::Construct(const Tizen::Base::ByteBuffer &srcImageBuf, const Tizen::Graphics::Rectangle *pDecodingRegion, bool autoRotate)
197 result r = E_SUCCESS;
200 std::unique_ptr<ByteBuffer> pDstBuf;
201 Tizen::Graphics::Rectangle transformRegion;
202 int orientationInfo = 0;
204 r = dec.Construct(srcImageBuf);
205 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
207 __pixelFormat = dec.GetPixelFormat();
209 SysTryReturn(NID_MEDIA, __pixelFormat != MEDIA_PIXEL_FORMAT_NONE, r, r,
210 "[%s] GetPixelFormat failed.", GetErrorMessage(r));
212 if(autoRotate == true)
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);
222 if (pDecodingRegion != null)
226 ImageRotationType rotateType = _IMAGE_ROTATE_FLIP_MAP[orientationInfo].rotateType;
227 ImageFlipType flipType = _IMAGE_ROTATE_FLIP_MAP[orientationInfo].flipType;
229 r = dec.GetDimension(imgWidth, imgHeight);
230 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] dec.GetDimension", GetErrorMessage(r));
232 if (rotateType == IMAGE_ROTATION_90 || rotateType == IMAGE_ROTATION_270)
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);
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);
251 if(autoRotate == true)
253 if (rotateType == IMAGE_ROTATION_90)
255 transformRegion.x = pDecodingRegion->y;
256 transformRegion.y = imgHeight-(pDecodingRegion->width+pDecodingRegion->x);
257 transformRegion.width = pDecodingRegion->height;
258 transformRegion.height = pDecodingRegion->width;
260 else if (rotateType == IMAGE_ROTATION_180)
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;
267 else if (rotateType == IMAGE_ROTATION_270)
269 transformRegion.x = imgWidth-(pDecodingRegion->height+pDecodingRegion->y);
270 transformRegion.y = pDecodingRegion->x;
271 transformRegion.width = pDecodingRegion->height;
272 transformRegion.height = pDecodingRegion->width;
276 transformRegion.x = pDecodingRegion->x;
277 transformRegion.y = pDecodingRegion->y;
278 transformRegion.width = pDecodingRegion->width;
279 transformRegion.height = pDecodingRegion->height;
282 if (flipType == IMAGE_FLIP_VERTICAL)
284 transformRegion.x = imgWidth-(transformRegion.width+transformRegion.x);
286 else if (flipType == IMAGE_FLIP_HORIZONTAL)
288 transformRegion.y = imgHeight-(transformRegion.height+transformRegion.y);
293 transformRegion.x = pDecodingRegion->x;
294 transformRegion.y = pDecodingRegion->y;
295 transformRegion.width = pDecodingRegion->width;
296 transformRegion.height = pDecodingRegion->height;
299 r = dec.SetDecodingRegion(transformRegion.x, transformRegion.y,
300 transformRegion.width, transformRegion.height);
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);
306 __width = transformRegion.width;
307 __height = transformRegion.height;
311 __pBuffer.reset(dec.DecodeN());
313 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] DecodeN failed.",
315 SysTryReturn(NID_MEDIA, __pBuffer.get() != null, r, r,
316 "[%s] DecodeN returned empty buffer.", GetErrorMessage(r));
318 else if (r == E_UNSUPPORTED_OPERATION)
321 ByteBuffer *pTmpBuf = null;
323 __pBuffer.reset(dec.DecodeN());
325 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
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);
334 __pBuffer.reset(pTmpBuf);
339 r = dec.GetDimension(__width, __height);
340 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] GetDimension failed.",
343 __pBuffer.reset(dec.DecodeN());
345 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] DecodeN failed.",
347 SysTryReturn(NID_MEDIA, __pBuffer.get() != null, r, r,
348 "[%s] DecodeN returned empty buffer.", GetErrorMessage(r));
351 if (autoRotate == true)
353 ByteBuffer *pTmpBuf = null;
357 if (orientationInfo == EXIF_ORIENTATION_TOP_LEFT || orientationInfo == 0)
362 if (orientationInfo > EXIF_ORIENTATION_LEFT_BOTTOM || orientationInfo < EXIF_ORIENTATION_TOP_LEFT)
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]");
370 length = _ImageUtil::GetBufferSize(__pixelFormat, __width, __height);
372 pDstBuf->Construct(length);
373 pDstBuf->SetLimit(length);
374 pDstBuf->SetPosition(0);
376 ImageRotationType rotateType = _IMAGE_ROTATE_FLIP_MAP[orientationInfo].rotateType;
377 ImageFlipType flipType = _IMAGE_ROTATE_FLIP_MAP[orientationInfo].flipType;
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)
385 __height = tempWidth;
388 __pBuffer.swap(pDstBuf);
390 if (flipType != IMAGE_FLIP_NONE)
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);
401 _ImageBufferImpl::Construct(const Bitmap &srcBitmap)
404 Bitmap *pTmpBmp = null;
407 result r = E_SUCCESS;
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.");
413 r = pTmpBmp->Lock(info);
414 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Bitmap.Lock failed.",
417 __width = info.width;
418 __height = info.height;
419 bpp = info.bitsPerPixel / 8;
420 length = __width * __height * bpp;
422 __pixelFormat = _ImageUtilImpl::ToMediaPixelFormat(srcBitmap.GetPixelColorFormat());
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.");
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));
434 r = pTmpBmp->Unlock();
435 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Bitmap.Unlock failed.", GetErrorMessage(r));
448 _ImageBufferImpl::Equals(ImageBuffer* pRhs) const
450 _ImageBufferImpl* pRhsImpl = null;
451 byte* pRawOther = null;
453 MediaPixelFormat pixFmtOther = MEDIA_PIXEL_FORMAT_NONE;
455 byte* pRawThis = null;
457 MediaPixelFormat pixFmtThis = MEDIA_PIXEL_FORMAT_NONE;
460 result r = E_SUCCESS;
468 pRhsImpl = GetInstance(*pRhs);
469 if (pRhsImpl == null)
473 else if (pRhsImpl == this)
479 // Compare dimensions.
480 if ((__height != pRhsImpl->GetHeight()) || (__width != pRhsImpl->GetWidth()))
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));
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));
494 // Check if contents are equal.
495 if ((__pixelFormat != pixFmtOther) || (__pBuffer->GetCapacity() != lengthOther))
501 if (memcmp(pRawOther, pRawThis, lengthOther) == 0)
518 _ImageBufferImpl::GetHashCode() const
522 hashCode = __pBuffer->GetHashCode();
524 hashCode = (hashCode ^ (__width * __height)) | (hashCode & __pixelFormat);
530 _ImageBufferImpl::GetHeight() const
536 _ImageBufferImpl::GetWidth() const
542 _ImageBufferImpl::GetPixelFormat() const
544 return __pixelFormat;
548 _ImageBufferImpl::Lock(byte* &data, int &length, MediaPixelFormat &pixelFormat)
550 result r = E_SUCCESS;
552 SysTryReturn(NID_MEDIA, __isLocked != true, E_INVALID_STATE, E_INVALID_STATE,
553 "[E_INVALID_STATE] Instance is locked. Unlock to use.");
555 data = const_cast<byte *>(__pBuffer->GetPointer());
556 length = _ImageUtil::GetBufferSize(__pixelFormat, __width, __height);
557 pixelFormat = __pixelFormat;
565 _ImageBufferImpl::Unlock()
567 result r = E_SUCCESS;
569 SysTryReturn(NID_MEDIA, __isLocked, E_INVALID_STATE, E_INVALID_STATE,
570 "[E_INVALID_STATE] Instance is not locked.");
578 _ImageBufferImpl::EncodeToBufferN(ImageFormat destImageFormat, int quality) const
580 result r = E_SUCCESS;
582 ByteBuffer* pBuf = null;
584 SysTryReturn(NID_MEDIA, !__isLocked, null, E_INVALID_STATE,
585 "[E_INVALID_STATE] Instance is locked. Unlock to use.");
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()));
597 _ImageBufferImpl::EncodeToFile(const String &destImagePath, ImageFormat destImageFormat,
598 bool overwrite, int quality) const
600 result r = E_SUCCESS;
601 std::unique_ptr<ByteBuffer> pBuf;
603 SysTryReturn(NID_MEDIA, !__isLocked, E_INVALID_STATE, E_INVALID_STATE,
604 "[E_INVALID_STATE] Instance is locked. Unlock to use.");
606 pBuf.reset(this->EncodeToBufferN(destImageFormat, quality));
607 SysTryReturn(NID_MEDIA, pBuf.get() != null, GetLastResult(), GetLastResult(),
608 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
610 r = _MediaUtil::BufferToFile(*pBuf.get(), destImagePath, overwrite);
611 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
617 _ImageBufferImpl::GetBitmapN(BitmapPixelFormat pixelFormat, BufferScaling bufferScaling) const
619 result r = E_SUCCESS;
620 std::unique_ptr<Bitmap> pOutBitmap;
621 std::unique_ptr<ByteBuffer> pConverted;
622 MediaPixelFormat inPixelFormat = MEDIA_PIXEL_FORMAT_NONE;
624 SysTryReturn(NID_MEDIA, !__isLocked, null, E_INVALID_STATE,
625 "[E_INVALID_STATE] Instance is locked. Unlock to use.");
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);
631 if (inPixelFormat != __pixelFormat)
633 // Convert raw data to the required pixel format.
634 pConverted.reset(GetByteBufferN(inPixelFormat));
636 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
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.");
643 if (inPixelFormat != __pixelFormat)
645 r = pOutBitmap->Construct(*pConverted.get(), Dimension(__width, __height), pixelFormat, bufferScaling);
649 r = pOutBitmap->Construct(*__pBuffer, Dimension(__width, __height), pixelFormat, bufferScaling);
652 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.",
654 return pOutBitmap.release();
658 _ImageBufferImpl::GetByteBufferN(MediaPixelFormat inPixelFormat) const
660 result r = E_SUCCESS;
661 std::unique_ptr<ByteBuffer> pOutBuf;
663 SysTryReturn(NID_MEDIA, !__isLocked, null, E_INVALID_STATE,
664 "[E_INVALID_STATE] Instance is locked. Unlock to use.");
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);
669 SysTryReturn(NID_MEDIA, IsSupportedPixelFormat(inPixelFormat) == true , null, E_UNSUPPORTED_FORMAT,
670 "[E_UNSUPPORTED_FORMAT] The specified pixelFormat is not supported.")
672 if (inPixelFormat != __pixelFormat)
674 // Convert raw data to the required pixel format.
677 r = cvt.Construct(__pixelFormat, __width, __height,
678 inPixelFormat, __width, __height);
679 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
681 pOutBuf.reset(cvt.ConvertN(*__pBuffer));
683 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
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.");
691 r = pOutBuf->Construct(*__pBuffer);
692 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
693 "[%s] Propagated.", GetErrorMessage(r));
697 return pOutBuf.release();
701 _ImageBufferImpl::CloneN() const
703 std::unique_ptr<ImageBuffer> pImgBuffer;
704 _ImageBufferImpl* pImgBufferImpl = null;
705 result r = E_SUCCESS;
708 MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
710 r = const_cast<_ImageBufferImpl *>(this)->Lock(pData, length, pixFmt);
711 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pImgBuffer.get(), r, "[%s] Propagated.", GetErrorMessage(r));
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.")
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));
721 const_cast<_ImageBufferImpl *>(this)->Unlock();
724 return pImgBuffer.release();
728 _ImageBufferImpl::ConvertPixelFormatN(MediaPixelFormat pixelFormat) const
730 std::unique_ptr<ImageBuffer> pImgBuffer;
731 _ImageBufferImpl* pImgBufferImpl = null;
732 result r = E_SUCCESS;
734 std::unique_ptr<byte[]> pDataConvert;
737 MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
739 SysTryReturn(NID_MEDIA, ISSUPPORTED(pixelFormat) == true, pImgBuffer.get(), E_INVALID_ARG,
740 "[E_INVALID_ARG] Pixel format %d is not supported.", pixelFormat);
742 if (pixelFormat != __pixelFormat)
746 r = cvt.Construct(__pixelFormat, __width, __height,
747 pixelFormat, __width, __height);
748 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated.", GetErrorMessage(r));
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));
754 pDataConvert.reset(cvt.ConvertN(pData, length, dstLength));
756 SysTryCatch(NID_MEDIA, (r == E_SUCCESS) && (pDataConvert.get() != null), , r,
757 "[%s] Failed to convert data to required pixelformat.", GetErrorMessage(r));
759 const_cast<_ImageBufferImpl *>(this)->Unlock();
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.")
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));
771 pImgBuffer.reset(CloneN());
775 return pImgBuffer.release();
778 const_cast<_ImageBufferImpl *>(this)->Unlock();
784 _ImageBufferImpl::ResizeN(int width, int height) const
786 std::unique_ptr<ImageBuffer> pImgBuffer;
787 _ImageBufferImpl* pImgBufferImpl = null;
788 result r = E_SUCCESS;
790 std::unique_ptr<byte[]> pDataResized;
793 MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
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);
798 if ((width != __width) && (height != __height))
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);
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);
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));
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));
818 const_cast<_ImageBufferImpl *>(this)->Unlock();
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.")
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));
830 pImgBuffer.reset(CloneN());
834 return pImgBuffer.release();
838 const_cast<_ImageBufferImpl *>(this)->Unlock();
844 _ImageBufferImpl::FlipN(ImageFlipType flipType) const
846 std::unique_ptr<ImageBuffer> pImgBuffer;
847 _ImageBufferImpl* pImgBufferImpl = null;
848 result r = E_SUCCESS;
850 std::unique_ptr<byte[]> pDataFlip;
852 MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
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);
857 if (flipType != IMAGE_FLIP_NONE)
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));
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);
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));
871 const_cast<_ImageBufferImpl *>(this)->Unlock();
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.")
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));
883 pImgBuffer.reset(CloneN());
887 return pImgBuffer.release();
891 const_cast<_ImageBufferImpl *>(this)->Unlock();
898 _ImageBufferImpl::RotateN(ImageRotationType rotationType) const
900 std::unique_ptr<ImageBuffer> pImgBuffer;
901 _ImageBufferImpl* pImgBufferImpl = null;
902 result r = E_SUCCESS;
904 std::unique_ptr<byte[]> pDataRotate;
907 int rotatedHeight = 0;
908 MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
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);
913 if (rotationType != IMAGE_ROTATION_0)
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));
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);
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));
928 const_cast<_ImageBufferImpl *>(this)->Unlock();
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.")
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));
940 pImgBuffer.reset(CloneN());
944 return pImgBuffer.release();
948 const_cast<_ImageBufferImpl *>(this)->Unlock();
955 _ImageBufferImpl::CropN(int x, int y, int width, int height) const
957 std::unique_ptr<ImageBuffer> pImgBuffer;
958 _ImageBufferImpl* pImgBufferImpl = null;
959 result r = E_SUCCESS;
961 std::unique_ptr<byte[]> pDataCropped;
964 MediaPixelFormat pixFmt = MEDIA_PIXEL_FORMAT_NONE;
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);
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).",
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);
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).",
986 if ((x != 0) || (y != 0) || (width != __width) || (height != __height))
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));
992 dstLength = _ImageUtil::GetBufferSize(__pixelFormat, width, height);
993 SysTryCatch(NID_MEDIA, dstLength > 0, , GetLastResult(),
994 "[%s] Could not get output buffer size.", GetErrorMessage(GetLastResult()));
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);
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));
1005 const_cast<_ImageBufferImpl *>(this)->Unlock();
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.")
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));
1017 pImgBuffer.reset(CloneN());
1021 return pImgBuffer.release();
1025 const_cast<_ImageBufferImpl *>(this)->Unlock();
1032 _ImageBufferImpl::GetImageInfo(const String& srcImagePath, ImageFormat& imageFormat,
1033 int &width, int &height)
1035 result r = E_SUCCESS;
1037 std::unique_ptr<ByteBuffer> pSrcBuf(_MediaUtil::FileToBufferN(srcImagePath, 0));
1038 SysTryReturn(NID_MEDIA, pSrcBuf.get() != null, GetLastResult(), GetLastResult(),
1039 "[%s] Propagated.", GetErrorMessage(GetLastResult()));
1041 r = GetImageInfo(*pSrcBuf.get(), imageFormat, width, height);
1047 _ImageBufferImpl::GetImageInfo(const ByteBuffer& srcImageBuf, ImageFormat& imageFormat,
1048 int &width, int &height)
1050 result r = E_SUCCESS;
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));
1063 _ImageBufferImpl::IsSupportedPixelFormat(MediaPixelFormat pixelFormat)
1065 for (int i = 0; i < sizeof(_IMAGE_BUFFER_PIXEL_FORMATS)/sizeof(_IMAGE_BUFFER_PIXEL_FORMATS[0]) ; i++)
1067 if(pixelFormat == _IMAGE_BUFFER_PIXEL_FORMATS[i])
1075 IListT<MediaPixelFormat>*
1076 _ImageBufferImpl::GetSupportedPixelFormatListN()
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.");
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++)
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));
1092 return pList.release();
1096 _ImageBufferImpl::GetInstance(ImageBuffer& a)
1101 const _ImageBufferImpl*
1102 _ImageBufferImpl::GetInstance(const ImageBuffer& a)