merge with master
[framework/osp/image-core.git] / src / FMedia_ImageDecoder.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file   FMedia_ImageDecoder.cpp
20  * @brief  This is the implementation file for the _ImageDecoder.
21  */
22
23 #include <unique_ptr.h>
24 #include <FBaseColArrayListT.h>
25 #include <FBaseSysLog.h>
26 #include <FBaseInteger.h>
27 #include <FIoFile.h>
28 #include <FMediaImageTypes.h>
29 #include "FMedia_MediaUtil.h"
30 #include "FMedia_Ffmpeg.h"
31 #include "FMedia_ColorConverter.h"
32 #include "FMedia_ImageDecoder.h"
33 #include "FMedia_PngDecoder.h"
34 #include "FMedia_JpegTurboDecoder.h"
35 #include "FMedia_GifDecoder.h"
36 #include "FMedia_BmpDecoder.h"
37 #include "FMedia_TiffDecoder.h"
38 #include "FMedia_WbmpDecoder.h"
39 #include "FMedia_ImageUtil.h"
40 #include "FMedia_ExifUtil.h"
41
42 using namespace Tizen::Base;
43 using namespace Tizen::Io;
44
45 namespace Tizen { namespace Media
46 {
47
48 #define IS_VALID_DEC_PIXEL(x)                              \
49         ((x == MEDIA_PIXEL_FORMAT_RGB565LE) || (x == MEDIA_PIXEL_FORMAT_BGRA8888) \
50          || (x == MEDIA_PIXEL_FORMAT_RGBA8888))
51
52 typedef struct {
53         ImageRotationType rotateType;
54         ImageFlipType flipType;
55         bool dimensionSwitch;
56 } _ImageExifInfo;
57
58 static const _ImageExifInfo _IMAGE_ROTATE_FLIP_MAP[] = {
59         { IMAGE_ROTATION_0,   IMAGE_FLIP_NONE,       false }, /* NONE         */
60         { IMAGE_ROTATION_0,   IMAGE_FLIP_NONE,       false }, /* TOP_LEFT     */
61         { IMAGE_ROTATION_0,   IMAGE_FLIP_VERTICAL,   false }, /* TOP_RIGHT    */
62         { IMAGE_ROTATION_180, IMAGE_FLIP_NONE,       false }, /* BOTTOM_RIGHT */
63         { IMAGE_ROTATION_0,   IMAGE_FLIP_HORIZONTAL, false }, /* BOTTOM_LEFT  */
64         { IMAGE_ROTATION_90,  IMAGE_FLIP_VERTICAL,   true  }, /* LEFT_TOP     */
65         { IMAGE_ROTATION_90,  IMAGE_FLIP_NONE,       true  }, /* RIGHT_TOP    */
66         { IMAGE_ROTATION_90,  IMAGE_FLIP_HORIZONTAL, true  }, /* RIGHT_BOTTOM */
67         { IMAGE_ROTATION_270, IMAGE_FLIP_NONE,       true  }  /* LEFT_BOTTOM  */
68 };
69
70 Tizen::Base::ByteBuffer*
71 _ImageDecoder::DecodeToBufferN(const Tizen::Base::String& filePath,
72                                 MediaPixelFormat pixelFormat, int &width, int &height, bool autoRotate)
73 {
74         result r = E_SUCCESS;
75
76         std::unique_ptr<ByteBuffer> pBuf;
77         _ImageDecoder dec;
78
79         SysTryReturn(NID_MEDIA, filePath.GetLength() > 0 && filePath.GetLength() <= PATH_MAX, null, E_INVALID_ARG,
80                                 "[E_INVALID_ARG] Given filePath length is zero or exceeds system limitations Length = %d.",filePath.GetLength());
81         SysTryReturn(NID_MEDIA, File::IsFileExist(filePath), null, E_FILE_NOT_FOUND,
82                                 "[E_FILE_NOT_FOUND] filePath:%ls", filePath.GetPointer());
83
84         r = dec.Construct(filePath, pixelFormat, IMG_FORMAT_NONE, autoRotate);
85         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
86                 "[%s] Decoder construct failed.", GetErrorMessage(r));
87
88         // Reset decoder output demension
89         pBuf.reset(dec.DecodeN());
90         r = GetLastResult();
91         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
92
93         r = dec.GetDimension(width, height);
94         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
95
96         SetLastResult(E_SUCCESS);
97         return pBuf.release();
98 }
99
100 Tizen::Base::ByteBuffer*
101 _ImageDecoder::DecodeRegionToBufferN(const Tizen::Base::String& filePath,
102                                 MediaPixelFormat pixelFormat, int x, int y, int width, int height)
103 {
104         result r = E_SUCCESS;
105         _ImageDecoder dec;
106         int imgWidth = 0;
107         int imgHeight = 0;
108         std::unique_ptr<ByteBuffer> pBuf;
109
110         r = dec.Construct(filePath, pixelFormat);
111         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] dec.Construct", GetErrorMessage(r));
112         r = dec.GetDimension(imgWidth, imgHeight);
113         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] dec.GetDimension", GetErrorMessage(r));
114
115         SysTryReturn(NID_MEDIA, imgWidth >= (x + width) && imgHeight >= (y + height),
116                 null, E_INVALID_ARG,
117                 "[E_INVALID_ARG] Bottom left point of region (%d, %d) should lie within dimensions of image (%d x %d)",
118                 x, y, width, height, imgWidth, imgHeight);
119
120         r = dec.SetDecodingRegion(x, y, width, height);
121         SysTryReturn(NID_MEDIA, r == E_SUCCESS || r == E_UNSUPPORTED_OPERATION, null, r,
122                 "[%s] dec.SetDecodingRegion failed for region (%d, %d) (%d x %d)",
123                 GetErrorMessage(r), x, y, width, height);
124
125         if (r == E_SUCCESS)
126         {
127                 pBuf.reset(dec.DecodeN());
128                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
129         }
130         else // E_UNSUPPORTED_OPERATION
131         {
132                 // crop image
133                 ByteBuffer *pTmpBuf = null;
134
135                 pBuf.reset(dec.DecodeN());
136                 r = GetLastResult();
137                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
138                 pTmpBuf = _ImageUtil::CropN(*pBuf.get(), pixelFormat, imgWidth, imgHeight, x, y, width, height);
139                 SysTryReturn(NID_MEDIA, pTmpBuf != null, null, GetLastResult(),
140                         "[%s] Crop failed for buffer(%x), pixelFormat(%d), image size(%dx%d), region(%d,%d), (%dx%d)",
141                         GetErrorMessage(GetLastResult()), pBuf->GetPointer(), pixelFormat, imgWidth,
142                         imgHeight, x, y, width, height);
143                 pBuf.reset(pTmpBuf);
144         }
145
146         SetLastResult(E_SUCCESS);
147         return pBuf.release();
148 }
149
150 Tizen::Base::ByteBuffer*
151 _ImageDecoder::DecodeRegionToBufferN(const Tizen::Base::ByteBuffer& srcBuf, MediaPixelFormat pixelFormat,
152                                                                          int x, int y, int width, int height)
153 {
154         result r = E_SUCCESS;
155         _ImageDecoder dec;
156         int imgWidth = 0;
157         int imgHeight = 0;
158         std::unique_ptr<ByteBuffer> pBuf;
159
160         r = dec.Construct(srcBuf, pixelFormat);
161         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] dec.Construct", GetErrorMessage(r));
162         r = dec.GetDimension(imgWidth, imgHeight);
163         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] dec.GetDimension", GetErrorMessage(r));
164
165         SysTryReturn(NID_MEDIA, imgWidth >= (x + width) && imgHeight >= (y + height),
166                 null, E_INVALID_ARG,
167                 "[E_INVALID_ARG] Bottom left point of region (%d, %d) should lie within dimensions of image (%d x %d)",
168                 x, y, width, height, imgWidth, imgHeight);
169
170         r = dec.SetDecodingRegion(x, y, width, height);
171         SysTryReturn(NID_MEDIA, r == E_SUCCESS || r == E_UNSUPPORTED_OPERATION, null, r,
172                 "[%s] dec.SetDecodingRegion failed for region (%d, %d) (%d x %d)",
173                 GetErrorMessage(r), x, y, width, height);
174
175         if (r == E_SUCCESS)
176         {
177                 pBuf.reset(dec.DecodeN());
178                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
179         }
180         else // E_UNSUPPORTED_OPERATION
181         {
182                 // crop image
183                 ByteBuffer *pTmpBuf = null;
184                 pBuf.reset(dec.DecodeN());
185                 r = GetLastResult();
186                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
187                 pTmpBuf = _ImageUtil::CropN(*pBuf.get(), pixelFormat, imgWidth, imgHeight, x, y, width, height);
188                 SysTryReturn(NID_MEDIA, pTmpBuf != null, null, GetLastResult(),
189                         "[%s] Crop failed for buffer(%x), pixelFormat(%d), image size(%dx%d), region(%d,%d), (%dx%d)",
190                         GetErrorMessage(GetLastResult()), pBuf->GetPointer(), pixelFormat, imgWidth,
191                         imgHeight, x, y, width, height);
192                 pBuf.reset(pTmpBuf);
193         }
194
195         SetLastResult(E_SUCCESS);
196         return pBuf.release();
197 }
198
199 result
200 _ImageDecoder::GetImageInfo(const Tizen::Base::String& filePath, ImageFormat &imgFormat,
201                                                         int &width, int &height)
202 {
203         result r = E_SUCCESS;
204         _ImageDecoder dec;
205
206         r = dec.Construct(filePath);
207         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] dec.Construct", GetErrorMessage(r));
208         imgFormat = dec.GetImageFormat();
209         r = dec.GetDimension(width, height);
210         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] dec.GetDimension", GetErrorMessage(r));
211
212 CATCH:
213         return r;
214 }
215
216 _ImageDecoder::_ImageDecoder(void)
217 {
218         __pDec = null;
219         __imgFormat = IMG_FORMAT_NONE;
220         __pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
221         __orgDim.width = 0;
222         __orgDim.height = 0;
223         __outDim.width = 0;
224         __outDim.height = 0;
225         __pSrcBuf = null;
226         __autoRotate = false;
227         __orientationInfo = 0;
228 }
229
230 _ImageDecoder::~_ImageDecoder(void)
231 {
232 }
233
234 _IImageDecoder*
235 _ImageDecoder::CreateDecoderN(ImageFormat srcFormat)
236 {
237         result r = E_SUCCESS;
238         std::unique_ptr<_IImageDecoder> pDec;
239
240         switch (srcFormat)
241         {
242         case IMG_FORMAT_JPG:
243                 pDec.reset( new (std::nothrow) _JpegTurboDecoder());
244                 break;
245
246         case IMG_FORMAT_PNG:
247                 pDec.reset( new (std::nothrow) _PngDecoder());
248                 break;
249
250         case IMG_FORMAT_GIF:
251                 pDec.reset( new (std::nothrow) _GifDecoder());
252                 break;
253
254         case IMG_FORMAT_BMP:
255                 pDec.reset( new (std::nothrow) _BmpDecoder());
256                 break;
257
258         case IMG_FORMAT_TIFF:
259                 pDec.reset( new (std::nothrow) _TiffDecoder());
260                 break;
261
262         case IMG_FORMAT_WBMP:
263                 pDec.reset( new (std::nothrow) _WbmpDecoder());
264                 break;
265
266         default:
267                 r = E_UNSUPPORTED_FORMAT;
268                 break;
269         }
270
271         //__imageFormat = srcFormat;
272         if (pDec.get() == null && r == E_SUCCESS)
273         {
274                 r = E_OUT_OF_MEMORY;
275         }
276         SetLastResult(r);
277         return pDec.release();
278 }
279
280
281 result
282 _ImageDecoder::Construct(const Tizen::Base::String& srcPath,
283                                                  MediaPixelFormat pixelFormat,
284                                                  ImageFormat imgFormat, bool autoRotate)
285 {
286         result r = E_SUCCESS;
287         std::unique_ptr<ByteBuffer> pBuf;
288
289         // File to Buffer
290         pBuf.reset(_MediaUtil::FileToBufferN(srcPath));
291         SysTryReturn(NID_MEDIA, pBuf.get() != null, GetLastResult(), GetLastResult(),
292                 "[%s] Propagated.", GetErrorMessage(GetLastResult()));
293
294         r = Construct(*pBuf.get(), pixelFormat, imgFormat);
295         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r));
296
297         if (autoRotate == true)
298         {
299                 __autoRotate = true;
300                 _ExifUtil imgExif;
301                 imgExif.Construct(pBuf->GetPointer(), pBuf->GetCapacity());
302                 imgExif.GetValue(EXIF_TAG_IMAGE_ORIENTATION, __orientationInfo);
303                 // imgExif.GetValue() will return "r = E_OBJ_NOT_FOUND" if it could not be found exif infomation.
304                 // However, the result should be decided by result of construct in this function.
305                 SetLastResult(E_SUCCESS);
306         }
307         return r;
308 }
309
310 result
311 _ImageDecoder::Construct(const Tizen::Base::ByteBuffer& srcBuf,
312                                                  MediaPixelFormat pixelFormat,
313                                                  ImageFormat imgFormat)
314 {
315         result r = E_SUCCESS;
316
317         SysTryReturnResult(NID_MEDIA, __pDec.get() == null, E_INVALID_STATE, "Already constructed");
318         SysTryCatch(NID_MEDIA,
319                 (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)|| (pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888) ||
320                 (pixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888), r = E_INVALID_ARG, E_INVALID_ARG,
321                 "[E_INVALID_ARG] pixelFormat:%d", pixelFormat);
322
323         SysTryCatch(NID_MEDIA, &srcBuf != null && srcBuf.GetCapacity() > 0,
324                 r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
325                 "[E_OBJ_NOT_FOUND] buf:0x%x, %d", &srcBuf, &srcBuf ? srcBuf.GetCapacity() : 0);
326
327         __pixelFormat = pixelFormat;
328
329         __pSrcBuf.reset(new (std::nothrow) ByteBuffer());
330         SysTryCatch(NID_MEDIA, __pSrcBuf.get() != null, , r, "[%s] Propagated.", GetErrorMessage(r));
331         r = __pSrcBuf->Construct(srcBuf);
332         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated.", GetErrorMessage(r));
333
334         __imgFormat = _ImageUtil::GetImageFormat(srcBuf);
335
336         SysTryCatch(NID_MEDIA,
337                 (__imgFormat > IMG_FORMAT_NONE) && (__imgFormat <= IMG_FORMAT_WBMP),
338                 r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT, "[%s] Propagated.",
339                 GetErrorMessage(GetLastResult()));
340
341         // Create decoder
342         __pDec.reset(CreateDecoderN(__imgFormat));
343         SysTryCatch(NID_MEDIA, __pDec.get() != null, r = GetLastResult(), r,
344                 "[%s] Could not create decoder for image format %d.",
345                 GetErrorMessage(r), __imgFormat);
346
347         // Decoder construction
348         r = __pDec->Construct((byte*) __pSrcBuf->GetPointer(), __pSrcBuf->GetCapacity(), pixelFormat);
349         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated.", GetErrorMessage(r));
350
351         // Get original dimension
352         r = __pDec->GetDimension(__orgDim.width, __orgDim.height);
353         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated.", GetErrorMessage(r));
354         __outDim.width = __orgDim.width;
355         __outDim.height = __orgDim.height;
356
357 CATCH:
358         return r;
359 }
360
361 byte*
362 _ImageDecoder::DecodeN(int& outLength, ImageScalingMethod scalingMethod)
363 {
364         result r = E_SUCCESS;
365         int rawLength = 0;
366         std::unique_ptr<byte[]> pOutBuf;
367         std::unique_ptr<byte[]> pRawBuf;
368         std::unique_ptr<byte[]> pDstBuf;
369         SysTryReturn(NID_MEDIA, __pDec.get() != null, null, E_INVALID_STATE, "Not yet constructed");
370
371         // Decode
372         pRawBuf.reset(__pDec->DecodeN(rawLength));
373         SysTryReturn(NID_MEDIA, pRawBuf.get() != null, null, GetLastResult(),
374                 "[%s] buffer is null (%x), buffer length is %d.",
375                 GetErrorMessage(GetLastResult()),pRawBuf.get(), rawLength);
376
377         // Get working dimension
378         if ((__outDim.width == 0) && (__outDim.height == 0))
379         {
380                 __outDim.width = __orgDim.width;
381                 __outDim.height = __orgDim.height;
382         }
383
384         // if no need to convert.
385         if ((__pDec->GetPixelFormat() == __pixelFormat)
386                 && (__orgDim.width == __outDim.width)
387                 && (__orgDim.height == __outDim.height))
388         {
389                 pOutBuf.swap(pRawBuf);
390                 outLength = rawLength;
391         }
392         else
393         {
394                 _ColorConverter cvt;
395
396                 // Converter construction
397                 r = cvt.Construct(__pDec->GetPixelFormat(), __orgDim.width, __orgDim.height,
398                                                   __pixelFormat, __outDim.width, __outDim.height, scalingMethod);
399                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
400
401                 // Convert to output format
402                 pOutBuf.reset(cvt.ConvertN(pRawBuf.get(), rawLength, outLength));
403                 r = GetLastResult();
404                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
405         }
406
407         if (__autoRotate == true)
408         {
409                 int dstWidth = 0;
410                 int dstHeight = 0;
411
412                 if (__orientationInfo == EXIF_ORIENTATION_TOP_LEFT || __orientationInfo == 0)
413                 {
414                         SetLastResult(E_SUCCESS);
415                         return pOutBuf.release();
416                 }
417
418                 if (__orientationInfo > EXIF_ORIENTATION_LEFT_BOTTOM || __orientationInfo  < EXIF_ORIENTATION_TOP_LEFT)
419                 {
420                         SetLastResult(E_SUCCESS);
421                         return pOutBuf.release();
422                 }
423
424                 pDstBuf.reset(new (std::nothrow) byte[outLength]);
425                 SysTryReturn(NID_MEDIA, pDstBuf.get() != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
426
427                 ImageRotationType rotateType = _IMAGE_ROTATE_FLIP_MAP[__orientationInfo].rotateType;
428                 ImageFlipType flipType = _IMAGE_ROTATE_FLIP_MAP[__orientationInfo].flipType;
429
430                 pDstBuf.reset(_ImageUtil::RotateN(pOutBuf.get(), __pixelFormat, __outDim.width, __outDim.height, rotateType, dstWidth, dstHeight));
431                 r = GetLastResult();
432                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] _ImageUtil:Resize", GetErrorMessage(r));
433
434                 __outDim.width = dstWidth;
435                 __outDim.height = dstHeight;
436
437                 pOutBuf.swap(pDstBuf);
438                 if (flipType != IMAGE_FLIP_NONE)
439                 {
440                         pDstBuf.reset(_ImageUtil::FlipN(pOutBuf.get(), __pixelFormat, __outDim.width, __outDim.height, flipType));
441                         r = GetLastResult();
442                         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] _ImageUtil:Flip", GetErrorMessage(r));
443
444                         pOutBuf.swap(pDstBuf);
445                 }
446         }
447         SetLastResult(E_SUCCESS);
448         return pOutBuf.release();
449 }
450
451 // TODO: Change return type to ByteBuffer*
452
453 Tizen::Base::ByteBuffer*
454 _ImageDecoder::DecodeN(void)
455 {
456         result r = E_SUCCESS;
457         int outLength = 0;
458         std::unique_ptr<byte[]> pTmpBuf;
459         std::unique_ptr<ByteBuffer> pByteBuf(new (std::nothrow) ByteBuffer());
460
461         SysTryReturn(NID_MEDIA, __pDec.get() != null, null, E_INVALID_STATE, "Not yet constructed");
462
463         pTmpBuf.reset(DecodeN(outLength));
464         SysTryReturn(NID_MEDIA, pTmpBuf.get() != null, null, GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
465
466         r = pByteBuf->Construct(outLength);
467         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
468                 "[%s] Propagated. Could not construct Bytebuffer of size %d",
469                 GetErrorMessage(r), outLength);
470
471         r = pByteBuf->SetArray((byte*) pTmpBuf.get(), 0, outLength);
472         SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
473         pByteBuf->Flip();
474
475         SetLastResult(E_SUCCESS);
476         return pByteBuf.release();
477 }
478
479 ImageFormat
480 _ImageDecoder::GetImageFormat(void) const
481 {
482         return __imgFormat;
483 }
484
485 result
486 _ImageDecoder::SetDecodingRegion(int x, int y, int width, int height)
487 {
488         SysTryReturnResult(NID_MEDIA, __pDec.get() != null, E_INVALID_STATE, "Not yet constructed");
489         result r = E_SUCCESS;
490
491         r = __pDec->SetDecodingRegion(x, y, width, height);
492         if (r == E_SUCCESS)
493         {
494                 __outDim.width = width;
495                 __outDim.height = height;
496                 __orgDim.width = width;
497                 __orgDim.height = height;
498         }
499         return r;
500 }
501
502 result
503 _ImageDecoder::GetDimension(int &width, int &height) const
504 {
505         SysTryReturnResult(NID_MEDIA, __pDec.get() != null, E_INVALID_STATE, "Not yet constructed");
506
507         width = __outDim.width;
508         height = __outDim.height;
509
510         return E_SUCCESS;
511 }
512
513 MediaPixelFormat
514 _ImageDecoder::GetPixelFormat(void) const
515 {
516         return __pixelFormat;
517 }
518
519 result
520 _ImageDecoder::SetOutputDimension(int width, int height, bool keepAspectRatio)
521 {
522         if (width == 0 || height == 0 || __orgDim.width == 0 ||
523                 __orgDim.height == 0 || keepAspectRatio == false)
524         {
525                 __outDim.width = width;
526                 __outDim.height = height;
527         }
528         else    // keep aspect ratio
529         {
530                 double xRatio = Integer(width).ToDouble() / Integer(__orgDim.width).ToDouble();
531                 double yRatio = Integer(height).ToDouble() / Integer(__orgDim.height).ToDouble();
532                 if (xRatio >= 1.0 || yRatio >= 1.0)
533                 {
534                         __outDim.width = __orgDim.width;
535                         __outDim.height = __orgDim.height;
536                 }
537                 else if (xRatio < yRatio)
538                 {
539                         __outDim.width = (int)(__orgDim.width * yRatio);
540                         __outDim.height = height;
541                 }
542                 else
543                 {
544                         __outDim.width = width;
545                         __outDim.height = (int)(__orgDim.height*xRatio);
546                 }
547         }
548         return E_SUCCESS;
549 }
550
551 }} // Tizen::Media