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);
83 RequestId reqId = (RequestId)(pValue->ToInt());
85 pFactory->Remove(reqId);
88 __pUrlReqIDList->RemoveAll(true);
93 _ImageImpl::GetInstance(Image* pImage)
97 return pImage->__pImageImpl;
104 _ImageImpl::GetInstance(const Image* pImage)
108 return pImage->__pImageImpl;
115 _ImageImpl::Construct(void)
121 _ImageImpl::DecodeToBitmapN(const Tizen::Base::String& srcImagePath, Tizen::Graphics::BitmapPixelFormat pixelFormat)
123 std::unique_ptr<ByteBuffer> pBuf;
126 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
127 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
128 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
130 pBmp = DecodeToBitmapN(*pBuf.get(), pixelFormat);
135 _ImageImpl::DecodeToBitmapN(const Tizen::Base::ByteBuffer& srcImageBuf, Tizen::Graphics::BitmapPixelFormat pixelFormat)
137 result r = E_SUCCESS;
138 std::unique_ptr<ByteBuffer> pBuf;
139 std::unique_ptr<Bitmap> pBmp;
144 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat));
145 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
147 pBuf.reset(dec.DecodeN());
148 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
149 "[%s] Propagated", GetErrorMessage(GetLastResult()));
151 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
153 r = dec.GetDimension(outDim.width, outDim.height);
154 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
156 pBmp.reset(new (std::nothrow) Bitmap);
157 SysTryReturn(NID_MEDIA, pBmp != null, null, E_OUT_OF_MEMORY,
158 "[%s] new Bitmap", GetErrorMessage(GetLastResult()));
159 r = pBmp->Construct(*pBuf.get(), outDim, pixelFormat, BUFFER_SCALING_AUTO);
160 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
162 // Set transparency in case of rgb565 format
163 if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
165 short rgb565Chroma = 0;
166 Boolean transparency(false);
171 Color *pMaskingColor = null;
173 r = dec.GetValue(L"transparency", transparency);
174 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
175 if (transparency.ToBool() == true)
177 r = dec.GetValue(L"chromaKey", chromaKey);
178 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
180 rgb565Chroma = chromaKey.ToShort();
181 red = (rgb565Chroma & 0xf800) >> 8;
182 red = red | (red >> 5);
183 green = (rgb565Chroma & 0x07e0) >> 3;
184 green = green | (green >> 6);
185 blue = (rgb565Chroma & 0x001f) << 3;
186 blue = blue | (blue >> 5);
188 pMaskingColor = new Color(red, green, blue);
189 SysTryReturn(NID_MEDIA, pMaskingColor != null, pBmp.release(), E_SUCCESS,
190 "[%s] Could not apply masking color.", GetErrorMessage(r));
191 r = pBmp->SetMaskingColor(pMaskingColor);
192 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS,
193 "[%s] Could not set masking color.", GetErrorMessage(r));
197 SetLastResult(E_SUCCESS);
198 return pBmp.release();
202 _ImageImpl::DecodeToBitmapN(const Tizen::Base::String& srcImagePath, Tizen::Graphics::BitmapPixelFormat pixelFormat, const Tizen::Graphics::Dimension &destDim,
203 Tizen::Graphics::BufferScaling bufferScaling)
205 std::unique_ptr<ByteBuffer> pBuf;
208 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
209 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
210 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
212 pBmp = DecodeToBitmapN(*pBuf.get(), pixelFormat, destDim, bufferScaling);
217 _ImageImpl::DecodeToBitmapN(const Tizen::Base::ByteBuffer& srcImageBuf, Tizen::Graphics::BitmapPixelFormat pixelFormat, const Tizen::Graphics::Dimension &destDim,
218 Tizen::Graphics::BufferScaling bufferScaling)
220 result r = E_SUCCESS;
221 std::unique_ptr<ByteBuffer> pBuf;
222 std::unique_ptr<Bitmap> pBmp;
227 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat));
228 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
230 // Reset decoder output demension
231 dec.SetOutputDimension(destDim.width, destDim.height, true);
233 pBuf.reset(dec.DecodeN());
234 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
235 "[%s] Propagated", GetErrorMessage(GetLastResult()));
237 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
239 r = dec.GetDimension(outDim.width, outDim.height);
240 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
242 pBmp.reset(new (std::nothrow) Bitmap);
243 SysTryReturn(NID_MEDIA, pBmp != null, null, E_OUT_OF_MEMORY,
244 "[%s] new Bitmap", GetErrorMessage(GetLastResult()));
245 r = pBmp->Construct(*pBuf.get(), outDim, pixelFormat, bufferScaling);
246 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
248 // Set transparency in case of rgb565 format
249 if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
251 short rgb565Chroma = 0;
252 Boolean transparency(false);
257 Color *pMaskingColor = null;
259 r = dec.GetValue(L"transparency", transparency);
260 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
261 if (transparency.ToBool() == true)
263 r = dec.GetValue(L"chromaKey", chromaKey);
264 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
266 rgb565Chroma = chromaKey.ToShort();
267 red = (rgb565Chroma & 0xf800) >> 8;
268 red = red | (red >> 5);
269 green = (rgb565Chroma & 0x07e0) >> 3;
270 green = green | (green >> 6);
271 blue = (rgb565Chroma & 0x001f) << 3;
272 blue = blue | (blue >> 5);
274 pMaskingColor = new Color(red, green, blue);
275 SysTryReturn(NID_MEDIA, pMaskingColor != null, pBmp.release(), E_SUCCESS,
276 "[%s] Could not apply masking color.", GetErrorMessage(r));
277 r = pBmp->SetMaskingColor(pMaskingColor);
278 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS,
279 "[%s] Could not set masking color.", GetErrorMessage(r));
283 SetLastResult(E_SUCCESS);
284 return pBmp.release();
288 _ImageImpl::DecodeToBitmapN(const Tizen::Base::ByteBuffer& srcImageBuf, Tizen::Graphics::BitmapPixelFormat pixelFormat,
289 const Tizen::Graphics::FloatDimension &destDim)
291 result r = E_SUCCESS;
292 std::unique_ptr<ByteBuffer> pBuf;
293 std::unique_ptr<Bitmap> pBmp;
294 Dimension orgDim, tmpDim;
295 FloatDimension outDim;
300 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat));
301 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
303 r = dec.GetDimension(orgDim.width, orgDim.height);
304 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
306 // Reset decoder output demension
307 dec.SetOutputDimension(_CoordinateSystemUtils::ConvertToInteger(destDim.width),
308 _CoordinateSystemUtils::ConvertToInteger(destDim.height),
311 pBuf.reset(dec.DecodeN());
312 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
313 "[%s] Propagated", GetErrorMessage(GetLastResult()));
315 r = dec.GetDimension(tmpDim.width, tmpDim.height);
316 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
318 r = _ImageUtil::GetResizedDimension(orgDim.width, orgDim.height, destDim.width, destDim.height, outDim.width, outDim.height);
319 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
321 pBmp.reset(new (std::nothrow) Bitmap);
322 SysTryReturn(NID_MEDIA, pBmp.get() != null, null, E_OUT_OF_MEMORY,
323 "[%s] new Bitmap", GetErrorMessage(GetLastResult()));
325 pBmp.reset(_BitmapImpl::GetNonScaledBitmapN(*pBuf.get(), tmpDim, pixelFormat, destDim));
327 // Set transparency in case of rgb565 format
328 if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
330 short rgb565Chroma = 0;
331 Boolean transparency(false);
336 Color *pMaskingColor = null;
338 r = dec.GetValue(L"transparency", transparency);
339 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
340 if (transparency.ToBool() == true)
342 r = dec.GetValue(L"chromaKey", chromaKey);
343 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS, "[%s] Propagated.", GetErrorMessage(r));
345 rgb565Chroma = chromaKey.ToShort();
346 red = (rgb565Chroma & 0xf800) >> 8;
347 red = red | (red >> 5);
348 green = (rgb565Chroma & 0x07e0) >> 3;
349 green = green | (green >> 6);
350 blue = (rgb565Chroma & 0x001f) << 3;
351 blue = blue | (blue >> 5);
353 pMaskingColor = new Color(red, green, blue);
354 SysTryReturn(NID_MEDIA, pMaskingColor != null, pBmp.release(), E_SUCCESS,
355 "[%s] Could not apply masking color.", GetErrorMessage(r));
356 r = pBmp->SetMaskingColor(pMaskingColor);
357 SysTryReturn(NID_MEDIA, r == E_SUCCESS, pBmp.release(), E_SUCCESS,
358 "[%s] Could not set masking color.", GetErrorMessage(r));
362 SetLastResult(E_SUCCESS);
363 return pBmp.release();
367 _ImageImpl::DecodeToBitmapN(const Tizen::Base::String& srcImagePath, Tizen::Graphics::BitmapPixelFormat pixelFormat,
368 const Tizen::Graphics::FloatDimension &destDim)
370 std::unique_ptr<ByteBuffer> pBuf;
373 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
374 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
375 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
377 pBmp = DecodeToBitmapN(*pBuf.get(), pixelFormat, destDim);
381 Tizen::Base::ByteBuffer*
382 _ImageImpl::DecodeToBufferN(const Tizen::Base::String& srcImagePath,
383 Tizen::Graphics::Dimension &restDim,
384 const Tizen::Graphics::Dimension &dstDim,
385 Tizen::Graphics::BitmapPixelFormat pixelFormat,
386 ImageFormat imgFormat, bool keepAspectRatio)
388 std::unique_ptr<ByteBuffer> pBuf;
389 ByteBuffer* pRetBuf = null;
391 //SysTryCatch(NID_MEDIA, IS_VALID_DIMENSION(dstDim), , E_OUT_OF_RANGE,
392 //"[E_OUT_OF_RANGE] dest dimension:%d,%d", dstDim.width, dstDim.height);
394 pBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
395 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
396 "[%s] FileToBufferN %S", GetErrorMessage(GetLastResult()), srcImagePath.GetPointer());
398 pRetBuf = DecodeToBufferN(*pBuf.get(), restDim, dstDim, pixelFormat, imgFormat, keepAspectRatio);
402 Tizen::Base::ByteBuffer*
403 _ImageImpl::DecodeToBufferN(const Tizen::Base::ByteBuffer &srcImageBuf,
404 Tizen::Graphics::Dimension &retDim,
405 const Tizen::Graphics::Dimension &dstDim,
406 Tizen::Graphics::BitmapPixelFormat pixelFormat,
407 ImageFormat imgFormat, bool keepAspectRatio)
409 result r = E_SUCCESS;
410 std::unique_ptr<ByteBuffer> pBuf;
413 //SysTryCatch(NID_MEDIA, IS_VALID_BITMAP_PIXEL(pixelFormat), , E_INVALID_ARG,
414 //"[E_INVALID_ARG] pixelFormat:%d", pixelFormat);
416 r = dec.Construct(srcImageBuf, _ImageUtilImpl::ToMediaPixelFormat(pixelFormat), imgFormat);
417 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
419 // Reset decoder output demension
420 dec.SetOutputDimension(dstDim.width, dstDim.height, keepAspectRatio);
422 pBuf.reset(dec.DecodeN());
424 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
426 r = dec.GetDimension(retDim.width, retDim.height);
427 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
429 SetLastResult(E_SUCCESS);
430 return pBuf.release();
433 Tizen::Base::ByteBuffer*
434 _ImageImpl::DecodeToBufferN(const Tizen::Base::String& srcImagePath,
435 Tizen::Graphics::BitmapPixelFormat pixelFormat,
436 int& imageWidth, int& imageHeight, bool keepAspectRatio)
438 ByteBuffer *pBuf = null;
441 pBuf = DecodeToBufferN(srcImagePath, dim, Dimension(0, 0), pixelFormat, IMG_FORMAT_NONE, keepAspectRatio);
442 imageWidth = dim.width;
443 imageHeight = dim.height;
448 Tizen::Base::ByteBuffer*
449 _ImageImpl::DecodeN(const Tizen::Base::String& srcImagePath,
450 Tizen::Graphics::BitmapPixelFormat pixelFormat,
451 int destWidth, int destHeight, bool keepAspectRatio)
455 return DecodeToBufferN(srcImagePath, dim, Dimension(destWidth, destHeight), pixelFormat, IMG_FORMAT_NONE, keepAspectRatio);
459 _ImageImpl::DecodeUrl(const Tizen::Base::Utility::Uri& srcImageUrl,
460 Tizen::Graphics::BitmapPixelFormat colorFormat,
461 int destWidth, int destHeight, RequestId& reqId,
462 const IImageDecodeUrlEventListener& listener, long timeout)
464 result r = E_SUCCESS;
466 _ImageUriDataFactory *pFactory = null;
468 SysTryCatch(NID_MEDIA, (colorFormat > Tizen::Graphics::BITMAP_PIXEL_FORMAT_MIN)
469 && colorFormat < Tizen::Graphics::BITMAP_PIXEL_FORMAT_MAX, , E_INVALID_ARG,
470 "[E_INVALID_ARG] Wrong color format.");
472 SysTryCatch(NID_MEDIA, destWidth > 0 && destHeight > 0, , E_OUT_OF_RANGE,
473 "[E_OUT_OF_RANGE] The designated width and height SHOUL be greater than 0.");
475 SysTryCatch(NID_MEDIA, timeout == _TIMEOUT_INFINITE || timeout > 0 ,
476 r = E_OUT_OF_RANGE, E_OUT_OF_RANGE,
477 "[E_OUT_OF_RANGE] The designated timeout SHOUL be greater than 0");
479 pFactory = _ImageUriDataFactory::GetInstance();
480 SysTryCatch(NID_MEDIA, pFactory != null, r = GetLastResult(), r,
481 "[%s] Failed to GetInstance().", GetErrorMessage(r));
483 r = pFactory->DecodeUrl(srcImageUrl, colorFormat, destWidth,destHeight, reqId, listener, timeout);
484 SysTryCatch(NID_MEDIA, r == E_SUCCESS , , r,"[%s] Propagated.", GetErrorMessage(r));
486 if (__pUrlReqIDList.get() == null)
488 __pUrlReqIDList.reset(new (std::nothrow)Collection::LinkedList());
489 SysTryCatch(NID_MEDIA, __pUrlReqIDList.get() != null, r = E_OUT_OF_MEMORY, r,
490 "[E_OUT_OF_MEMORY] Propagated. Failed to allocate a LinkedList.", GetErrorMessage(r));
492 __pUrlReqIDList->Add(new (std::nothrow) Integer(reqId));
501 _ImageImpl::EncodeToBufferN(const Bitmap& srcBmp, ImageFormat dstFormat)
503 std::unique_ptr<ByteBuffer> pBuf;
507 // ClearLastResult();
509 Tizen::Graphics::Bitmap& tmpBmp = const_cast<Tizen::Graphics::Bitmap&>(srcBmp);
512 tmpBmp.Lock(bmpInfo);
514 dim.SetSize(bmpInfo.width, bmpInfo.height);
516 // TODO: handle case that pitch != width * bpp/8
517 SysTryReturn(NID_MEDIA, bmpInfo.pitch == bmpInfo.width*bmpInfo.bitsPerPixel/8, null, E_SYSTEM,
518 "[E_SYSTEM] pitch=%d bpp=%d", bmpInfo.pitch, bmpInfo.bitsPerPixel);
520 pBuf.reset(_ImageEncoder::EncodeN(dstFormat, (const byte*)bmpInfo.pPixels, bmpInfo.pitch * bmpInfo.height,
521 dim.width, dim.height,
522 _ImageUtilImpl::ToMediaPixelFormat(srcBmp.GetPixelColorFormat()),
523 _DEFAULT_ENCODE_QUALITY));
524 SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(), "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
526 return pBuf.release();
530 _ImageImpl::EncodeToFile(const Bitmap& srcBmp, ImageFormat dstFormat,
531 const String& dstPath, bool overwrite)
533 result r = E_SUCCESS;
534 std::unique_ptr<ByteBuffer> pBuf;
536 pBuf.reset(EncodeToBufferN(srcBmp, dstFormat));
537 SysTryReturn(NID_MEDIA, pBuf.get() != null, GetLastResult(), GetLastResult(),
538 "[%s] Propagated.", GetErrorMessage(GetLastResult()));
540 r = _MediaUtil::BufferToFile(*pBuf.get(), dstPath, overwrite);
541 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
547 Tizen::Base::ByteBuffer*
548 _ImageImpl::CompressJpegN(const Tizen::Base::ByteBuffer& srcImageBuf, int limitSize)
550 result r = E_SUCCESS;
551 std::unique_ptr<ByteBuffer> pDecBuf;
552 std::unique_ptr<ByteBuffer> pEncBuf;
555 volatile int limit = limitSize;
556 MediaPixelFormat pixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888;
558 // TODO : use yuv pixel format
560 r = dec.Construct(srcImageBuf, pixelFormat);
561 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Decoder construct failed.", GetErrorMessage(r));
563 pDecBuf.reset(dec.DecodeN());
565 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
566 SysTryReturn(NID_MEDIA, pDecBuf.get() != null, null, E_SYSTEM, "[E_SYSTEM] Propagated.");
568 r = dec.GetDimension(srcDim.width, srcDim.height);
569 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ", GetErrorMessage(r));
571 for (int i = 0; i < _MAX_ENCODE_RESIZE_LOOP; i++)
574 ByteBuffer *pTmpBuf = null;
576 pEncBuf.reset(EncodeToBufferLimitN(*pDecBuf.get(), srcDim, pixelFormat, IMG_FORMAT_JPG, limit));
578 if (pEncBuf.get() != null)
583 // halve and make even number
584 dstDim.width = srcDim.width >> 2;
585 dstDim.height = srcDim.height >> 2;
587 dstDim.width = dstDim.width << 1;
588 dstDim.height = dstDim.height << 1;
590 SysTryReturn(NID_MEDIA, srcDim != dstDim && dstDim.width > 0 && dstDim.height > 0, null, E_SYSTEM,
591 "[E_SYSTEM] Resize failed:src:%dx%d dst:%dx%d, %d %d, %d",
592 srcDim.width, srcDim.height, dstDim.width, dstDim.height, i, _SCALE_DOWN_RATIO,
595 pTmpBuf = _ImageUtilImpl::ResizeN(*pDecBuf.get(), srcDim, pixelFormat, dstDim);
596 SysTryReturn(NID_MEDIA, pTmpBuf != null, null, GetLastResult(),
597 "[%s] ResizeN: %dx%d->%dx%d", GetErrorMessage(GetLastResult()),
598 srcDim.width, srcDim.height, dstDim.width, dstDim.height);
601 pDecBuf.reset(pTmpBuf);
603 SysTryReturn(NID_MEDIA, pEncBuf.get() != null, null, E_SYSTEM, "[E_SYSTEM] Compress failed");
604 SetLastResult(E_SUCCESS);
605 return pEncBuf.release();
609 _ImageImpl::CompressJpeg(const Tizen::Base::String& srcImagePath,
610 const Tizen::Base::String& dstImagePath, int limitSize)
613 result r = E_SUCCESS;
614 std::unique_ptr<ByteBuffer> pSrcBuf;
615 std::unique_ptr<ByteBuffer> pEncBuf;
617 pSrcBuf.reset(_MediaUtil::FileToBufferN(srcImagePath));
618 SysTryReturn(NID_MEDIA, pSrcBuf.get() != null, GetLastResult(), GetLastResult(),
619 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
621 // SysTryCatch(NID_MEDIA, pSrcBuf->GetCapacity() < MAX_IMGFILE_SIZE, r = E_OVERFLOW, E_OVERFLOW,
622 // "[E_OUT_OF_RANGE] Input file size is smaller than limitSize.");
624 SysTryReturn(NID_MEDIA, pSrcBuf.get()->GetCapacity() > limitSize, E_OUT_OF_RANGE, E_OUT_OF_RANGE,
625 "[E_OUT_OF_RANGE] Input file size is smaller than limitSize.");
627 pEncBuf.reset(CompressJpegN(*pSrcBuf, limitSize));
628 SysTryReturn(NID_MEDIA, pEncBuf != null, GetLastResult(), GetLastResult(),
629 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
631 if (File::IsFileExist(dstImagePath))
633 File::Remove(dstImagePath);
636 r = file.Construct(dstImagePath, "wb", true);
637 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
638 r = file.Write(*pEncBuf);
639 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated. ", GetErrorMessage(r));
644 Tizen::Base::ByteBuffer*
645 _ImageImpl::ConvertToBufferN(const Tizen::Base::String& srcImagePath, ImageFormat destImageFormat)
647 std::unique_ptr<Bitmap> pBmp;
648 ByteBuffer* pBuf = null;
650 pBmp.reset(DecodeToBitmapN(srcImagePath, BITMAP_PIXEL_FORMAT_ARGB8888, Dimension(0, 0),
651 BUFFER_SCALING_NONE));
652 SysTryReturn(NID_MEDIA, pBmp.get(), null, GetLastResult(),
653 "[%s] Propagated. ", GetErrorMessage(GetLastResult()));
655 pBuf = EncodeToBufferN(*pBmp.get(), destImageFormat);
656 SysTryReturn(NID_MEDIA, pBuf != null, null, GetLastResult(),
657 "[%s] Propagated.", GetErrorMessage(GetLastResult()));
659 SetLastResult(E_SUCCESS);
663 Tizen::Base::ByteBuffer*
664 _ImageImpl::EncodeToBufferLimitN(const Tizen::Base::ByteBuffer &srcBuf,
665 const Tizen::Graphics::Dimension& dim,
666 MediaPixelFormat pixelFormat, ImageFormat imgFormat, int limit)
668 int minQuality = _MIN_ENCODE_QUALITY;
669 int maxQuality = _MAX_ENCODE_QUALITY;
674 std::unique_ptr<ByteBuffer> pMaxBuf;
675 std::unique_ptr<ByteBuffer> pMinBuf;
677 pMaxBuf.reset(EncodeToBufferQualityN(srcBuf, dim, pixelFormat, imgFormat, maxQuality));
678 SysTryReturn(NID_MEDIA, pMaxBuf.get() != null, pMinBuf.get(), E_SYSTEM, "[E_SYSTEM] maxBuf is null");
679 maxDiff = pMaxBuf->GetLimit() - limit;
680 SysLog(NID_MEDIA, "maxDiff:%d buf:%d limit:%d q:%d",
681 maxDiff, pMaxBuf->GetLimit(), limit, maxQuality);
684 SetLastResult(E_SUCCESS);
685 return pMaxBuf.release();
687 pMinBuf.reset(EncodeToBufferQualityN(srcBuf, dim, pixelFormat, imgFormat, minQuality));
688 SysTryReturn(NID_MEDIA, pMinBuf.get() != null, pMinBuf.release(), E_SYSTEM, "[E_SYSTEM] minBuf is null");
689 minDiff = pMinBuf->GetLimit() - limit;
690 SysLog(NID_MEDIA, "minDiff:%d buf:%d limit:%d q:%d",
691 minDiff, pMinBuf->GetLimit(), limit, minQuality);
694 SetLastResult(E_OVERFLOW);
699 SetLastResult(E_SUCCESS);
700 return pMinBuf.release();
703 for (int i = 0; i < _MAX_ENCODE_LOOP; i++)
705 int prevQuality = curQuality;
707 ByteBuffer *pCurBuf = null;
709 curQuality = (minQuality + maxQuality) / 2;
710 if (prevQuality == curQuality)
714 pCurBuf = EncodeToBufferQualityN(srcBuf, dim, pixelFormat, imgFormat, curQuality);
715 if (pCurBuf == null && pMinBuf.get() != null)
719 SysTryReturn(NID_MEDIA, pCurBuf != null, pMinBuf.release(), E_SYSTEM,
720 "[E_SYSTEM] curBuf is null : %d %d %d", dim.width, dim.height, curQuality);
721 curDiff = pCurBuf->GetLimit() - limit;
722 SysLog(NID_MEDIA, "curDiff:%d buf:%d limit:%d q:%d",
723 curDiff, pCurBuf->GetLimit(), limit, curQuality);
726 SetLastResult(E_SUCCESS);
729 else if (curDiff > 0)
732 maxQuality = curQuality;
733 pMaxBuf.reset(pCurBuf);
735 else if (curDiff < 0)
737 pMinBuf.reset(pCurBuf);
739 minQuality = curQuality;
744 SetLastResult(E_SUCCESS);
748 // should not come here.
749 SetLastResult(E_SYSTEM);
751 return pMinBuf.release();
754 Tizen::Base::ByteBuffer*
755 _ImageImpl::EncodeToBufferQualityN(const Tizen::Base::ByteBuffer &srcBuf,
756 const Tizen::Graphics::Dimension& dim,
757 MediaPixelFormat pixelFormat, ImageFormat imgFormat, int quality)
759 ByteBuffer* pBuf = null;
761 pBuf = _ImageEncoder::EncodeN(imgFormat, srcBuf.GetPointer(), srcBuf.GetLimit(),
762 dim.width, dim.height, pixelFormat, quality);
763 SysTryReturn(NID_MEDIA, pBuf != null, pBuf, GetLastResult(),
764 "[%s] enc.EncodeN. ", GetErrorMessage(GetLastResult()));
770 _ImageImpl::GetImageInfo(const Tizen::Base::String& path, ImageFormat &imgFormat,
771 Tizen::Graphics::Dimension &dim)
773 return _ImageDecoder::GetImageInfo(path, imgFormat, dim.width, dim.height);