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 if (__pUrlReqIDList.get() != null)
68 _ImageUriDataFactory *pFactory = null;
70 pFactory = _ImageUriDataFactory::GetInstance();
71 SysTryReturn(NID_MEDIA, pFactory != null, , GetLastResult(), "[%s] Failed to get Factory instance.",
72 GetErrorMessage(GetLastResult()));
75 num = __pUrlReqIDList->GetCount();
76 for (int i = 0; i < num; i++)
78 pObj = __pUrlReqIDList->GetAt(i);
81 Integer *pValue = dynamic_cast<Integer*>(pObj);
87 RequestId reqId = (RequestId)(pValue->ToInt());
89 pFactory->Remove(reqId);
92 __pUrlReqIDList->RemoveAll(true);
97 _ImageImpl::GetInstance(Image* pImage)
101 return pImage->__pImageImpl;
108 _ImageImpl::GetInstance(const Image* pImage)
112 return pImage->__pImageImpl;
119 _ImageImpl::Construct(void)
125 _ImageImpl::DecodeToBitmapN(const Tizen::Base::String& srcImagePath, Tizen::Graphics::BitmapPixelFormat pixelFormat)
127 std::unique_ptr<ByteBuffer> pBuf;
130 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
131 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
132 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
134 pBmp = DecodeToBitmapN(*pBuf.get(), pixelFormat);
139 _ImageImpl::DecodeToBitmapN(const Tizen::Base::ByteBuffer& srcImageBuf, Tizen::Graphics::BitmapPixelFormat pixelFormat)
141 result r = E_SUCCESS;
142 std::unique_ptr<ByteBuffer> pBuf;
143 std::unique_ptr<Bitmap> pBmp;
148 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat));
149 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
151 pBuf.reset(dec.DecodeN());
152 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
153 "[%s] Propagated", GetErrorMessage(GetLastResult()));
155 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
157 r = dec.GetDimension(outDim.width, outDim.height);
158 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
160 pBmp.reset(new (std::nothrow) Bitmap);
161 SysTryReturn(NID_MEDIA, pBmp != null, null, E_OUT_OF_MEMORY,
162 "[%s] new Bitmap", GetErrorMessage(GetLastResult()));
163 r = pBmp->Construct(*pBuf.get(), outDim, pixelFormat, BUFFER_SCALING_AUTO);
164 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
166 // Set transparency in case of rgb565 format
167 if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
169 short rgb565Chroma = 0;
170 Boolean transparency(false);
175 Color *pMaskingColor = null;
177 r = dec.GetValue(L"transparency", transparency);
178 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
179 if (transparency.ToBool() == true)
181 r = dec.GetValue(L"chromaKey", chromaKey);
182 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
184 rgb565Chroma = chromaKey.ToShort();
185 red = (rgb565Chroma & 0xf800) >> 8;
186 red = red | (red >> 5);
187 green = (rgb565Chroma & 0x07e0) >> 3;
188 green = green | (green >> 6);
189 blue = (rgb565Chroma & 0x001f) << 3;
190 blue = blue | (blue >> 5);
192 pMaskingColor = new Color(red, green, blue);
193 SysTryReturn(NID_MEDIA, pMaskingColor != null, pBmp.release(), E_SUCCESS,
194 "[%s] Could not apply masking color.", GetErrorMessage(r));
195 r = pBmp->SetMaskingColor(pMaskingColor);
196 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS,
197 "[%s] Could not set masking color.", GetErrorMessage(r));
198 delete pMaskingColor;
202 SetLastResult(E_SUCCESS);
203 return pBmp.release();
207 _ImageImpl::DecodeToBitmapN(const Tizen::Base::String& srcImagePath, Tizen::Graphics::BitmapPixelFormat pixelFormat, const Tizen::Graphics::Dimension &destDim,
208 Tizen::Graphics::BufferScaling bufferScaling)
210 std::unique_ptr<ByteBuffer> pBuf;
213 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
214 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
215 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
217 pBmp = DecodeToBitmapN(*pBuf.get(), pixelFormat, destDim, bufferScaling);
222 _ImageImpl::DecodeToBitmapN(const Tizen::Base::ByteBuffer& srcImageBuf, Tizen::Graphics::BitmapPixelFormat pixelFormat, const Tizen::Graphics::Dimension &destDim,
223 Tizen::Graphics::BufferScaling bufferScaling)
225 result r = E_SUCCESS;
226 std::unique_ptr<ByteBuffer> pBuf;
227 std::unique_ptr<Bitmap> pBmp;
232 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat));
233 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
235 // Reset decoder output demension
236 dec.SetOutputDimension(destDim.width, destDim.height, true);
238 pBuf.reset(dec.DecodeN());
239 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
240 "[%s] Propagated", GetErrorMessage(GetLastResult()));
242 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
244 r = dec.GetDimension(outDim.width, outDim.height);
245 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
247 pBmp.reset(new (std::nothrow) Bitmap);
248 SysTryReturn(NID_MEDIA, pBmp != null, null, E_OUT_OF_MEMORY,
249 "[%s] new Bitmap", GetErrorMessage(GetLastResult()));
250 r = pBmp->Construct(*pBuf.get(), outDim, pixelFormat, bufferScaling);
251 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
253 // Set transparency in case of rgb565 format
254 if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
256 short rgb565Chroma = 0;
257 Boolean transparency(false);
262 Color *pMaskingColor = null;
264 r = dec.GetValue(L"transparency", transparency);
265 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
266 if (transparency.ToBool() == true)
268 r = dec.GetValue(L"chromaKey", chromaKey);
269 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
271 rgb565Chroma = chromaKey.ToShort();
272 red = (rgb565Chroma & 0xf800) >> 8;
273 red = red | (red >> 5);
274 green = (rgb565Chroma & 0x07e0) >> 3;
275 green = green | (green >> 6);
276 blue = (rgb565Chroma & 0x001f) << 3;
277 blue = blue | (blue >> 5);
279 pMaskingColor = new Color(red, green, blue);
280 SysTryReturn(NID_MEDIA, pMaskingColor != null, pBmp.release(), E_SUCCESS,
281 "[%s] Could not apply masking color.", GetErrorMessage(r));
282 r = pBmp->SetMaskingColor(pMaskingColor);
283 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS,
284 "[%s] Could not set masking color.", GetErrorMessage(r));
285 delete pMaskingColor;
289 SetLastResult(E_SUCCESS);
290 return pBmp.release();
294 _ImageImpl::DecodeToBitmapN(const Tizen::Base::ByteBuffer& srcImageBuf, Tizen::Graphics::BitmapPixelFormat pixelFormat,
295 const Tizen::Graphics::FloatDimension &destDim)
297 result r = E_SUCCESS;
298 std::unique_ptr<ByteBuffer> pBuf;
299 std::unique_ptr<Bitmap> pBmp;
300 Dimension orgDim, tmpDim;
301 FloatDimension outDim;
306 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat));
307 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
309 r = dec.GetDimension(orgDim.width, orgDim.height);
310 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
312 // Reset decoder output demension
313 dec.SetOutputDimension(_CoordinateSystemUtils::ConvertToInteger(destDim.width),
314 _CoordinateSystemUtils::ConvertToInteger(destDim.height),
317 pBuf.reset(dec.DecodeN());
318 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
319 "[%s] Propagated", GetErrorMessage(GetLastResult()));
321 r = dec.GetDimension(tmpDim.width, tmpDim.height);
322 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
324 r = _ImageUtil::GetResizedDimension(orgDim.width, orgDim.height, destDim.width, destDim.height, outDim.width, outDim.height);
325 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
327 pBmp.reset(new (std::nothrow) Bitmap);
328 SysTryReturn(NID_MEDIA, pBmp.get() != null, null, E_OUT_OF_MEMORY,
329 "[%s] new Bitmap", GetErrorMessage(GetLastResult()));
331 pBmp.reset(_BitmapImpl::GetNonScaledBitmapN(*pBuf.get(), tmpDim, pixelFormat, destDim));
333 // Set transparency in case of rgb565 format
334 if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
336 short rgb565Chroma = 0;
337 Boolean transparency(false);
342 Color *pMaskingColor = null;
344 r = dec.GetValue(L"transparency", transparency);
345 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
346 if (transparency.ToBool() == true)
348 r = dec.GetValue(L"chromaKey", chromaKey);
349 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
351 rgb565Chroma = chromaKey.ToShort();
352 red = (rgb565Chroma & 0xf800) >> 8;
353 red = red | (red >> 5);
354 green = (rgb565Chroma & 0x07e0) >> 3;
355 green = green | (green >> 6);
356 blue = (rgb565Chroma & 0x001f) << 3;
357 blue = blue | (blue >> 5);
359 pMaskingColor = new Color(red, green, blue);
360 SysTryReturn(NID_MEDIA, pMaskingColor != null, pBmp.release(), E_SUCCESS,
361 "[%s] Could not apply masking color.", GetErrorMessage(r));
362 r = pBmp->SetMaskingColor(pMaskingColor);
363 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS,
364 "[%s] Could not set masking color.", GetErrorMessage(r));
365 delete pMaskingColor;
369 SetLastResult(E_SUCCESS);
370 return pBmp.release();
374 _ImageImpl::DecodeToBitmapN(const Tizen::Base::String& srcImagePath, Tizen::Graphics::BitmapPixelFormat pixelFormat,
375 const Tizen::Graphics::FloatDimension &destDim)
377 std::unique_ptr<ByteBuffer> pBuf;
380 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
381 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
382 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
384 pBmp = DecodeToBitmapN(*pBuf.get(), pixelFormat, destDim);
388 Tizen::Base::ByteBuffer*
389 _ImageImpl::DecodeToBufferN(const Tizen::Base::String& srcImagePath,
390 Tizen::Graphics::Dimension &restDim,
391 const Tizen::Graphics::Dimension &dstDim,
392 Tizen::Graphics::BitmapPixelFormat pixelFormat,
393 ImageFormat imgFormat, bool keepAspectRatio)
395 std::unique_ptr<ByteBuffer> pBuf;
396 ByteBuffer* pRetBuf = null;
398 //SysTryCatch(NID_MEDIA, IS_VALID_DIMENSION(dstDim), , E_OUT_OF_RANGE,
399 //"[E_OUT_OF_RANGE] dest dimension:%d,%d", dstDim.width, dstDim.height);
401 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
402 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
403 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
405 pRetBuf = DecodeToBufferN(*pBuf.get(), restDim, dstDim, pixelFormat, imgFormat, keepAspectRatio);
409 Tizen::Base::ByteBuffer*
410 _ImageImpl::DecodeToBufferN(const Tizen::Base::ByteBuffer &srcImageBuf,
411 Tizen::Graphics::Dimension &retDim,
412 const Tizen::Graphics::Dimension &dstDim,
413 Tizen::Graphics::BitmapPixelFormat pixelFormat,
414 ImageFormat imgFormat, bool keepAspectRatio)
416 result r = E_SUCCESS;
417 std::unique_ptr<ByteBuffer> pBuf;
420 //SysTryCatch(NID_MEDIA, IS_VALID_BITMAP_PIXEL(pixelFormat), , E_INVALID_ARG,
421 //"[E_INVALID_ARG] pixelFormat:%d", pixelFormat);
423 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat), imgFormat);
424 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
426 // Reset decoder output demension
427 dec.SetOutputDimension(dstDim.width, dstDim.height, keepAspectRatio);
429 pBuf.reset(dec.DecodeN());
431 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
433 r = dec.GetDimension(retDim.width, retDim.height);
434 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
436 SetLastResult(E_SUCCESS);
437 return pBuf.release();
440 Tizen::Base::ByteBuffer*
441 _ImageImpl::DecodeToBufferN(const Tizen::Base::String& srcImagePath,
442 Tizen::Graphics::BitmapPixelFormat pixelFormat,
443 int& imageWidth, int& imageHeight, bool keepAspectRatio)
445 ByteBuffer *pBuf = null;
448 pBuf = DecodeToBufferN(srcImagePath, dim, Dimension(0, 0), pixelFormat, IMG_FORMAT_NONE, keepAspectRatio);
449 imageWidth = dim.width;
450 imageHeight = dim.height;
455 Tizen::Base::ByteBuffer*
456 _ImageImpl::DecodeN(const Tizen::Base::String& srcImagePath,
457 Tizen::Graphics::BitmapPixelFormat pixelFormat,
458 int destWidth, int destHeight, bool keepAspectRatio)
462 return DecodeToBufferN(srcImagePath, dim, Dimension(destWidth, destHeight), pixelFormat, IMG_FORMAT_NONE, keepAspectRatio);
466 _ImageImpl::DecodeUrl(const Tizen::Base::Utility::Uri& srcImageUrl,
467 Tizen::Graphics::BitmapPixelFormat colorFormat,
468 int destWidth, int destHeight, RequestId& reqId,
469 const IImageDecodeUrlEventListener& listener, long timeout)
471 result r = E_SUCCESS;
473 _ImageUriDataFactory *pFactory = null;
475 SysTryCatch(NID_MEDIA, (colorFormat > Tizen::Graphics::BITMAP_PIXEL_FORMAT_MIN)
476 && colorFormat < Tizen::Graphics::BITMAP_PIXEL_FORMAT_MAX, , E_INVALID_ARG,
477 "[E_INVALID_ARG] Wrong color format.");
479 SysTryCatch(NID_MEDIA, destWidth > 0 && destHeight > 0, , E_OUT_OF_RANGE,
480 "[E_OUT_OF_RANGE] The designated width and height SHOUL be greater than 0.");
482 SysTryCatch(NID_MEDIA, timeout == _TIMEOUT_INFINITE || timeout > 0 ,
483 r = E_OUT_OF_RANGE, E_OUT_OF_RANGE,
484 "[E_OUT_OF_RANGE] The designated timeout SHOUL be greater than 0");
486 pFactory = _ImageUriDataFactory::GetInstance();
487 SysTryCatch(NID_MEDIA, pFactory != null, r = GetLastResult(), r,
488 "[%s] Failed to GetInstance().", GetErrorMessage(r));
490 r = pFactory->DecodeUrl(srcImageUrl, colorFormat, destWidth,destHeight, reqId, listener, timeout);
491 SysTryCatch(NID_MEDIA, r == E_SUCCESS , , r,"[%s] Propagated.", GetErrorMessage(r));
493 if (__pUrlReqIDList.get() == null)
495 __pUrlReqIDList.reset(new (std::nothrow)Collection::LinkedList());
496 SysTryCatch(NID_MEDIA, __pUrlReqIDList.get() != null, r = E_OUT_OF_MEMORY, r,
497 "[E_OUT_OF_MEMORY] Propagated. Failed to allocate a LinkedList.", GetErrorMessage(r));
499 __pUrlReqIDList->Add(new (std::nothrow) Integer(reqId));
508 _ImageImpl::EncodeToBufferN(const Bitmap& srcBmp, ImageFormat dstFormat)
510 std::unique_ptr<ByteBuffer> pBuf;
514 // ClearLastResult();
516 Tizen::Graphics::Bitmap& tmpBmp = const_cast<Tizen::Graphics::Bitmap&>(srcBmp);
519 tmpBmp.Lock(bmpInfo);
521 dim.SetSize(bmpInfo.width, bmpInfo.height);
523 // TODO: handle case that pitch != width * bpp/8
524 SysTryReturn(NID_MEDIA, bmpInfo.pitch == bmpInfo.width*bmpInfo.bitsPerPixel/8, null, E_SYSTEM,
525 "[E_SYSTEM] pitch=%d bpp=%d", bmpInfo.pitch, bmpInfo.bitsPerPixel);
527 pBuf.reset(_ImageEncoder::EncodeN(dstFormat, (const byte*)bmpInfo.pPixels, bmpInfo.pitch * bmpInfo.height,
528 dim.width, dim.height,
529 _ImageUtilImpl::ToMediaPixelFormat(srcBmp.GetPixelColorFormat()),
530 _DEFAULT_ENCODE_QUALITY));
531 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(), "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
533 return pBuf.release();
537 _ImageImpl::EncodeToFile(const Bitmap& srcBmp, ImageFormat dstFormat,
538 const String& dstPath, bool overwrite)
540 result r = E_SUCCESS;
541 std::unique_ptr<ByteBuffer> pBuf;
543 pBuf.reset(EncodeToBufferN(srcBmp, dstFormat));
544 SysTryReturn(NID_MEDIA, pBuf.get() != null, GetLastResult(), GetLastResult(),
545 "[%s] Propagated.", GetErrorMessage(GetLastResult()));
547 r = _MediaUtil::BufferToFile(*pBuf.get(), dstPath, overwrite);
548 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
554 Tizen::Base::ByteBuffer*
555 _ImageImpl::CompressJpegN(const Tizen::Base::ByteBuffer& srcImageBuf, int limitSize)
557 result r = E_SUCCESS;
558 std::unique_ptr<ByteBuffer> pDecBuf;
559 std::unique_ptr<ByteBuffer> pEncBuf;
562 volatile int limit = limitSize;
563 MediaPixelFormat pixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888;
565 // TODO : use yuv pixel format
567 r = dec.Construct(srcImageBuf, pixelFormat);
568 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
570 pDecBuf.reset(dec.DecodeN());
572 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
573 SysTryReturn(NID_MEDIA, pDecBuf.get() != null, null, E_SYSTEM, "[E_SYSTEM] Propagated.");
575 r = dec.GetDimension(srcDim.width, srcDim.height);
576 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
578 for (int i = 0; i < _MAX_ENCODE_RESIZE_LOOP; i++)
581 ByteBuffer *pTmpBuf = null;
583 pEncBuf.reset(EncodeToBufferLimitN(*pDecBuf.get(), srcDim, pixelFormat, IMG_FORMAT_JPG, limit));
585 if (pEncBuf.get() != null)
590 // halve and make even number
591 dstDim.width = srcDim.width >> 2;
592 dstDim.height = srcDim.height >> 2;
594 dstDim.width = dstDim.width << 1;
595 dstDim.height = dstDim.height << 1;
597 SysTryReturn(NID_MEDIA, srcDim != dstDim && dstDim.width > 0 && dstDim.height > 0, null, E_SYSTEM,
598 "[E_SYSTEM] Resize failed:src:%dx%d dst:%dx%d, %d %d, %d",
599 srcDim.width, srcDim.height, dstDim.width, dstDim.height, i, _SCALE_DOWN_RATIO,
602 pTmpBuf = _ImageUtilImpl::ResizeN(*pDecBuf.get(), srcDim, pixelFormat, dstDim);
603 SysTryReturn(NID_MEDIA, pTmpBuf != null, null, GetLastResult(),
604 "[%s] ResizeN: %dx%d->%dx%d", GetErrorMessage(GetLastResult()),
605 srcDim.width, srcDim.height, dstDim.width, dstDim.height);
608 pDecBuf.reset(pTmpBuf);
610 SysTryReturn(NID_MEDIA, pEncBuf.get() != null, null, E_SYSTEM, "[E_SYSTEM] Compress failed");
611 SetLastResult(E_SUCCESS);
612 return pEncBuf.release();
616 _ImageImpl::CompressJpeg(const Tizen::Base::String& srcImagePath,
617 const Tizen::Base::String& dstImagePath, int limitSize)
620 result r = E_SUCCESS;
621 std::unique_ptr<ByteBuffer> pSrcBuf;
622 std::unique_ptr<ByteBuffer> pEncBuf;
624 pSrcBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
625 SysTryReturn(NID_MEDIA, pSrcBuf.get() != null, GetLastResult(), GetLastResult(),
626 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
628 // SysTryCatch(NID_MEDIA, pSrcBuf->GetCapacity() < MAX_IMGFILE_SIZE, r = E_OVERFLOW, E_OVERFLOW,
629 // "[E_OUT_OF_RANGE] Input file size is smaller than limitSize.");
631 SysTryReturn(NID_MEDIA, pSrcBuf.get()->GetCapacity() > limitSize, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
632 "[E_OUT_OF_RANGE] Input file size is smaller than limitSize.");
634 pEncBuf.reset(CompressJpegN(*pSrcBuf, limitSize));
635 SysTryReturn(NID_MEDIA, pEncBuf != null, GetLastResult(), GetLastResult(),
636 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
638 if (File::IsFileExist(dstImagePath))
640 File::Remove(dstImagePath);
643 r = file.Construct(dstImagePath, "wb", true);
644 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
645 r = file.Write(*pEncBuf);
646 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
651 Tizen::Base::ByteBuffer*
652 _ImageImpl::ConvertToBufferN(const Tizen::Base::String& srcImagePath, ImageFormat destImageFormat)
654 std::unique_ptr<Bitmap> pBmp;
655 ByteBuffer* pBuf = null;
657 pBmp.reset(DecodeToBitmapN(srcImagePath, BITMAP_PIXEL_FORMAT_ARGB8888, Dimension(0, 0),
658 BUFFER_SCALING_NONE));
659 SysTryReturn(NID_MEDIA, pBmp.get(), null, GetLastResult(),
660 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
662 pBuf = EncodeToBufferN(*pBmp.get(), destImageFormat);
663 SysTryReturn(NID_MEDIA, pBuf != null, null, GetLastResult(),
664 "[%s] Propagated.", GetErrorMessage(GetLastResult()));
666 SetLastResult(E_SUCCESS);
670 Tizen::Base::ByteBuffer*
671 _ImageImpl::EncodeToBufferLimitN(const Tizen::Base::ByteBuffer &srcBuf,
672 const Tizen::Graphics::Dimension& dim,
673 MediaPixelFormat pixelFormat, ImageFormat imgFormat, int limit)
675 int minQuality = _MIN_ENCODE_QUALITY;
676 int maxQuality = _MAX_ENCODE_QUALITY;
681 std::unique_ptr<ByteBuffer> pMaxBuf;
682 std::unique_ptr<ByteBuffer> pMinBuf;
684 pMaxBuf.reset(EncodeToBufferQualityN(srcBuf, dim, pixelFormat, imgFormat, maxQuality));
685 SysTryReturn(NID_MEDIA, pMaxBuf.get() != null, pMinBuf.get(), E_SYSTEM, "[E_SYSTEM] maxBuf is null");
686 maxDiff = pMaxBuf->GetLimit() - limit;
687 SysLog(NID_MEDIA, "maxDiff:%d buf:%d limit:%d q:%d",
688 maxDiff, pMaxBuf->GetLimit(), limit, maxQuality);
691 SetLastResult(E_SUCCESS);
692 return pMaxBuf.release();
694 pMinBuf.reset(EncodeToBufferQualityN(srcBuf, dim, pixelFormat, imgFormat, minQuality));
695 SysTryReturn(NID_MEDIA, pMinBuf.get() != null, pMinBuf.release(), E_SYSTEM, "[E_SYSTEM] minBuf is null");
696 minDiff = pMinBuf->GetLimit() - limit;
697 SysLog(NID_MEDIA, "minDiff:%d buf:%d limit:%d q:%d",
698 minDiff, pMinBuf->GetLimit(), limit, minQuality);
701 SetLastResult(E_OVERFLOW);
706 SetLastResult(E_SUCCESS);
707 return pMinBuf.release();
710 for (int i = 0; i < _MAX_ENCODE_LOOP; i++)
712 int prevQuality = curQuality;
714 ByteBuffer *pCurBuf = null;
716 curQuality = (minQuality + maxQuality) / 2;
717 if (prevQuality == curQuality)
721 pCurBuf = EncodeToBufferQualityN(srcBuf, dim, pixelFormat, imgFormat, curQuality);
722 if (pCurBuf == null && pMinBuf.get() != null)
726 SysTryReturn(NID_MEDIA, pCurBuf != null, pMinBuf.release(), E_SYSTEM,
727 "[E_SYSTEM] curBuf is null : %d %d %d", dim.width, dim.height, curQuality);
728 curDiff = pCurBuf->GetLimit() - limit;
729 SysLog(NID_MEDIA, "curDiff:%d buf:%d limit:%d q:%d",
730 curDiff, pCurBuf->GetLimit(), limit, curQuality);
733 SetLastResult(E_SUCCESS);
736 else if (curDiff > 0)
739 maxQuality = curQuality;
740 pMaxBuf.reset(pCurBuf);
742 else if (curDiff < 0)
744 pMinBuf.reset(pCurBuf);
746 minQuality = curQuality;
751 SetLastResult(E_SUCCESS);
755 // should not come here.
756 SetLastResult(E_SYSTEM);
758 return pMinBuf.release();
761 Tizen::Base::ByteBuffer*
762 _ImageImpl::EncodeToBufferQualityN(const Tizen::Base::ByteBuffer &srcBuf,
763 const Tizen::Graphics::Dimension& dim,
764 MediaPixelFormat pixelFormat, ImageFormat imgFormat, int quality)
766 ByteBuffer* pBuf = null;
768 pBuf = _ImageEncoder::EncodeN(imgFormat, srcBuf.GetPointer(), srcBuf.GetLimit(),
769 dim.width, dim.height, pixelFormat, quality);
770 SysTryReturn(NID_MEDIA, pBuf != null, pBuf, GetLastResult(),
771 "[%s] enc.EncodeN. ", GetErrorMessage(GetLastResult()));
777 _ImageImpl::GetImageInfo(const Tizen::Base::String& path, ImageFormat &imgFormat,
778 Tizen::Graphics::Dimension &dim)
780 return _ImageDecoder::GetImageInfo(path, imgFormat, dim.width, dim.height);