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_ImageImpl.cpp
20 * @brief This file contains the implementation of subsystem's Image.
23 #include <unique_ptr.h>
25 #include <FMediaImage.h>
26 #include <FMediaImageUtil.h>
27 #include <FMediaIImageEventListener.h>
28 #include <FBaseSysLog.h>
29 #include "FMedia_MediaUtil.h"
30 #include "FMedia_ImageImpl.h"
31 #include "FMedia_ImageUtil.h"
32 #include "FMedia_ImageUtilImpl.h"
33 #include "FMedia_ImageDecoder.h"
34 #include "FMedia_ImageEncoder.h"
35 #include "FMedia_ImageUriDataFactory.h"
36 #include "FGrp_BitmapImpl.h"
37 #include "FUi_CoordinateSystemUtils.h"
40 using namespace Tizen::Graphics;
41 using namespace Tizen::Base;
42 using namespace Tizen::Io;
43 using namespace Tizen::Ui;
45 namespace Tizen { namespace Media
48 static const float _SCALE_DOWN_RATIO = 0.5;
49 static const int _RGB565_PIXEL_DEPTH = 2;
50 static const int _MIN_ENCODE_QUALITY = 20; // Changed from 50 to 20 to allow greater compression.
51 static const int _MAX_ENCODE_QUALITY = 99;
52 static const int _DEFAULT_ENCODE_QUALITY = 50;
53 static const int _MAX_ENCODE_LOOP = 2;
54 static const int _MAX_ENCODE_RESIZE_LOOP = 2;
55 //static const int MAX_IMGFILE_SIZE = 4096000;
57 _ImageImpl::_ImageImpl(void)
59 __pUrlReqIDList.reset(null);
62 _ImageImpl::~_ImageImpl(void)
64 _ImageUriDataFactory *pFactory = null;
66 pFactory = _ImageUriDataFactory::GetInstance();
67 SysTryReturn(NID_MEDIA, pFactory != null, , GetLastResult(), "[%s] Failed to get Factory instance.",
68 GetErrorMessage(GetLastResult()));
70 if (__pUrlReqIDList.get() != null)
76 num = __pUrlReqIDList->GetCount();
77 for (int i = 0; i < num; i++)
79 pObj = __pUrlReqIDList->GetAt(i);
82 Integer *pValue = dynamic_cast<Integer*>(pObj);
88 RequestId reqId = (RequestId)(pValue->ToInt());
90 pFactory->Remove(reqId);
93 __pUrlReqIDList->RemoveAll(true);
98 _ImageImpl::GetInstance(Image* pImage)
102 return pImage->__pImageImpl;
109 _ImageImpl::GetInstance(const Image* pImage)
113 return pImage->__pImageImpl;
120 _ImageImpl::Construct(void)
126 _ImageImpl::DecodeToBitmapN(const Tizen::Base::String& srcImagePath, Tizen::Graphics::BitmapPixelFormat pixelFormat)
128 std::unique_ptr<ByteBuffer> pBuf;
131 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
132 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
133 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
135 pBmp = DecodeToBitmapN(*pBuf.get(), pixelFormat);
140 _ImageImpl::DecodeToBitmapN(const Tizen::Base::ByteBuffer& srcImageBuf, Tizen::Graphics::BitmapPixelFormat pixelFormat)
142 result r = E_SUCCESS;
143 std::unique_ptr<ByteBuffer> pBuf;
144 std::unique_ptr<Bitmap> pBmp;
149 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat));
150 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
152 pBuf.reset(dec.DecodeN());
153 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
154 "[%s] Propagated", GetErrorMessage(GetLastResult()));
156 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
158 r = dec.GetDimension(outDim.width, outDim.height);
159 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
161 pBmp.reset(new (std::nothrow) Bitmap);
162 SysTryReturn(NID_MEDIA, pBmp != null, null, E_OUT_OF_MEMORY,
163 "[%s] new Bitmap", GetErrorMessage(GetLastResult()));
164 r = pBmp->Construct(*pBuf.get(), outDim, pixelFormat, BUFFER_SCALING_AUTO);
165 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
167 // Set transparency in case of rgb565 format
168 if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
170 short rgb565Chroma = 0;
171 Boolean transparency(false);
176 Color *pMaskingColor = null;
178 r = dec.GetValue(L"transparency", transparency);
179 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
180 if (transparency.ToBool() == true)
182 r = dec.GetValue(L"chromaKey", chromaKey);
183 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
185 rgb565Chroma = chromaKey.ToShort();
186 red = (rgb565Chroma & 0xf800) >> 8;
187 red = red | (red >> 5);
188 green = (rgb565Chroma & 0x07e0) >> 3;
189 green = green | (green >> 6);
190 blue = (rgb565Chroma & 0x001f) << 3;
191 blue = blue | (blue >> 5);
193 pMaskingColor = new Color(red, green, blue);
194 SysTryReturn(NID_MEDIA, pMaskingColor != null, pBmp.release(), E_SUCCESS,
195 "[%s] Could not apply masking color.", GetErrorMessage(r));
196 r = pBmp->SetMaskingColor(pMaskingColor);
197 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS,
198 "[%s] Could not set masking color.", GetErrorMessage(r));
199 delete pMaskingColor;
203 SetLastResult(E_SUCCESS);
204 return pBmp.release();
208 _ImageImpl::DecodeToBitmapN(const Tizen::Base::String& srcImagePath, Tizen::Graphics::BitmapPixelFormat pixelFormat, const Tizen::Graphics::Dimension &destDim,
209 Tizen::Graphics::BufferScaling bufferScaling)
211 std::unique_ptr<ByteBuffer> pBuf;
214 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
215 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
216 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
218 pBmp = DecodeToBitmapN(*pBuf.get(), pixelFormat, destDim, bufferScaling);
223 _ImageImpl::DecodeToBitmapN(const Tizen::Base::ByteBuffer& srcImageBuf, Tizen::Graphics::BitmapPixelFormat pixelFormat, const Tizen::Graphics::Dimension &destDim,
224 Tizen::Graphics::BufferScaling bufferScaling)
226 result r = E_SUCCESS;
227 std::unique_ptr<ByteBuffer> pBuf;
228 std::unique_ptr<Bitmap> pBmp;
233 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat));
234 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
236 // Reset decoder output demension
237 dec.SetOutputDimension(destDim.width, destDim.height, true);
239 pBuf.reset(dec.DecodeN());
240 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
241 "[%s] Propagated", GetErrorMessage(GetLastResult()));
243 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
245 r = dec.GetDimension(outDim.width, outDim.height);
246 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
248 pBmp.reset(new (std::nothrow) Bitmap);
249 SysTryReturn(NID_MEDIA, pBmp != null, null, E_OUT_OF_MEMORY,
250 "[%s] new Bitmap", GetErrorMessage(GetLastResult()));
251 r = pBmp->Construct(*pBuf.get(), outDim, pixelFormat, bufferScaling);
252 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
254 // Set transparency in case of rgb565 format
255 if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
257 short rgb565Chroma = 0;
258 Boolean transparency(false);
263 Color *pMaskingColor = null;
265 r = dec.GetValue(L"transparency", transparency);
266 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
267 if (transparency.ToBool() == true)
269 r = dec.GetValue(L"chromaKey", chromaKey);
270 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
272 rgb565Chroma = chromaKey.ToShort();
273 red = (rgb565Chroma & 0xf800) >> 8;
274 red = red | (red >> 5);
275 green = (rgb565Chroma & 0x07e0) >> 3;
276 green = green | (green >> 6);
277 blue = (rgb565Chroma & 0x001f) << 3;
278 blue = blue | (blue >> 5);
280 pMaskingColor = new Color(red, green, blue);
281 SysTryReturn(NID_MEDIA, pMaskingColor != null, pBmp.release(), E_SUCCESS,
282 "[%s] Could not apply masking color.", GetErrorMessage(r));
283 r = pBmp->SetMaskingColor(pMaskingColor);
284 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS,
285 "[%s] Could not set masking color.", GetErrorMessage(r));
286 delete pMaskingColor;
290 SetLastResult(E_SUCCESS);
291 return pBmp.release();
295 _ImageImpl::DecodeToBitmapN(const Tizen::Base::ByteBuffer& srcImageBuf, Tizen::Graphics::BitmapPixelFormat pixelFormat,
296 const Tizen::Graphics::FloatDimension &destDim)
298 result r = E_SUCCESS;
299 std::unique_ptr<ByteBuffer> pBuf;
300 std::unique_ptr<Bitmap> pBmp;
301 Dimension orgDim, tmpDim;
302 FloatDimension outDim;
307 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat));
308 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
310 r = dec.GetDimension(orgDim.width, orgDim.height);
311 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
313 // Reset decoder output demension
314 dec.SetOutputDimension(_CoordinateSystemUtils::ConvertToInteger(destDim.width),
315 _CoordinateSystemUtils::ConvertToInteger(destDim.height),
318 pBuf.reset(dec.DecodeN());
319 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
320 "[%s] Propagated", GetErrorMessage(GetLastResult()));
322 r = dec.GetDimension(tmpDim.width, tmpDim.height);
323 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
325 r = _ImageUtil::GetResizedDimension(orgDim.width, orgDim.height, destDim.width, destDim.height, outDim.width, outDim.height);
326 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
328 pBmp.reset(new (std::nothrow) Bitmap);
329 SysTryReturn(NID_MEDIA, pBmp.get() != null, null, E_OUT_OF_MEMORY,
330 "[%s] new Bitmap", GetErrorMessage(GetLastResult()));
332 pBmp.reset(_BitmapImpl::GetNonScaledBitmapN(*pBuf.get(), tmpDim, pixelFormat, destDim));
334 // Set transparency in case of rgb565 format
335 if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
337 short rgb565Chroma = 0;
338 Boolean transparency(false);
343 Color *pMaskingColor = null;
345 r = dec.GetValue(L"transparency", transparency);
346 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
347 if (transparency.ToBool() == true)
349 r = dec.GetValue(L"chromaKey", chromaKey);
350 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
352 rgb565Chroma = chromaKey.ToShort();
353 red = (rgb565Chroma & 0xf800) >> 8;
354 red = red | (red >> 5);
355 green = (rgb565Chroma & 0x07e0) >> 3;
356 green = green | (green >> 6);
357 blue = (rgb565Chroma & 0x001f) << 3;
358 blue = blue | (blue >> 5);
360 pMaskingColor = new Color(red, green, blue);
361 SysTryReturn(NID_MEDIA, pMaskingColor != null, pBmp.release(), E_SUCCESS,
362 "[%s] Could not apply masking color.", GetErrorMessage(r));
363 r = pBmp->SetMaskingColor(pMaskingColor);
364 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS,
365 "[%s] Could not set masking color.", GetErrorMessage(r));
366 delete pMaskingColor;
370 SetLastResult(E_SUCCESS);
371 return pBmp.release();
375 _ImageImpl::DecodeToBitmapN(const Tizen::Base::String& srcImagePath, Tizen::Graphics::BitmapPixelFormat pixelFormat,
376 const Tizen::Graphics::FloatDimension &destDim)
378 std::unique_ptr<ByteBuffer> pBuf;
381 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
382 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
383 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
385 pBmp = DecodeToBitmapN(*pBuf.get(), pixelFormat, destDim);
389 Tizen::Base::ByteBuffer*
390 _ImageImpl::DecodeToBufferN(const Tizen::Base::String& srcImagePath,
391 Tizen::Graphics::Dimension &restDim,
392 const Tizen::Graphics::Dimension &dstDim,
393 Tizen::Graphics::BitmapPixelFormat pixelFormat,
394 ImageFormat imgFormat, bool keepAspectRatio)
396 std::unique_ptr<ByteBuffer> pBuf;
397 ByteBuffer* pRetBuf = null;
399 //SysTryCatch(NID_MEDIA, IS_VALID_DIMENSION(dstDim), , E_OUT_OF_RANGE,
400 //"[E_OUT_OF_RANGE] dest dimension:%d,%d", dstDim.width, dstDim.height);
402 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
403 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
404 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
406 pRetBuf = DecodeToBufferN(*pBuf.get(), restDim, dstDim, pixelFormat, imgFormat, keepAspectRatio);
410 Tizen::Base::ByteBuffer*
411 _ImageImpl::DecodeToBufferN(const Tizen::Base::ByteBuffer &srcImageBuf,
412 Tizen::Graphics::Dimension &retDim,
413 const Tizen::Graphics::Dimension &dstDim,
414 Tizen::Graphics::BitmapPixelFormat pixelFormat,
415 ImageFormat imgFormat, bool keepAspectRatio)
417 result r = E_SUCCESS;
418 std::unique_ptr<ByteBuffer> pBuf;
421 //SysTryCatch(NID_MEDIA, IS_VALID_BITMAP_PIXEL(pixelFormat), , E_INVALID_ARG,
422 //"[E_INVALID_ARG] pixelFormat:%d", pixelFormat);
424 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat), imgFormat);
425 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
427 // Reset decoder output demension
428 dec.SetOutputDimension(dstDim.width, dstDim.height, keepAspectRatio);
430 pBuf.reset(dec.DecodeN());
432 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
434 r = dec.GetDimension(retDim.width, retDim.height);
435 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
437 SetLastResult(E_SUCCESS);
438 return pBuf.release();
441 Tizen::Base::ByteBuffer*
442 _ImageImpl::DecodeToBufferN(const Tizen::Base::String& srcImagePath,
443 Tizen::Graphics::BitmapPixelFormat pixelFormat,
444 int& imageWidth, int& imageHeight, bool keepAspectRatio)
446 ByteBuffer *pBuf = null;
449 pBuf = DecodeToBufferN(srcImagePath, dim, Dimension(0, 0), pixelFormat, IMG_FORMAT_NONE, keepAspectRatio);
450 imageWidth = dim.width;
451 imageHeight = dim.height;
456 Tizen::Base::ByteBuffer*
457 _ImageImpl::DecodeN(const Tizen::Base::String& srcImagePath,
458 Tizen::Graphics::BitmapPixelFormat pixelFormat,
459 int destWidth, int destHeight, bool keepAspectRatio)
463 return DecodeToBufferN(srcImagePath, dim, Dimension(destWidth, destHeight), pixelFormat, IMG_FORMAT_NONE, keepAspectRatio);
467 _ImageImpl::DecodeUrl(const Tizen::Base::Utility::Uri& srcImageUrl,
468 Tizen::Graphics::BitmapPixelFormat colorFormat,
469 int destWidth, int destHeight, RequestId& reqId,
470 const IImageDecodeUrlEventListener& listener, long timeout)
472 result r = E_SUCCESS;
474 _ImageUriDataFactory *pFactory = null;
476 SysTryCatch(NID_MEDIA, (colorFormat > Tizen::Graphics::BITMAP_PIXEL_FORMAT_MIN)
477 && colorFormat < Tizen::Graphics::BITMAP_PIXEL_FORMAT_MAX, , E_INVALID_ARG,
478 "[E_INVALID_ARG] Wrong color format.");
480 SysTryCatch(NID_MEDIA, destWidth > 0 && destHeight > 0, , E_OUT_OF_RANGE,
481 "[E_OUT_OF_RANGE] The designated width and height SHOUL be greater than 0.");
483 SysTryCatch(NID_MEDIA, timeout == _TIMEOUT_INFINITE || timeout > 0 ,
484 r = E_OUT_OF_RANGE, E_OUT_OF_RANGE,
485 "[E_OUT_OF_RANGE] The designated timeout SHOUL be greater than 0");
487 pFactory = _ImageUriDataFactory::GetInstance();
488 SysTryCatch(NID_MEDIA, pFactory != null, r = GetLastResult(), r,
489 "[%s] Failed to GetInstance().", GetErrorMessage(r));
491 r = pFactory->DecodeUrl(srcImageUrl, colorFormat, destWidth,destHeight, reqId, listener, timeout);
492 SysTryCatch(NID_MEDIA, r == E_SUCCESS , , r,"[%s] Propagated.", GetErrorMessage(r));
494 if (__pUrlReqIDList.get() == null)
496 __pUrlReqIDList.reset(new (std::nothrow)Collection::LinkedList());
497 SysTryCatch(NID_MEDIA, __pUrlReqIDList.get() != null, r = E_OUT_OF_MEMORY, r,
498 "[E_OUT_OF_MEMORY] Propagated. Failed to allocate a LinkedList.", GetErrorMessage(r));
500 __pUrlReqIDList->Add(new (std::nothrow) Integer(reqId));
509 _ImageImpl::EncodeToBufferN(const Bitmap& srcBmp, ImageFormat dstFormat)
511 std::unique_ptr<ByteBuffer> pBuf;
515 // ClearLastResult();
517 Tizen::Graphics::Bitmap& tmpBmp = const_cast<Tizen::Graphics::Bitmap&>(srcBmp);
520 tmpBmp.Lock(bmpInfo);
522 dim.SetSize(bmpInfo.width, bmpInfo.height);
524 // TODO: handle case that pitch != width * bpp/8
525 SysTryReturn(NID_MEDIA, bmpInfo.pitch == bmpInfo.width*bmpInfo.bitsPerPixel/8, null, E_SYSTEM,
526 "[E_SYSTEM] pitch=%d bpp=%d", bmpInfo.pitch, bmpInfo.bitsPerPixel);
528 pBuf.reset(_ImageEncoder::EncodeN(dstFormat, (const byte*)bmpInfo.pPixels, bmpInfo.pitch * bmpInfo.height,
529 dim.width, dim.height,
530 _ImageUtilImpl::ToMediaPixelFormat(srcBmp.GetPixelColorFormat()),
531 _DEFAULT_ENCODE_QUALITY));
532 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(), "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
534 return pBuf.release();
538 _ImageImpl::EncodeToFile(const Bitmap& srcBmp, ImageFormat dstFormat,
539 const String& dstPath, bool overwrite)
541 result r = E_SUCCESS;
542 std::unique_ptr<ByteBuffer> pBuf;
544 pBuf.reset(EncodeToBufferN(srcBmp, dstFormat));
545 SysTryReturn(NID_MEDIA, pBuf.get() != null, GetLastResult(), GetLastResult(),
546 "[%s] Propagated.", GetErrorMessage(GetLastResult()));
548 r = _MediaUtil::BufferToFile(*pBuf.get(), dstPath, overwrite);
549 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
555 Tizen::Base::ByteBuffer*
556 _ImageImpl::CompressJpegN(const Tizen::Base::ByteBuffer& srcImageBuf, int limitSize)
558 result r = E_SUCCESS;
559 std::unique_ptr<ByteBuffer> pDecBuf;
560 std::unique_ptr<ByteBuffer> pEncBuf;
563 volatile int limit = limitSize;
564 MediaPixelFormat pixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888;
566 // TODO : use yuv pixel format
568 r = dec.Construct(srcImageBuf, pixelFormat);
569 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
571 pDecBuf.reset(dec.DecodeN());
573 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
574 SysTryReturn(NID_MEDIA, pDecBuf.get() != null, null, E_SYSTEM, "[E_SYSTEM] Propagated.");
576 r = dec.GetDimension(srcDim.width, srcDim.height);
577 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
579 for (int i = 0; i < _MAX_ENCODE_RESIZE_LOOP; i++)
582 ByteBuffer *pTmpBuf = null;
584 pEncBuf.reset(EncodeToBufferLimitN(*pDecBuf.get(), srcDim, pixelFormat, IMG_FORMAT_JPG, limit));
586 if (pEncBuf.get() != null)
591 // halve and make even number
592 dstDim.width = srcDim.width >> 2;
593 dstDim.height = srcDim.height >> 2;
595 dstDim.width = dstDim.width << 1;
596 dstDim.height = dstDim.height << 1;
598 SysTryReturn(NID_MEDIA, srcDim != dstDim && dstDim.width > 0 && dstDim.height > 0, null, E_SYSTEM,
599 "[E_SYSTEM] Resize failed:src:%dx%d dst:%dx%d, %d %d, %d",
600 srcDim.width, srcDim.height, dstDim.width, dstDim.height, i, _SCALE_DOWN_RATIO,
603 pTmpBuf = _ImageUtilImpl::ResizeN(*pDecBuf.get(), srcDim, pixelFormat, dstDim);
604 SysTryReturn(NID_MEDIA, pTmpBuf != null, null, GetLastResult(),
605 "[%s] ResizeN: %dx%d->%dx%d", GetErrorMessage(GetLastResult()),
606 srcDim.width, srcDim.height, dstDim.width, dstDim.height);
609 pDecBuf.reset(pTmpBuf);
611 SysTryReturn(NID_MEDIA, pEncBuf.get() != null, null, E_SYSTEM, "[E_SYSTEM] Compress failed");
612 SetLastResult(E_SUCCESS);
613 return pEncBuf.release();
617 _ImageImpl::CompressJpeg(const Tizen::Base::String& srcImagePath,
618 const Tizen::Base::String& dstImagePath, int limitSize)
621 result r = E_SUCCESS;
622 std::unique_ptr<ByteBuffer> pSrcBuf;
623 std::unique_ptr<ByteBuffer> pEncBuf;
625 pSrcBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
626 SysTryReturn(NID_MEDIA, pSrcBuf.get() != null, GetLastResult(), GetLastResult(),
627 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
629 // SysTryCatch(NID_MEDIA, pSrcBuf->GetCapacity() < MAX_IMGFILE_SIZE, r = E_OVERFLOW, E_OVERFLOW,
630 // "[E_OUT_OF_RANGE] Input file size is smaller than limitSize.");
632 SysTryReturn(NID_MEDIA, pSrcBuf.get()->GetCapacity() > limitSize, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
633 "[E_OUT_OF_RANGE] Input file size is smaller than limitSize.");
635 pEncBuf.reset(CompressJpegN(*pSrcBuf, limitSize));
636 SysTryReturn(NID_MEDIA, pEncBuf != null, GetLastResult(), GetLastResult(),
637 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
639 if (File::IsFileExist(dstImagePath))
641 File::Remove(dstImagePath);
644 r = file.Construct(dstImagePath, "wb", true);
645 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
646 r = file.Write(*pEncBuf);
647 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
652 Tizen::Base::ByteBuffer*
653 _ImageImpl::ConvertToBufferN(const Tizen::Base::String& srcImagePath, ImageFormat destImageFormat)
655 std::unique_ptr<Bitmap> pBmp;
656 ByteBuffer* pBuf = null;
658 pBmp.reset(DecodeToBitmapN(srcImagePath, BITMAP_PIXEL_FORMAT_ARGB8888, Dimension(0, 0),
659 BUFFER_SCALING_NONE));
660 SysTryReturn(NID_MEDIA, pBmp.get(), null, GetLastResult(),
661 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
663 pBuf = EncodeToBufferN(*pBmp.get(), destImageFormat);
664 SysTryReturn(NID_MEDIA, pBuf != null, null, GetLastResult(),
665 "[%s] Propagated.", GetErrorMessage(GetLastResult()));
667 SetLastResult(E_SUCCESS);
671 Tizen::Base::ByteBuffer*
672 _ImageImpl::EncodeToBufferLimitN(const Tizen::Base::ByteBuffer &srcBuf,
673 const Tizen::Graphics::Dimension& dim,
674 MediaPixelFormat pixelFormat, ImageFormat imgFormat, int limit)
676 int minQuality = _MIN_ENCODE_QUALITY;
677 int maxQuality = _MAX_ENCODE_QUALITY;
682 std::unique_ptr<ByteBuffer> pMaxBuf;
683 std::unique_ptr<ByteBuffer> pMinBuf;
685 pMaxBuf.reset(EncodeToBufferQualityN(srcBuf, dim, pixelFormat, imgFormat, maxQuality));
686 SysTryReturn(NID_MEDIA, pMaxBuf.get() != null, pMinBuf.get(), E_SYSTEM, "[E_SYSTEM] maxBuf is null");
687 maxDiff = pMaxBuf->GetLimit() - limit;
688 SysLog(NID_MEDIA, "maxDiff:%d buf:%d limit:%d q:%d",
689 maxDiff, pMaxBuf->GetLimit(), limit, maxQuality);
692 SetLastResult(E_SUCCESS);
693 return pMaxBuf.release();
695 pMinBuf.reset(EncodeToBufferQualityN(srcBuf, dim, pixelFormat, imgFormat, minQuality));
696 SysTryReturn(NID_MEDIA, pMinBuf.get() != null, pMinBuf.release(), E_SYSTEM, "[E_SYSTEM] minBuf is null");
697 minDiff = pMinBuf->GetLimit() - limit;
698 SysLog(NID_MEDIA, "minDiff:%d buf:%d limit:%d q:%d",
699 minDiff, pMinBuf->GetLimit(), limit, minQuality);
702 SetLastResult(E_OVERFLOW);
707 SetLastResult(E_SUCCESS);
708 return pMinBuf.release();
711 for (int i = 0; i < _MAX_ENCODE_LOOP; i++)
713 int prevQuality = curQuality;
715 ByteBuffer *pCurBuf = null;
717 curQuality = (minQuality + maxQuality) / 2;
718 if (prevQuality == curQuality)
722 pCurBuf = EncodeToBufferQualityN(srcBuf, dim, pixelFormat, imgFormat, curQuality);
723 if (pCurBuf == null && pMinBuf.get() != null)
727 SysTryReturn(NID_MEDIA, pCurBuf != null, pMinBuf.release(), E_SYSTEM,
728 "[E_SYSTEM] curBuf is null : %d %d %d", dim.width, dim.height, curQuality);
729 curDiff = pCurBuf->GetLimit() - limit;
730 SysLog(NID_MEDIA, "curDiff:%d buf:%d limit:%d q:%d",
731 curDiff, pCurBuf->GetLimit(), limit, curQuality);
734 SetLastResult(E_SUCCESS);
737 else if (curDiff > 0)
740 maxQuality = curQuality;
741 pMaxBuf.reset(pCurBuf);
743 else if (curDiff < 0)
745 pMinBuf.reset(pCurBuf);
747 minQuality = curQuality;
752 SetLastResult(E_SUCCESS);
756 // should not come here.
757 SetLastResult(E_SYSTEM);
759 return pMinBuf.release();
762 Tizen::Base::ByteBuffer*
763 _ImageImpl::EncodeToBufferQualityN(const Tizen::Base::ByteBuffer &srcBuf,
764 const Tizen::Graphics::Dimension& dim,
765 MediaPixelFormat pixelFormat, ImageFormat imgFormat, int quality)
767 ByteBuffer* pBuf = null;
769 pBuf = _ImageEncoder::EncodeN(imgFormat, srcBuf.GetPointer(), srcBuf.GetLimit(),
770 dim.width, dim.height, pixelFormat, quality);
771 SysTryReturn(NID_MEDIA, pBuf != null, pBuf, GetLastResult(),
772 "[%s] enc.EncodeN. ", GetErrorMessage(GetLastResult()));
778 _ImageImpl::GetImageInfo(const Tizen::Base::String& path, ImageFormat &imgFormat,
779 Tizen::Graphics::Dimension &dim)
781 return _ImageDecoder::GetImageInfo(path, imgFormat, dim.width, dim.height);