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_ImageUtil.cpp
20 * @brief This is the implementation file for the _ImageUtil.
23 #include <unique_ptr.h>
24 #include <FBaseSysLog.h>
25 #include <FBaseInteger.h>
26 #include <FBaseFloat.h>
27 #include <FBaseDouble.h>
28 #include <image_util.h>
29 #include <mmf/mm_error.h>
30 #include <mmf/mm_util_imgp.h>
31 #include "FMedia_ImageUtil.h"
32 #include "FMedia_Ffmpeg.h"
33 #include <arpa/inet.h>
34 #include "FMedia_MediaUtil.h"
35 #include "FMedia_SlpUtil.h"
37 using namespace Tizen::Base;
38 using namespace Tizen::Io;
42 namespace Tizen { namespace Media
45 #define IS_VALID_PIXEL(x) \
46 ((x == MEDIA_PIXEL_FORMAT_YUV420P) || (x == MEDIA_PIXEL_FORMAT_NV12) \
47 || (x == MEDIA_PIXEL_FORMAT_YUYV422) || (x == MEDIA_PIXEL_FORMAT_RGB565LE) \
48 || (x == MEDIA_PIXEL_FORMAT_BGRA8888) || (x == MEDIA_PIXEL_FORMAT_RGBA8888) \
49 || (x == MEDIA_PIXEL_FORMAT_BGR888) || (x == MEDIA_PIXEL_FORMAT_RGB888) \
50 || (x == MEDIA_PIXEL_FORMAT_NV21) || ( x == MEDIA_PIXEL_FORMAT_YUV444P))
52 #define IS_VALID_BUF(buf, format, w, h) \
53 (_ImageUtil::GetBufferSize(format, w, h) <= buf.GetCapacity())
57 MediaPixelFormat mediaPixelFmt;
62 static const _PixelFormatMap _PIXEL_FORMAT_MAP[] =
64 { MEDIA_PIXEL_FORMAT_RGB565LE, PIX_FMT_RGB565LE, 2 },
65 { MEDIA_PIXEL_FORMAT_BGRA8888, PIX_FMT_BGRA, 4 },
66 { MEDIA_PIXEL_FORMAT_RGBA8888, PIX_FMT_RGBA, 4 },
67 { MEDIA_PIXEL_FORMAT_RGB565BE, PIX_FMT_RGB565BE, 2 },
68 { MEDIA_PIXEL_FORMAT_RGB888, PIX_FMT_RGB24, 3 },
69 { MEDIA_PIXEL_FORMAT_BGR888, PIX_FMT_BGR24, 3 },
70 { MEDIA_PIXEL_FORMAT_YUV420P, PIX_FMT_YUV420P, 1.5 },
71 { MEDIA_PIXEL_FORMAT_YUV444P, PIX_FMT_YUV444P, 3 },
72 { MEDIA_PIXEL_FORMAT_YUYV422, PIX_FMT_YUYV422, 2 },
73 { MEDIA_PIXEL_FORMAT_UYVY422, PIX_FMT_UYVY422, 2 },
74 { MEDIA_PIXEL_FORMAT_NV12, PIX_FMT_NV12, 1.5 },
75 { MEDIA_PIXEL_FORMAT_NV12_TILE, PIX_FMT_NV12, 1.5 },
76 { MEDIA_PIXEL_FORMAT_NV21, PIX_FMT_NV21, 1.5 }
79 static const int _BPP_RGB565 = 2;
80 static const int _BPP_RGB888 = 3;
81 static const int _BPP_ARGB8888 = 4;
82 static const int _BPP_YUV444 = 3;
83 static const float _BPP_YUV420 = 1.5;
84 static const float _BPP_NV12 = 1.5;
87 * Input is assumed to be 8888
88 * pDataIn => Input ARGB/BGRA/RGBA 8888 Buffer
89 * pDataOut => Output buffer, allocated by caller
90 * inWidth => Input Width
91 * inHeight => Input Height
92 * outWidth => Output Width
93 * outHeight => Output Height
96 _ImageUtil::Resize8888(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
106 byte* pOutput = pDataOut;
107 byte* pOut = pDataOut;
108 const byte* pIn = null;
110 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
111 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
112 "[E_OUT_OF_MEMORY] Could not allocate memory.");
114 /* Calculate X Scale factor */
115 scaleX = inWidth * 256 / outWidth;
117 /* Calculate Y Scale factor, aspect ratio is not maintained */
118 scaleY = inHeight * 256 / outHeight;
120 for (j = 0; j < outWidth; j++)
122 /* Get input index based on column scale factor */
124 /* To get more optimization, this is calculated once and
125 * is placed in a LUT and used for indexing
127 pColLUT [j] = ((j * scaleX) >> 8) * _BPP_ARGB8888;
132 for (i = 0; i < outHeight; i++)
134 /* Get input routWidth index based on routWidth scale factor */
135 iRow = (i * scaleY >> 8) * inWidth * _BPP_ARGB8888;
137 /* Loop could be unrolled for more optimization */
138 for (j = 0; j < (outWidth); j++)
140 /* Get input index based on column scale factor */
141 iIndex = iRow + pColLUT [j];
143 pIn = pDataIn + iIndex;
155 * Input is assumed to be RGB888
156 * pDataIn => Input RGB888 Buffer
157 * pDataOut => Output buffer, allocated by caller
158 * inWidth => Input Width
159 * inHeight => Input Height
160 * outWidth => Output Width
161 * outHeight => Output Height
164 _ImageUtil::ResizeRGB888(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
174 byte* pOutput = pDataOut;
175 byte* pOut = pDataOut;
176 const byte* pIn = null;
178 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
179 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
180 "[E_OUT_OF_MEMORY] Could not allocate memory.");
182 /* Calculate X Scale factor */
183 scaleX = inWidth * 256 / outWidth;
185 /* Calculate Y Scale factor, aspect ratio is not maintained */
186 scaleY = inHeight * 256 / outHeight;
188 for (j = 0; j < outWidth; j++)
190 /* Get input index based on column scale factor */
192 /* To get more optimization, this is calculated once and
193 * is placed in a LUT and used for indexing
195 pColLUT[j] = ((j * scaleX) >> 8) * _BPP_RGB888;
200 for (i = 0; i < outHeight; i++)
202 /* Get input routWidth index based on routWidth scale factor */
203 iRow = (i * scaleY >> 8) * inWidth * _BPP_RGB888;
205 /* Loop could be unrolled for more optimization */
206 for (j = 0; j < (outWidth); j++)
208 /* Get input index based on column scale factor */
209 iIndex = iRow + pColLUT [j];
210 pIn = pDataIn + iIndex;
222 * Input is assumed to be RGB565
223 * pDataIn => Input RGB565 Buffer
224 * pDataOut => Output RGB565 Buffer (memory is assumed to be already allocated)
225 * inWidth => Input Width
226 * inHeight => Input Height
227 * outWidth => Output Width
228 * outHeight => Output Height
231 _ImageUtil::ResizeRGB565(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
241 byte* pOutput = pDataOut;
242 byte* pOut = pDataOut;
243 const byte* pIn = null;
245 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
246 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
247 "[E_OUT_OF_MEMORY] Could not allocate memory.");
249 /* Calculate X Scale factor */
250 scaleX = inWidth * 256 / outWidth;
252 /* Calculate Y Scale factor, aspect ratio is not maintained */
253 scaleY = inHeight * 256 / outHeight;
255 for (j = 0; j < outWidth; j++)
257 /* Get input index based on column scale factor */
259 /* To get more optimization, this is calculated once and
260 * is placed in a LUT and used for indexing
262 pColLUT [j] = ((j * scaleX) >> 8) * _BPP_RGB565;
267 for (i = 0; i < outHeight; i++)
269 /* Get input row index based on row scale factor */
270 iRow = (i * scaleY >> 8) * inWidth * _BPP_RGB565;
272 /* Loop could be unrolled for more optimization */
273 for (j = 0; j < (outWidth); j++)
275 /* Get input index based on column scale factor */
276 iIndex = iRow + pColLUT [j];
278 pIn = pDataIn + iIndex;
288 * Input is assumed to be YUV444
289 * pDataIn => Input YUV444 Buffer
290 * pDataOut => Output buffer, allocated by caller
291 * inWidth => Input Width
292 * inHeight => Input Height
293 * outWidth => Output Width
294 * outHeight => Output Height
297 _ImageUtil::ResizeYUV444(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
307 int ipixelcount = inWidth * inHeight;
308 int opixelcount = outWidth * outHeight;
309 byte* pOutput = pDataOut;
313 const byte* pInY = null;
314 const byte* pInU = null;
315 const byte* pInV = null;
317 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
318 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
319 "[E_OUT_OF_MEMORY] Could not allocate memory.");
321 /* Calculate X Scale factor */
322 scaleX = inWidth * 256 / outWidth;
324 /* Calculate Y Scale factor, aspect ratio is not maintained */
325 scaleY = inHeight * 256 / outHeight;
327 for (j = 0; j < outWidth; j++)
329 /* Get input index based on column scale factor */
331 /* To get more optimization, this is calculated once and
332 * is placed in a LUT and used for indexing
334 pColLUT[j] = ((j * scaleX) >> 8);
338 pOutU = pOutY + opixelcount;
339 pOutV = pOutU + opixelcount;
342 pInU = pInY + ipixelcount;
343 pInV = pInU + ipixelcount;
345 for (i = 0; i < outHeight; i++)
347 /* Get input row index based on row scale factor */
348 iRow = (i * scaleY >> 8) * inWidth;
350 /* Loop could be unrolled for more optimization */
351 for (j = 0; j < outWidth; j++)
353 /* Get input index based on column scale factor */
354 iIndex = iRow + pColLUT [j];
356 *(pOutY++) = *(pInY + iIndex);
357 *(pOutU++) = *(pInU + iIndex);
358 *(pOutV++) = *(pInV + iIndex);
366 * Input is assumed to be YUYV422
367 * pDataIn => Input YUYV422 Buffer
368 * pDataOut => Output buffer, allocated by caller
369 * inWidth => Input Width
370 * inHeight => Input Height
371 * outWidth => Output Width
372 * outHeight => Output Height
375 _ImageUtil::ResizeYUYV422(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
378 return ResizeRGB565(pDataIn, pDataOut, inWidth, inHeight, outWidth, outHeight);
382 * Input is assumed to be YUV420P
383 * pDataIn => Input YUV420P Buffer
384 * pDataOut => Output buffer, allocated by caller
385 * inWidth => Input Width
386 * inHeight => Input Height
387 * outWidth => Output Width
388 * outHeight => Output Height
391 _ImageUtil::ResizeYUV420P(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
401 int ipixelcount = inWidth * inHeight;
402 int opixelcount = outWidth * outHeight;
403 byte* pOutput = pDataOut;
408 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
409 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
410 "[E_OUT_OF_MEMORY] Could not allocate memory.");
412 /* Calculate X Scale factor */
413 scaleX = inWidth * 256 / outWidth;
415 /* Calculate Y Scale factor, aspect ratio is not maintained */
416 scaleY = inHeight * 256 / outHeight;
418 for (j = 0; j < outWidth; j++)
420 /* Get input index based on column scale factor */
422 /* To get more optimization, this is calculated once and
423 * is placed in a LUT and used for indexing
425 pColLUT[j] = ((j * scaleX) >> 8);
430 for (i = 0; i < outHeight; i++)
432 /* Get input row index based on row scale factor */
433 iRow = (i * scaleY >> 8) * inWidth;
435 /* Loop could be unrolled for more optimization */
436 for (j = 0; j < (outWidth); j++)
438 /* Get input index based on column scale factor */
439 iIndex = iRow + pColLUT[j];
441 *pOutY++ = pDataIn[iIndex];
445 pOutU = pOutput + opixelcount;
446 pOutV = pOutU + (opixelcount/4);
448 for (i = 0; i < (outHeight + 1) / 2; i++)
450 /* Get input row index based on row scale factor */
451 iRow = (i * scaleY >> 8) * inWidth/2;
453 /* Loop could be unrolled for more optimization */
454 for (j = 0; j < (outWidth)/2; j++)
456 /* Get input index based on column scale factor */
457 iIndex = iRow + pColLUT[j];
459 *pOutU++ = pDataIn[iIndex + ipixelcount];
460 *pOutV++ = pDataIn[iIndex + ipixelcount + (ipixelcount/4)];
468 * Input is assumed to be NV12
469 * pDataIn => Input NV12 Buffer
470 * pDataOut => Output buffer, allocated by caller
471 * inWidth => Input Width
472 * inHeight => Input Height
473 * outWidth => Output Width
474 * outHeight => Output Height
477 _ImageUtil::ResizeNV12(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
487 int ipixelcount = inWidth * inHeight;
488 int opixelcount = outWidth * outHeight;
489 byte* pOutput = pDataOut;
493 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
494 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
495 "[E_OUT_OF_MEMORY] Could not allocate memory.");
497 /* Calculate X Scale factor */
498 scaleX = inWidth * 256 / outWidth;
500 /* Calculate Y Scale factor, aspect ratio is not maintained */
501 scaleY = inHeight * 256 / outHeight;
503 for (j = 0; j < outWidth; j++)
505 /* Get input index based on column scale factor */
507 /* To get more optimization, this is calculated once and
508 * is placed in a LUT and used for indexing
510 pColLUT[j] = ((j * scaleX) >> 8);
515 for (i = 0; i < outHeight; i++)
517 /* Get input row index based on row scale factor */
518 iRow = (i * scaleY >> 8) * inWidth;
520 /* Loop could be unrolled for more optimization */
521 for (j = 0; j < (outWidth); j++)
523 /* Get input index based on column scale factor */
524 iIndex = iRow + pColLUT[j];
526 *pOutY++ = pDataIn[iIndex];
530 pOutUV = pOutput + opixelcount;
532 for (i = 0; i < (outHeight + 1) / 2; i++)
534 /* Get input row index based on row scale factor */
535 iRow = (i * scaleY >> 8) * inWidth/2;
537 /* Loop could be unrolled for more optimization */
538 for (j = 0; j < (outWidth)/2; j++)
540 /* Get input index based on column scale factor */
541 iIndex = iRow + pColLUT[j];
543 *pOutUV++ = pDataIn[iIndex + ipixelcount];
544 *pOutUV++ = pDataIn[iIndex + ipixelcount + 1];
552 _ImageUtil::ResizeBuffer(const byte* pInBuf, MediaPixelFormat pixelFormat,
553 int srcWidth, int srcHeight, byte* pOutBuf, int dstWidth, int dstHeight)
555 result r = E_SUCCESS;
560 case MEDIA_PIXEL_FORMAT_RGBA8888:
561 case MEDIA_PIXEL_FORMAT_BGRA8888:
563 r = Resize8888(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
567 case MEDIA_PIXEL_FORMAT_RGB888:
569 r = ResizeRGB888(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
573 case MEDIA_PIXEL_FORMAT_RGB565LE:
575 r = ResizeRGB565(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
579 case MEDIA_PIXEL_FORMAT_YUV444P:
581 r = ResizeYUV444(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
585 case MEDIA_PIXEL_FORMAT_YUYV422:
587 r = ResizeYUYV422(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
591 case MEDIA_PIXEL_FORMAT_YUV420P:
593 r = ResizeYUV420P(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
597 case MEDIA_PIXEL_FORMAT_NV12:
599 r = ResizeNV12(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
604 r = E_UNSUPPORTED_FORMAT;
611 _ImageUtil::RotateBuffer(const byte* srcBuf, MediaPixelFormat pixelFormat,
612 int width, int height, byte* dstBuf, int& outWidth, int& outHeight,
613 ImageRotationType rotate)
615 result r = E_SUCCESS;
618 mm_util_img_format colorFormat = MM_UTIL_IMG_FMT_NUM;
619 mm_util_img_rotate_type rotation = MM_UTIL_ROTATE_NUM;
621 image_util_colorspace_e colorFormat = IMAGE_UTIL_COLORSPACE_RGB565;
622 image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
625 SysTryCatch(NID_MEDIA, width > 0 && height > 0, r = E_INVALID_ARG, E_INVALID_ARG,
626 "[E_INVALID_ARG] Invalid dimension: Should be greater than zero: (%d x %d)",
629 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
630 "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
632 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, width, height),
633 r = E_INVALID_ARG, E_INVALID_ARG,
634 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", width, height);
636 if (rotate == IMAGE_ROTATION_0)
638 int length = GetBufferSize(pixelFormat, width, height);
639 memcpy(dstBuf, srcBuf, length);
643 // Set output dimensions;
644 if ((rotate == IMAGE_ROTATION_90) || (rotate == IMAGE_ROTATION_270))
655 if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
659 case IMAGE_ROTATION_90:
663 unsigned short* pSrcBuf = (unsigned short *)srcBuf;
664 unsigned short* pDstBuf = (unsigned short *)dstBuf;
665 unsigned short* pTmpOutCol = null;
667 // Copying from all source rows to destination columns.
668 for (rowCount = 0; rowCount < height; rowCount++)
670 // pTmpOutCol points to the top of the output column being filled.
671 pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
673 for (colCount = 0; colCount < width; colCount++)
675 *pTmpOutCol = *pSrcBuf++;
676 pTmpOutCol += outWidth;
682 case IMAGE_ROTATION_180:
685 unsigned short* pSrcBuf = (unsigned short *)srcBuf;
686 unsigned short* pDstBuf = (unsigned short *)dstBuf;
688 // pDstBuf points to the bottom right corner of the output image.
689 pDstBuf += (outWidth * outHeight) - 1;
691 for (pixCount = (width * height); pixCount > 0; pixCount--)
693 *pDstBuf = *pSrcBuf++;
699 case IMAGE_ROTATION_270:
703 unsigned short* pSrcBuf = (unsigned short *)srcBuf;
704 unsigned short* pDstBuf = (unsigned short *)dstBuf;
705 unsigned short* pTmpOutCol = null;
707 // Copying all source rows to destination columns.
708 for (rowCount = 0; rowCount < height; rowCount++)
710 // pTmpOutCol points to the bottom of the column being filled.
711 pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
713 for (colCount = 0; colCount < width; colCount++)
715 *pTmpOutCol = *pSrcBuf++;
716 pTmpOutCol -= outWidth;
726 else if (pixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888 || pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888)
730 case IMAGE_ROTATION_90:
734 unsigned int* pSrcBuf = (unsigned int *)srcBuf;
735 unsigned int* pDstBuf = (unsigned int *)dstBuf;
736 unsigned int* pTmpOutCol = null;
738 // Copying from all source rows to destination columns.
739 for (rowCount = 0; rowCount < height; rowCount++)
741 // pTmpOutCol points to the top of the output column being filled.
742 pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
744 for (colCount = 0; colCount < width; colCount++)
746 *pTmpOutCol = *pSrcBuf++;
747 pTmpOutCol += outWidth;
753 case IMAGE_ROTATION_180:
756 unsigned int* pSrcBuf = (unsigned int *)srcBuf;
757 unsigned int* pDstBuf = (unsigned int *)dstBuf;
759 // pDstBuf points to the bottom right corner of the output image.
760 pDstBuf += (outWidth * outHeight) - 1;
762 for (pixCount = (width * height); pixCount > 0; pixCount--)
764 *pDstBuf = *pSrcBuf++;
770 case IMAGE_ROTATION_270:
774 unsigned int* pSrcBuf = (unsigned int *)srcBuf;
775 unsigned int* pDstBuf = (unsigned int *)dstBuf;
776 unsigned int* pTmpOutCol = null;
778 // Copying all source rows to destination columns.
779 for (rowCount = 0; rowCount < height; rowCount++)
781 // pTmpOutCol points to the bottom of the column being filled.
782 pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
784 for (colCount = 0; colCount < width; colCount++)
786 *pTmpOutCol = *pSrcBuf++;
787 pTmpOutCol -= outWidth;
801 colorFormat = _SlpUtil::ToMmUtilImgFormat(pixelFormat);
802 rotation = _SlpUtil::ToMmUtilRotateType(rotate);
804 ret = mm_util_rotate_image((unsigned char*)srcBuf, width, height, colorFormat,
805 (unsigned char*)dstBuf, (unsigned int *)&outWidth, (unsigned int *)&outHeight, rotation);
807 SysTryCatch(NID_MEDIA, ret == 0, r = E_SYSTEM, E_SYSTEM,
808 "mm_util_rotate_image: %0x", ret);
812 colorFormat = _SlpUtil::ToColorspace(pixelFormat);
813 rotation = _SlpUtil::ToRotation(rotate);
815 ret = image_util_transform(dstBuf, &outWidth, &outHeight, rotation,
816 srcBuf, width, height, colorFormat);
818 SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
819 "[E_SYSTEM] util_transform failed: %0x", ret);
830 _ImageUtil::FlipBuffer(const byte* srcBuf, MediaPixelFormat pixelFormat,
831 int width, int height,
832 byte* dstBuf, ImageFlipType flip)
834 result r = E_SUCCESS;
837 mm_util_img_format colorFormat = MM_UTIL_IMG_FMT_NUM;
838 mm_util_img_rotate_type rotation = MM_UTIL_ROTATE_NUM;
840 unsigned int outWidth = 0;
841 unsigned int outHeight = 0;
843 image_util_colorspace_e colorFormat = IMAGE_UTIL_COLORSPACE_RGB565;
844 image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
849 SysTryCatch(NID_MEDIA, width > 0 && height > 0, r = E_INVALID_ARG, E_INVALID_ARG,
850 "[E_INVALID_ARG] Invalid dimension: Should be greater than zero: (%d x %d)",
853 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
854 "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
856 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, width, height),
857 r = E_INVALID_ARG, E_INVALID_ARG,
858 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", width, height);
860 if (flip == IMAGE_FLIP_NONE)
862 int length = GetBufferSize(pixelFormat, width, height);
863 memcpy(dstBuf, srcBuf, length);
867 // Set output dimensions;
871 if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
873 if (flip == IMAGE_FLIP_HORIZONTAL)
877 unsigned short* pSrcBuf = (unsigned short *)srcBuf;
878 unsigned short* pDstBuf = (unsigned short *)dstBuf;
879 // pTmpOutRow points to last column of first row of destination.
880 unsigned short* pTmpOutRow = pDstBuf + width - 1;
882 for (rowCount = 0; rowCount < height; rowCount++)
884 for (colCount = 0; colCount < width; colCount++)
886 *pTmpOutRow-- = *pSrcBuf++; // copy source row in reverse to destination.
888 pTmpOutRow += (2 * outWidth);
894 unsigned short* pSrcBuf = (unsigned short *)srcBuf;
895 unsigned short* pDstBuf = (unsigned short *)dstBuf;
896 // pTmpOutRow points to the start of last row in destination buffer.
897 unsigned short* pTmpOutRow = pDstBuf + (width * (height - 1));
899 for (rowCount = 0; rowCount < height; rowCount++)
901 // copy one row worth of data.
902 memcpy(pTmpOutRow, pSrcBuf, sizeof(unsigned short) * width);
903 pTmpOutRow -= width; // go to one higher row.
904 pSrcBuf += width; // go to next row.
912 colorFormat = _SlpUtil::ToMmUtilImgFormat(pixelFormat);
913 rotation = _SlpUtil::ToMmUtilRotateType(flip);
915 ret = mm_util_rotate_image((unsigned char*)srcBuf, width, height, colorFormat,
916 (unsigned char*)dstBuf, &outWidth, &outHeight, rotation);
918 SysTryCatch(NID_MEDIA, ret == 0, r = E_SYSTEM, E_SYSTEM,
919 "mm_util_rotate_image failed with error code: %0x", ret);
921 colorFormat = _SlpUtil::ToColorspace(pixelFormat);
922 rotation = _SlpUtil::ToRotation(flip);
924 ret = image_util_transform(dstBuf, &outWidth, &outHeight, rotation,
925 srcBuf, width, height, colorFormat);
926 SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
927 "util_transform failed with error code: %0x", ret);
936 _ImageUtil::ConvertPixelFormat(const ByteBuffer& srcBuf,
937 MediaPixelFormat srcFormat, int srcWidth, int srcHeight,
938 ByteBuffer& dstBuf, MediaPixelFormat dstFormat)
940 result r = E_SUCCESS;
944 image_util_colorspace_e srcColor = IMAGE_UTIL_COLORSPACE_RGB565;
945 image_util_colorspace_e dstColor = IMAGE_UTIL_COLORSPACE_RGB565;
947 SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
948 "[E_INVALID_ARG] Invalid dimension: Should be greater than zero. (%d x %d)", srcWidth, srcHeight);
950 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(srcFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
951 "[E_UNSUPPORTED_FORMAT] Unsupported srcPixelFormat:%d", srcFormat);
952 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(dstFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
953 "[E_UNSUPPORTED_FORMAT] Unsupported dstPixelFormat:%d", dstFormat);
955 SysTryCatch(NID_MEDIA, IsValidDimension(srcFormat, srcWidth, srcHeight),
956 r = E_INVALID_ARG, E_INVALID_ARG,
957 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
959 SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, dstFormat, srcWidth, srcHeight),
960 r = E_INVALID_ARG, E_INVALID_ARG,
961 "[E_INVALID_ARG] Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
962 dstBuf.GetLimit(), dstFormat, srcWidth, srcHeight);
964 srcColor = _SlpUtil::ToColorspace(srcFormat);
965 dstColor = _SlpUtil::ToColorspace(dstFormat);
967 ret = image_util_convert_colorspace((unsigned char*) dstBuf.GetPointer(), dstColor,
968 (byte*)srcBuf.GetPointer(), srcWidth, srcHeight, srcColor);
969 SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
970 "[E_SYSTEM] convert_colorspace failed with error code %d", ret);
971 r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(dstFormat, srcWidth, srcHeight));
972 SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
973 "[%s] SetLimit to %d failed for buffer.", GetErrorMessage(r),
974 _ImageUtil::GetBufferSize(dstFormat, srcWidth, srcHeight));
979 int dstWidth = srcWidth;
980 int dstHeight = srcHeight;
981 int width = srcWidth;
983 int srcLength = srcBuf.GetCapacity();
986 std::unique_ptr<byte []> pDstBuf;
987 struct SwsContext* pCvtCtxt = null;
988 // Get ffmpeg format type
989 PixelFormat ffSrcFormat = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(srcFormat);
990 PixelFormat ffDstFormat = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(dstFormat);
992 SysTryReturn(NID_MEDIA, srcWidth > 0 && srcHeight > 0, E_INVALID_ARG, E_INVALID_ARG,
993 "[E_INVALID_ARG] Invalid dimension: Should be greater that zero (%d x %d)", srcWidth, srcHeight);
995 SysTryReturn(NID_MEDIA, ffSrcFormat != PIX_FMT_NONE, E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
996 "[E_UNSUPPORTED_FORMAT] Unsupported srcPixelFormat: %d", srcFormat);
997 SysTryReturn(NID_MEDIA, ffDstFormat != PIX_FMT_NONE, E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
998 "[E_UNSUPPORTED_FORMAT] Unsupported dstPixelFormat: %d", dstFormat);
1000 SysTryReturn(NID_MEDIA, IsValidDimension(srcFormat, srcWidth, srcHeight),
1001 E_INVALID_ARG, E_INVALID_ARG,
1002 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
1004 SysTryReturn(NID_MEDIA, IS_VALID_BUF(srcBuf, srcFormat, srcWidth, srcHeight),
1005 E_INVALID_ARG, E_INVALID_ARG,
1006 "[E_INVALID_ARG] Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
1007 srcBuf.GetLimit(), srcFormat, srcWidth, srcHeight);
1009 SysTryReturn(NID_MEDIA, IsValidDimension(dstFormat, srcWidth, srcHeight),
1010 E_INVALID_ARG, E_INVALID_ARG,
1011 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
1013 SysTryReturn(NID_MEDIA, IS_VALID_BUF(dstBuf, dstFormat, srcWidth, srcHeight),
1014 E_INVALID_ARG, E_INVALID_ARG,
1015 "[E_INVALID_ARG] Invalid dst buffer size (%d) for pixelformat (%d) and size (%d x %d)",
1016 dstBuf.GetLimit(), dstFormat, srcWidth, srcHeight);
1018 avcodec_register_all();
1023 std::unique_ptr<byte []> pSrcBufUPtr;
1024 const byte* pSrcData = null;
1025 byte* pDstData = null;
1031 size = GetBufferSize(srcFormat, srcWidth, srcHeight);
1033 pSrcBufUPtr.reset(new (std::nothrow) byte[size]);
1034 pSrcBuf = pSrcBufUPtr.get();
1035 SysTryReturn(NID_MEDIA, pSrcBuf != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
1036 "[E_OUT_OF_MEMORY] Couldn't allocate buffer");
1037 memset(pSrcBuf, 0, size);
1039 pSrcData = srcBuf.GetPointer();
1040 SysTryReturn(NID_MEDIA, pSrcData != null, GetLastResult(), GetLastResult(),
1041 "[%s] ByteBuffer::GetPointer() returned null", GetErrorMessage(GetLastResult()));
1045 // Create a new buffer with input buffer, padded to increase width to be 8 pixels wide.
1046 for (row = 0; row < srcHeight; row++)
1048 memcpy(pDstData, pSrcData, srcWidth);
1050 pSrcData += srcWidth;
1056 pSrcBuf = (const_cast<byte *>(srcBuf.GetPointer()));
1057 SysTryReturn(NID_MEDIA, pSrcBuf != null, GetLastResult(), GetLastResult(),
1058 "[%s] srcBuf.GetPointer failed", GetErrorMessage(GetLastResult()));
1063 // Create scale context
1064 pCvtCtxt = sws_getContext(srcWidth, srcHeight, ffSrcFormat,
1065 dstWidth, dstHeight, ffDstFormat,
1066 SWS_BICUBIC, NULL, NULL, NULL);
1068 SysTryReturn(NID_MEDIA, pCvtCtxt != null, E_SYSTEM, E_SYSTEM,
1069 "[E_SYSTEM] sws_getContext failed for src size (%d x %d), pix (%d), and dst size (%d x %d), pix (%d)",
1070 srcWidth, srcHeight, ffSrcFormat,
1071 dstWidth, dstHeight, ffDstFormat);
1073 // Calculate src/dest size
1074 size = avpicture_get_size(ffSrcFormat, srcWidth, srcHeight);
1075 SysTryReturn(NID_MEDIA, size <= srcLength, E_INVALID_ARG, E_INVALID_ARG,
1076 "[E_INVALID_ARG] underflow: Required buffer size (%d) < given buffer size (%d), for pix (%d), (%d x %d)",
1077 size, srcLength, srcFormat, srcWidth, srcHeight);
1079 size = avpicture_get_size(ffDstFormat, dstWidth, dstHeight);
1080 SysTryReturn(NID_MEDIA, size >= 0, E_FAILURE, E_FAILURE,
1081 "[E_FAILURE] Not able find size of dest frame for pix (%d), size (%d x %d)");
1083 pDstBuf.reset(new (std::nothrow) byte[size]);
1084 SysTryReturn(NID_MEDIA, pDstBuf.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
1085 "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", size);
1088 memset(&srcFrame, 0, sizeof(srcFrame));
1089 memset(&dstFrame, 0, sizeof(dstFrame));
1091 // Fill source frame
1092 avpicture_fill((AVPicture*)&srcFrame, (byte*)pSrcBuf, ffSrcFormat, srcWidth, srcHeight);
1095 avpicture_fill((AVPicture*)&dstFrame, (byte*)pDstBuf.get(), ffDstFormat, dstWidth, dstHeight);
1098 sws_scale(pCvtCtxt, srcFrame.data, srcFrame.linesize, 0, srcHeight,
1099 dstFrame.data, dstFrame.linesize);
1101 if (width == srcWidth)
1103 r = dstBuf.SetArray(pDstBuf.get(), 0, dstLength);
1104 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
1105 "[%s] Propagated.", GetErrorMessage(r));
1110 // The padding must be removed from output buffer.
1112 std::unique_ptr<byte []> pUnpadded;
1113 byte *pSrcData = null;
1114 byte *pDstData = null;
1117 size = GetBufferSize(srcFormat, srcWidth, srcHeight);
1119 pUnpadded.reset(new (std::nothrow) byte[size]);
1120 SysTryReturn(NID_MEDIA, pUnpadded.get() != null, E_OUT_OF_MEMORY,
1121 E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Couldn't allocate buffer");
1122 memset(pUnpadded.get(), 0, size);
1124 pSrcData = pDstBuf.get();
1126 pDstData = pUnpadded.get();
1128 // Create a new buffer with input buffer, padded to increase width to be 8 pixels wide.
1129 for (row = 0; row < srcHeight; row++)
1131 memcpy(pDstData, pSrcData, srcWidth);
1132 pDstData += srcWidth;
1136 r = dstBuf.SetArray(pUnpadded.get(), 0, size);
1137 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r,
1138 r, "[%s] Propagated.", GetErrorMessage(r));
1142 if (pCvtCtxt != NULL)
1144 sws_freeContext(pCvtCtxt);
1157 _ImageUtil::Resize(const ByteBuffer& srcBuf,
1158 MediaPixelFormat pixelFormat,
1159 int srcWidth, int srcHeight,
1161 int dstWidth, int dstHeight)
1163 result r = E_SUCCESS;
1164 unsigned int outWidth = dstWidth;
1165 unsigned int outHeight = dstHeight;
1166 byte* pDataOut = null;
1168 SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
1169 "Invalid src dimension: Should be greater than zero: (%d x %d)", srcWidth, srcHeight);
1170 SysTryCatch(NID_MEDIA, dstWidth > 0 && dstHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
1171 "Invalid dst dimension: Should be greater than zero: (%d x %d)", dstWidth, dstHeight);
1173 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
1174 "Unsupported pixelFormat: %d", pixelFormat);
1176 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, srcWidth, srcHeight),
1177 r = E_INVALID_ARG, E_INVALID_ARG,
1178 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
1180 SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, srcWidth, srcHeight),
1181 r = E_INVALID_ARG, E_INVALID_ARG,
1182 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
1183 srcBuf.GetLimit(), pixelFormat, srcWidth, srcHeight);
1185 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, dstWidth, dstHeight),
1186 r = E_INVALID_ARG, E_INVALID_ARG,
1187 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", dstWidth, dstHeight);
1189 SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, dstWidth, dstHeight),
1190 r = E_INVALID_ARG, E_INVALID_ARG,
1191 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
1192 dstBuf.GetLimit(), pixelFormat, dstWidth, dstHeight);
1194 pDataOut = const_cast<byte*>(dstBuf.GetPointer());
1196 r = ResizeBuffer(const_cast<byte*>(srcBuf.GetPointer()), pixelFormat,
1197 srcWidth, srcHeight, pDataOut, dstWidth, dstHeight);
1198 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Resize failed.", GetErrorMessage(r));
1200 r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
1201 SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
1202 "[%s] dstBuf.SetLimit to %d failed.", GetErrorMessage(r),
1203 _ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
1210 _ImageUtil::Rotate(const ByteBuffer& srcBuf,
1211 MediaPixelFormat pixelFormat,
1212 int width, int height,
1214 ImageRotationType rotate)
1216 result r = E_SUCCESS;
1219 mm_util_img_format colorFormat = MM_UTIL_IMG_FMT_NUM;
1220 mm_util_img_rotate_type rotation = MM_UTIL_ROTATE_NUM;
1222 unsigned int outWidth = 0;
1223 unsigned int outHeight = 0;
1225 image_util_colorspace_e colorFormat = IMAGE_UTIL_COLORSPACE_RGB565;
1226 image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
1232 SysTryCatch(NID_MEDIA, width > 0 && height > 0, r = E_INVALID_ARG, E_INVALID_ARG,
1233 "[E_INVALID_ARG] Invalid dimension: Should be greater than zero: (%d x %d)",
1236 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
1237 "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
1239 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, width, height),
1240 r = E_INVALID_ARG, E_INVALID_ARG,
1241 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", width, height);
1243 SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, width, height),
1244 r = E_INVALID_ARG, E_INVALID_ARG,
1245 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
1246 srcBuf.GetLimit(), pixelFormat, width, height);
1248 SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, width, height),
1249 r = E_INVALID_ARG, E_INVALID_ARG,
1250 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
1251 dstBuf.GetLimit(), pixelFormat, width, height);
1253 if (rotate == IMAGE_ROTATION_0)
1255 r = dstBuf.SetArray(srcBuf.GetPointer(), 0, srcBuf.GetLimit());
1256 SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
1257 "[%s] dstBuf.SetArray failed. SrcBuffer = %d, SrcBuffer.Limit = %d, dstBuffer.Position = %d, dstBuffer.Capacity = %d.",
1258 GetErrorMessage(r), srcBuf.GetPointer(), srcBuf.GetLimit(), dstBuf.GetPosition(), dstBuf.GetCapacity());
1263 // Set output dimensions;
1264 if ((rotate == IMAGE_ROTATION_90) || (rotate == IMAGE_ROTATION_270))
1275 if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB888)
1279 byte* pSrcBuf = (byte *)srcBuf.GetPointer();
1280 byte* pDstBuf = (byte *)dstBuf.GetPointer();
1281 byte* pTmpOutCol = null;
1285 case IMAGE_ROTATION_90:
1287 // Copying from all source rows to destination columns.
1288 for (rowCount = 0; rowCount < height; rowCount++)
1290 // pTmpOutCol points to the top of the output column being filled.
1291 pTmpOutCol = pDstBuf + outWidth * 3 - 1 - rowCount * 3;
1293 for (colCount = 0; colCount < width / 2; colCount++)
1295 pTmpOutCol = pTmpOutCol - 2;
1296 *pTmpOutCol++ = *pSrcBuf++; // copied R byte
1297 *pTmpOutCol++ = *pSrcBuf++; // copied G byte
1298 *pTmpOutCol = *pSrcBuf++; // copied B byte
1299 pTmpOutCol += outWidth * 3;
1301 pTmpOutCol = pTmpOutCol - 2;
1302 *pTmpOutCol++ = *pSrcBuf++; // copied R byte
1303 *pTmpOutCol++ = *pSrcBuf++; // copied G byte
1304 *pTmpOutCol = *pSrcBuf++; // copied B byte
1305 pTmpOutCol += outWidth * 3;
1310 case IMAGE_ROTATION_180:
1312 // Copying all source rows to destination columns.
1313 for (rowCount = 0; rowCount < height; rowCount++)
1315 // pTmpOutCol points to the bottom of the column being filled.
1316 pTmpOutCol = pDstBuf + ((outWidth * outHeight * 3) - 1) - (rowCount * outWidth * 3);
1318 for (colCount = 0; colCount < width / 2; colCount++)
1320 pTmpOutCol -= 2; // move to R bye of pixel
1321 *pTmpOutCol++ = *pSrcBuf++; // copied R
1322 *pTmpOutCol++ = *pSrcBuf++; // copied G
1323 *pTmpOutCol = *pSrcBuf++; // copied B
1324 pTmpOutCol -= 3; // move to next pixel to get copied
1326 pTmpOutCol -= 2; // move to R bye of pixel
1327 *pTmpOutCol++ = *pSrcBuf++; // copied R
1328 *pTmpOutCol++ = *pSrcBuf++; // copied G
1329 *pTmpOutCol = *pSrcBuf++; // copied B
1330 pTmpOutCol -= 3; // move to next pixel to get copied
1335 case IMAGE_ROTATION_270:
1337 // Copying all source rows to destination columns.
1338 for (rowCount = 0; rowCount < height; rowCount++)
1340 // pTmpOutCol points to the bottom of the column being filled.
1341 pTmpOutCol = pDstBuf + (outWidth * 3 * (outHeight - 1)) + rowCount * 3;
1343 for (colCount = 0; colCount < width / 2; colCount++)
1345 *pTmpOutCol++ = *pSrcBuf++; // copied R
1346 *pTmpOutCol++ = *pSrcBuf++; // copied G
1347 *pTmpOutCol = *pSrcBuf++; // copied B
1348 pTmpOutCol -= 2; // take pointer back to R
1349 pTmpOutCol -= outWidth * 3;
1351 *pTmpOutCol++ = *pSrcBuf++; // copied R
1352 *pTmpOutCol++ = *pSrcBuf++; // copied G
1353 *pTmpOutCol = *pSrcBuf++; // copied B
1354 pTmpOutCol -= 2; // take pointer back to R
1355 pTmpOutCol -= outWidth * 3;
1365 else if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
1369 case IMAGE_ROTATION_90:
1373 unsigned short* pSrcBuf = (unsigned short *)srcBuf.GetPointer();
1374 unsigned short* pDstBuf = (unsigned short *)dstBuf.GetPointer();
1375 unsigned short* pTmpOutCol = null;
1377 // Copying from all source rows to destination columns.
1378 for (rowCount = 0; rowCount < height; rowCount++)
1380 // pTmpOutCol points to the top of the output column being filled.
1381 pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
1383 for (colCount = 0; colCount < width; colCount++)
1385 *pTmpOutCol = *pSrcBuf++;
1386 pTmpOutCol += outWidth;
1392 case IMAGE_ROTATION_180:
1395 unsigned short* pSrcBuf = (unsigned short *)srcBuf.GetPointer();
1396 unsigned short* pDstBuf = (unsigned short *)dstBuf.GetPointer();
1398 // pDstBuf points to the bottom right corner of the output image.
1399 pDstBuf += (outWidth * outHeight) - 1;
1401 for (pixCount = (width * height); pixCount > 0; pixCount--)
1403 *pDstBuf = *pSrcBuf++;
1409 case IMAGE_ROTATION_270:
1413 unsigned short* pSrcBuf = (unsigned short *)srcBuf.GetPointer();
1414 unsigned short* pDstBuf = (unsigned short *)dstBuf.GetPointer();
1415 unsigned short* pTmpOutCol = null;
1417 // Copying all source rows to destination columns.
1418 for (rowCount = 0; rowCount < height; rowCount++)
1420 // pTmpOutCol points to the bottom of the column being filled.
1421 pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
1423 for (colCount = 0; colCount < width; colCount++)
1425 *pTmpOutCol = *pSrcBuf++;
1426 pTmpOutCol -= outWidth;
1436 else if (pixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888 || pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888)
1440 case IMAGE_ROTATION_90:
1444 unsigned int* pSrcBuf = (unsigned int *)srcBuf.GetPointer();
1445 unsigned int* pDstBuf = (unsigned int *)dstBuf.GetPointer();
1446 unsigned int* pTmpOutCol = null;
1448 // Copying from all source rows to destination columns.
1449 for (rowCount = 0; rowCount < height; rowCount++)
1451 // pTmpOutCol points to the top of the output column being filled.
1452 pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
1454 for (colCount = 0; colCount < width; colCount++)
1456 *pTmpOutCol = *pSrcBuf++;
1457 pTmpOutCol += outWidth;
1463 case IMAGE_ROTATION_180:
1466 unsigned int* pSrcBuf = (unsigned int *)srcBuf.GetPointer();
1467 unsigned int* pDstBuf = (unsigned int *)dstBuf.GetPointer();
1469 // pDstBuf points to the bottom right corner of the output image.
1470 pDstBuf += (outWidth * outHeight) - 1;
1472 for (pixCount = (width * height); pixCount > 0; pixCount--)
1474 *pDstBuf = *pSrcBuf++;
1480 case IMAGE_ROTATION_270:
1484 unsigned int* pSrcBuf = (unsigned int *)srcBuf.GetPointer();
1485 unsigned int* pDstBuf = (unsigned int *)dstBuf.GetPointer();
1486 unsigned int* pTmpOutCol = null;
1488 // Copying all source rows to destination columns.
1489 for (rowCount = 0; rowCount < height; rowCount++)
1491 // pTmpOutCol points to the bottom of the column being filled.
1492 pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
1494 for (colCount = 0; colCount < width; colCount++)
1496 *pTmpOutCol = *pSrcBuf++;
1497 pTmpOutCol -= outWidth;
1507 else if (pixelFormat == MEDIA_PIXEL_FORMAT_YUV420P)
1511 byte* pDstY = (byte *)dstBuf.GetPointer();
1512 byte* pDstU = pDstY + outWidth * outHeight;
1513 byte* pDstV = pDstU + (outWidth / 2) * (outHeight / 2);
1515 byte* pSrcY = (byte *) srcBuf.GetPointer();
1516 byte* pSrcU = pSrcY + width * height;
1517 byte* pSrcV = pSrcU + (width /2) * ( height / 2);
1518 byte* pTmpOutColY = null;
1519 byte* pTmpOutColU = null;
1520 byte* pTmpOutColV = null;
1523 case IMAGE_ROTATION_90:
1525 // Copying from all source rows to destination columns of Y plane.
1526 for (rowCount = 0; rowCount < height / 2; rowCount++)
1528 // pTmpOutCol points to the top of the output column being filled.
1529 pTmpOutColU = pDstU + (outWidth / 2) - 1 - rowCount;
1530 pTmpOutColV = pDstV + (outWidth / 2) - 1 - rowCount;
1531 pTmpOutColY = pDstY + outWidth - 1 - rowCount;
1532 for (colCount = 0; colCount < width / 2; colCount++)
1534 *pTmpOutColU = *pSrcU++;
1535 pTmpOutColU += outWidth / 2;
1536 *pTmpOutColV = *pSrcV++;
1537 pTmpOutColV += outWidth / 2;
1538 *pTmpOutColY = *pSrcY++;
1539 pTmpOutColY += outWidth;
1541 for (colCount = width / 2; colCount < width; colCount++)
1543 *pTmpOutColY = *pSrcY++;
1544 pTmpOutColY += outWidth;
1547 for (rowCount = height / 2; rowCount < height; rowCount++)
1549 pTmpOutColY = pDstY + outWidth - 1 - rowCount;
1550 for (colCount = 0; colCount < width; colCount++)
1552 *pTmpOutColY = *pSrcY++;
1553 pTmpOutColY += outWidth;
1558 case IMAGE_ROTATION_180:
1560 // Copying from all source rows to destination columns of Y plane.
1561 pTmpOutColY = pDstY + outWidth * outHeight - 1;
1562 pTmpOutColU = pDstU + (outWidth / 2) * (outHeight / 2) - 1;
1563 pTmpOutColV = pDstV + (outWidth / 2) * (outHeight / 2) - 1;
1564 for (colCount = 0; colCount < (outWidth / 2 * outHeight / 2); colCount++)
1566 *pTmpOutColY-- = *pSrcY++;
1567 *pTmpOutColU-- = *pSrcU++;
1568 *pTmpOutColV-- = *pSrcV++;
1570 for (colCount = (outWidth / 2 * outHeight / 2); colCount < (outWidth * outHeight); colCount++)
1572 *pTmpOutColY-- = *pSrcY++;
1576 case IMAGE_ROTATION_270:
1579 // Copying from all source rows to destination columns of Y plane.
1580 for (rowCount = 0; rowCount < height / 2; rowCount++)
1582 // pTmpOutCol points to the top of the output column being filled.
1583 pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
1584 pTmpOutColU = pDstU + (outWidth / 2) * (outHeight / 2 - 1) + rowCount;
1585 pTmpOutColV = pDstV + (outWidth / 2) * (outHeight / 2 - 1) + rowCount;
1586 for (colCount = 0; colCount < width / 2; colCount++)
1588 *pTmpOutColY = *pSrcY++;
1589 pTmpOutColY -= outWidth;
1590 *pTmpOutColU = *pSrcU++;
1591 pTmpOutColU -= outWidth / 2;
1592 *pTmpOutColV = *pSrcV++;
1593 pTmpOutColV -= outWidth / 2;
1595 for (colCount = width / 2; colCount < width; colCount++)
1597 *pTmpOutColY = *pSrcY++;
1598 pTmpOutColY -= outWidth;
1601 for (rowCount = height / 2; rowCount < height; rowCount++)
1603 pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
1604 // pTmpOutCol points to the top of the output column being filled.
1605 for (colCount = 0; colCount < width; colCount++)
1607 *pTmpOutColY = *pSrcY++;
1608 pTmpOutColY -= outWidth;
1617 else if (pixelFormat == MEDIA_PIXEL_FORMAT_NV12
1618 || pixelFormat == MEDIA_PIXEL_FORMAT_NV21)
1622 byte* pDstY = (byte *)dstBuf.GetPointer();
1623 short* pDstUV = (short* )(pDstY + outWidth * outHeight);
1625 byte* pSrcY = (byte* ) srcBuf.GetPointer();
1626 short* pSrcUV = (short* )(pSrcY + width * height);
1627 byte* pTmpOutColY = null;
1628 short* pTmpOutColUV = null;
1632 case IMAGE_ROTATION_90:
1634 // Copying from all source rows to destination columns of Y plane.
1635 for (rowCount = 0; rowCount < height / 2; rowCount++)
1637 // pTmpOutCol points to the top of the output column being filled.
1638 pTmpOutColUV = pDstUV + (outWidth / 2) - 1 - rowCount;
1639 pTmpOutColY = pDstY + outWidth - 1 - rowCount;
1640 for (colCount = 0; colCount < width / 2; colCount++)
1642 *pTmpOutColUV = *pSrcUV++;
1643 pTmpOutColUV += outWidth / 2 ;
1644 *pTmpOutColY = *pSrcY++;
1645 pTmpOutColY += outWidth;
1647 for (colCount = width / 2; colCount < width; colCount++)
1649 *pTmpOutColY = *pSrcY++;
1650 pTmpOutColY += outWidth;
1653 for (rowCount = height / 2; rowCount < height; rowCount++)
1655 // pTmpOutCol points to the top of the output column being filled.
1656 pTmpOutColY = pDstY + outWidth - 1 - rowCount;
1657 for (colCount = 0; colCount < width; colCount++)
1659 *pTmpOutColY = *pSrcY++;
1660 pTmpOutColY += outWidth;
1665 case IMAGE_ROTATION_180:
1667 // Copying from all source rows to destination columns of Y plane.
1668 pTmpOutColY = pDstY + outWidth * outHeight - 1;
1669 pTmpOutColUV = pDstUV + (outWidth / 2) * (outHeight / 2) - 1;
1670 for (colCount = 0; colCount < (outWidth / 2 * outHeight / 2); colCount++)
1672 *pTmpOutColY-- = *pSrcY++;
1673 *pTmpOutColUV-- = *pSrcUV++;
1675 for (colCount = (outWidth / 2 * outHeight / 2); colCount < outWidth * outHeight; colCount++)
1677 *pTmpOutColY-- = *pSrcY++;
1681 case IMAGE_ROTATION_270:
1683 // Copying from all source rows to destination columns of Y plane.
1684 for (rowCount = 0; rowCount < height / 2; rowCount++)
1686 // pTmpOutCol points to the top of the output column being filled.
1687 pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
1688 pTmpOutColUV = pDstUV + (outWidth / 2) * (outHeight / 2 - 1) + rowCount;
1689 for (colCount = 0; colCount < width / 2; colCount++)
1691 *pTmpOutColY = *pSrcY++;
1692 pTmpOutColY -= outWidth;
1693 *pTmpOutColUV = *pSrcUV++;
1694 pTmpOutColUV -= outWidth / 2;
1696 for (colCount = width / 2; colCount < width; colCount++)
1698 *pTmpOutColY = *pSrcY++;
1699 pTmpOutColY -= outWidth;
1702 for (rowCount = height / 2; rowCount < height; rowCount++)
1704 // pTmpOutCol points to the top of the output column being filled.
1705 pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
1706 for (colCount = 0; colCount < width; colCount++)
1708 *pTmpOutColY = *pSrcY++;
1709 pTmpOutColY -= outWidth;
1719 else if (pixelFormat == MEDIA_PIXEL_FORMAT_YUV444P)
1723 byte* pDstY = (byte *)dstBuf.GetPointer();
1724 byte* pDstU = pDstY + outWidth * outHeight;
1725 byte* pDstV = pDstU + outWidth * outHeight;
1727 byte* pSrcY = (byte *) srcBuf.GetPointer();
1728 byte* pSrcU = pSrcY + width * height;
1729 byte* pSrcV = pSrcU + width * height;
1730 byte* pTmpOutColY = null;
1731 byte* pTmpOutColU = null;
1732 byte* pTmpOutColV = null;
1736 case IMAGE_ROTATION_90:
1738 // Copying from all source rows to destination columns of Y plane.
1739 for (rowCount = 0; rowCount < height; rowCount++)
1741 // pTmpOutCol points to the top of the output column being filled.
1742 pTmpOutColU = pDstU + outWidth - 1 - rowCount;
1743 pTmpOutColV = pDstV + outWidth - 1 - rowCount;
1744 pTmpOutColY = pDstY + outWidth - 1 - rowCount;
1745 for (colCount = 0; colCount < width / 2; colCount++)
1747 *pTmpOutColU = *pSrcU++;
1748 pTmpOutColU += outWidth;
1749 *pTmpOutColV = *pSrcV++;
1750 pTmpOutColV += outWidth;
1751 *pTmpOutColY = *pSrcY++;
1752 pTmpOutColY += outWidth;
1754 *pTmpOutColU = *pSrcU++;
1755 pTmpOutColU += outWidth;
1756 *pTmpOutColV = *pSrcV++;
1757 pTmpOutColV += outWidth;
1758 *pTmpOutColY = *pSrcY++;
1759 pTmpOutColY += outWidth;
1764 case IMAGE_ROTATION_180:
1766 // Copying from all source rows to destination columns of Y plane.
1767 pTmpOutColY = pDstY + outWidth * outHeight - 1;
1768 pTmpOutColU = pDstU + outWidth * outHeight - 1;
1769 pTmpOutColV = pDstV + outWidth * outHeight - 1;
1770 for (colCount = (outWidth * outHeight); colCount > 0; colCount--)
1772 *pTmpOutColY-- = *pSrcY++;
1773 *pTmpOutColU-- = *pSrcU++;
1774 *pTmpOutColV-- = *pSrcV++;
1778 case IMAGE_ROTATION_270:
1780 // Copying from all source rows to destination columns of Y plane.
1781 for (rowCount = 0; rowCount < height; rowCount++)
1783 // pTmpOutCol points to the top of the output column being filled.
1784 pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
1785 pTmpOutColU = pDstU + (outWidth * (outHeight - 1)) + rowCount;
1786 pTmpOutColV = pDstV + (outWidth * (outHeight - 1)) + rowCount;
1787 for (colCount = 0; colCount < width / 2; colCount++)
1789 *pTmpOutColY = *pSrcY++;
1790 pTmpOutColY -= outWidth;
1791 *pTmpOutColU = *pSrcU++;
1792 pTmpOutColU -= outWidth;
1793 *pTmpOutColV = *pSrcV++;
1794 pTmpOutColV -= outWidth;
1796 *pTmpOutColY = *pSrcY++;
1797 pTmpOutColY -= outWidth;
1798 *pTmpOutColU = *pSrcU++;
1799 pTmpOutColU -= outWidth;
1800 *pTmpOutColV = *pSrcV++;
1801 pTmpOutColV -= outWidth;
1810 else if (pixelFormat == MEDIA_PIXEL_FORMAT_YUYV422)
1814 short* pSrcBuf = (short*)srcBuf.GetPointer();
1815 short* pDstBuf = (short*)dstBuf.GetPointer();
1816 short* pTmpOutCol = null;
1820 case IMAGE_ROTATION_90:
1822 // Copying from all source rows to destination columns.
1823 for (rowCount = 0; rowCount < height; rowCount++)
1825 // pTmpOutCol points to the top of the output column being filled.
1826 pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
1827 for (colCount = 0; colCount < width / 2 ; colCount++)
1829 *pTmpOutCol = *pSrcBuf++; // copied Y0 U0
1830 pTmpOutCol += outWidth;
1832 *pTmpOutCol = *pSrcBuf++; // copied Y1 V0
1833 pTmpOutCol += outWidth;
1838 case IMAGE_ROTATION_180:
1840 // Copying all source rows to destination columns.
1841 for (rowCount = 0; rowCount < height; rowCount++)
1843 // pTmpOutCol points to the bottom of the column being filled.
1844 pTmpOutCol = pDstBuf + ((outWidth * outHeight ) - 1) - (rowCount * outWidth);
1846 for (colCount = 0; colCount < width / 2; colCount++)
1848 *pTmpOutCol-- = *pSrcBuf++; // copied Y0 U0
1849 *pTmpOutCol-- = *pSrcBuf++; // copied Y1 V0
1854 case IMAGE_ROTATION_270:
1856 // Copying all source rows to destination columns.
1857 for (rowCount = 0; rowCount < height; rowCount++)
1859 // pTmpOutCol points to the bottom of the column being filled.
1860 pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
1861 for (colCount = 0; colCount < width / 2; colCount++)
1863 *pTmpOutCol = *pSrcBuf++; // copied B
1864 pTmpOutCol -= outWidth;
1866 *pTmpOutCol = *pSrcBuf++; // copied B
1867 pTmpOutCol -= outWidth;
1880 colorFormat = _SlpUtil::ToMmUtilImgFormat(pixelFormat);
1881 rotation = _SlpUtil::ToMmUtilRotateType(rotate);
1883 ret = mm_util_rotate_image((unsigned char*)srcBuf.GetPointer(), width, height, colorFormat,
1884 (unsigned char*)dstBuf.GetPointer(), &outWidth, &outHeight, rotation);
1886 SysTryCatch(NID_MEDIA, ret == 0, r = E_SYSTEM, E_SYSTEM,
1887 "mm_util_rotate_image: %0x", ret);
1891 colorFormat = _SlpUtil::ToColorspace(pixelFormat);
1892 rotation = _SlpUtil::ToRotation(rotate);
1894 ret = image_util_transform((byte*)dstBuf.GetPointer(), &outWidth, &outHeight, rotation,
1895 (byte*)srcBuf.GetPointer(), width, height, colorFormat);
1897 SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
1898 "[E_SYSTEM] util_transform failed: %0x", ret);
1903 r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
1904 SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
1905 "[%s] dstBuf.SetLimit failed for (%d x %d) pixel format: %d",
1906 GetErrorMessage(r), outWidth, outHeight, pixelFormat);
1915 _ImageUtil::Flip(const ByteBuffer& srcBuf, MediaPixelFormat pixelFormat,
1916 int width, int height,
1917 ByteBuffer& dstBuf, ImageFlipType flip)
1919 result r = E_SUCCESS;
1922 mm_util_img_format colorFormat = MM_UTIL_IMG_FMT_NUM;
1923 mm_util_img_rotate_type rotation = MM_UTIL_ROTATE_NUM;
1925 unsigned int outWidth = 0;
1926 unsigned int outHeight = 0;
1928 image_util_colorspace_e colorFormat = IMAGE_UTIL_COLORSPACE_RGB565;
1929 image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
1934 SysTryCatch(NID_MEDIA, width > 0 && height > 0, r = E_INVALID_ARG, E_INVALID_ARG,
1935 "[E_INVALID_ARG] Invalid dimension: Should be greater than zero: (%d x %d)",
1938 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
1939 "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
1941 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, width, height),
1942 r = E_INVALID_ARG, E_INVALID_ARG,
1943 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", width, height);
1945 SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, width, height),
1946 r = E_INVALID_ARG, E_INVALID_ARG,
1947 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
1948 srcBuf.GetLimit(), pixelFormat, width, height);
1950 SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, width, height),
1951 r = E_INVALID_ARG, E_INVALID_ARG,
1952 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
1953 dstBuf.GetLimit(), pixelFormat, width, height);
1955 if (flip == IMAGE_FLIP_NONE)
1957 r = dstBuf.SetArray(srcBuf.GetPointer(), 0, srcBuf.GetLimit());
1958 SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
1959 "[%s] dstBuf.SetArray failed: source (%x %d), dst (%d %d)",
1960 srcBuf.GetPointer(), srcBuf.GetLimit(),
1961 dstBuf.GetPosition(), dstBuf.GetCapacity());
1966 // Set output dimensions;
1970 if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
1972 if (flip == IMAGE_FLIP_HORIZONTAL)
1976 unsigned short* pSrcBuf = (unsigned short *)srcBuf.GetPointer();
1977 unsigned short* pDstBuf = (unsigned short *)dstBuf.GetPointer();
1978 // pTmpOutRow points to last column of first row of destination.
1979 unsigned short* pTmpOutRow = pDstBuf + width - 1;
1981 for (rowCount = 0; rowCount < height; rowCount++)
1983 for (colCount = 0; colCount < width; colCount++)
1985 *pTmpOutRow-- = *pSrcBuf++; // copy source row in reverse to destination.
1987 pTmpOutRow += (2 * outWidth);
1993 unsigned short* pSrcBuf = (unsigned short *)srcBuf.GetPointer();
1994 unsigned short* pDstBuf = (unsigned short *)dstBuf.GetPointer();
1995 // pTmpOutRow points to the start of last row in destination buffer.
1996 unsigned short* pTmpOutRow = pDstBuf + (width * (height - 1));
1998 for (rowCount = 0; rowCount < height; rowCount++)
2000 // copy one row worth of data.
2001 memcpy(pTmpOutRow, pSrcBuf, sizeof(unsigned short) * width);
2002 pTmpOutRow -= width; // go to one higher row.
2003 pSrcBuf += width; // go to next row.
2011 colorFormat = _SlpUtil::ToMmUtilImgFormat(pixelFormat);
2012 rotation = _SlpUtil::ToMmUtilRotateType(flip);
2014 ret = mm_util_rotate_image((unsigned char*)srcBuf.GetPointer(), width, height, colorFormat,
2015 (unsigned char*)dstBuf.GetPointer(), &outWidth, &outHeight, rotation);
2017 SysTryCatch(NID_MEDIA, ret == 0, r = E_SYSTEM, E_SYSTEM,
2018 "mm_util_rotate_image failed with error code: %0x", ret);
2020 colorFormat = _SlpUtil::ToColorspace(pixelFormat);
2021 rotation = _SlpUtil::ToRotation(flip);
2023 ret = image_util_transform((byte*)dstBuf.GetPointer(), &outWidth, &outHeight, rotation,
2024 (byte*)srcBuf.GetPointer(), width, height, colorFormat);
2025 SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
2026 "util_transform failed with error code: %0x", ret);
2030 r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
2031 SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
2032 "[%s] SetLimit to %d failed for buffer.", GetErrorMessage(r),
2033 _ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
2041 Tizen::Media::ImageFormat
2042 _ImageUtil::GetImageFormat(const Tizen::Base::String& srcImageFile)
2044 ImageFormat imgFormat;
2045 ByteBuffer* pBuf = null;
2047 pBuf = _MediaUtil::FileToBufferN(srcImageFile, _ImageUtil::MinImageFormatLength());
2048 SysTryCatch(NID_MEDIA, pBuf != null, , GetLastResult(),
2049 "[%s] _MediaUtil::FileToBufferN failed for %ls.",
2050 GetErrorMessage(GetLastResult()), srcImageFile.GetPointer());
2052 imgFormat = GetImageFormat(*pBuf);
2062 return IMG_FORMAT_NONE;
2067 _ImageUtil::HasAlphaChannel(const Tizen::Base::String& srcImageFile)
2069 bool hasAlpha = false;
2070 ByteBuffer* pBuf = null;
2072 pBuf = _MediaUtil::FileToBufferN(srcImageFile);
2073 SysTryCatch(NID_MEDIA, pBuf != null, , GetLastResult(),
2074 "[%s] _MediaUtil::FileToBufferN failed for %ls.",
2075 GetErrorMessage(GetLastResult()), srcImageFile.GetPointer());
2076 hasAlpha = HasAlphaChannel(*pBuf);
2087 // For check image format
2088 static byte _PNG_HEADER[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
2089 static byte _JPEG_HEADER[] = { 0xFF, 0xD8 }; // support only JFIF.
2090 static byte _GIF_HEADER[] = { 'G', 'I', 'F' };
2091 static byte _TIFF_HEADER[][4] = { { 0x49, 0x49, 0x2A, 0x00 }, { 0x4D, 0x4D, 0x00, 0x2A } };
2092 static byte _BMP_HEADER[] = { 'B', 'M' };
2093 static byte _WBMP_HEADER[] = { 0x00, 0x00 };
2095 static const int MIN_IMAGE_FORMAT_LENGTH = sizeof(_PNG_HEADER);
2098 _ImageUtil::MinImageFormatLength(void)
2100 return MIN_IMAGE_FORMAT_LENGTH;
2104 _ImageUtil::GetImageFormat(const Tizen::Base::ByteBuffer& srcBuf)
2106 const byte* pBuf = null;
2113 { _PNG_HEADER, sizeof(_PNG_HEADER), IMG_FORMAT_PNG },
2114 { _JPEG_HEADER, sizeof(_JPEG_HEADER), IMG_FORMAT_JPG },
2115 { _BMP_HEADER, sizeof(_BMP_HEADER), IMG_FORMAT_BMP },
2116 { _GIF_HEADER, sizeof(_GIF_HEADER), IMG_FORMAT_GIF },
2117 { _TIFF_HEADER[0], sizeof(_TIFF_HEADER[0]), IMG_FORMAT_TIFF },
2118 { _TIFF_HEADER[1], sizeof(_TIFF_HEADER[1]), IMG_FORMAT_TIFF },
2119 { _WBMP_HEADER, sizeof(_WBMP_HEADER), IMG_FORMAT_WBMP },
2121 ImageFormat fmt = IMG_FORMAT_NONE;
2122 SysTryCatch(NID_MEDIA, &srcBuf != null, , E_INVALID_ARG,
2123 "[E_INVALID_ARG] srcBuf is null");
2124 SysTryCatch(NID_MEDIA, srcBuf.GetLimit() >= MIN_IMAGE_FORMAT_LENGTH, , E_INVALID_DATA,
2125 "[E_INVALID_DATA] data is too small:%d < %d", srcBuf.GetLimit(), MIN_IMAGE_FORMAT_LENGTH);
2127 pBuf = (const byte*) (srcBuf.GetPointer());
2128 SysTryCatch(NID_MEDIA, pBuf != null, , E_INVALID_ARG,
2129 "[E_INVALID_ARG] Could not get file header.");
2130 for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
2132 if (memcmp(pBuf, map[i].pHeader, map[i].size) == 0)
2134 fmt = map[i].format;
2138 if ((fmt == IMG_FORMAT_WBMP) && (pBuf[2] == 1 || pBuf[2] == 2) && pBuf[3] == 0 )
2140 fmt = IMG_FORMAT_NONE;
2146 return IMG_FORMAT_NONE;
2150 _ImageUtil::HasAlphaChannel(const Tizen::Base::ByteBuffer& srcBuf)
2152 ImageFormat imgFormat = IMG_FORMAT_NONE;
2153 const byte* pBuf = null;
2154 bool idatFlag = false;
2155 bool hasAlpha = false;
2156 unsigned int cnkLength = 0;
2157 int curPosition = 0;
2161 SysTryReturn(NID_MEDIA, &srcBuf != null, hasAlpha, E_INVALID_ARG,
2162 "[E_INVALID_ARG] srcBuf is null");
2164 imgFormat = GetImageFormat(srcBuf);
2166 SysTryReturn(NID_MEDIA, imgFormat == IMG_FORMAT_PNG, hasAlpha, E_UNSUPPORTED_FORMAT,
2167 "[E_UNSUPPORTED_FORMAT] The file is not of PNG format.");
2169 pBuf = (const byte*)srcBuf.GetPointer();
2170 bufSize = srcBuf.GetCapacity();
2173 // 25 means, Png ID(8byte) + IHDR length(4byte) + IHDR(4byte) +
2174 // Width(4byte) + Height(4byte) + Bitdepth(1byte) and next 1byte is
2176 // If color type is between 4 and 7, it uses alpha channel.
2177 SysTryReturn(NID_MEDIA, bufSize > (curPosition + 4), hasAlpha, E_UNSUPPORTED_FORMAT,
2178 "[E_INVALID_DATA] data size is too small: %d < %d", bufSize, curPosition + 4);
2180 value = pBuf[curPosition];
2181 if ((4 <= value) && (value <= 7))
2185 else if (value == 3)
2187 // check tRNS chunck existance if color type is 3(indexed palette).
2188 // 25byte + remained IHDR 3byte(filter mode etc.) = 28byte
2189 // 28byte + ?(4byte)
2191 // Chunk length(4byte)+ chunk name(4byte) + length(value of chunk length) + CRC(4byte)
2192 // chunk can be pHYs, sBIT, gAMA, cHRM, tRNS, etc (before IDAT)
2193 SysTryReturn(NID_MEDIA, bufSize > (curPosition + 4), hasAlpha, E_INVALID_DATA,
2194 "[E_INVALID_DATA] data size is too small: %d < %d", bufSize, curPosition + 4);
2196 // Structure of chunk:
2197 // |<----------------- A single chunk ---------------------->|
2198 // |_________________________________________________________|
2199 // | 4 bytes || 4 bytes || chunk length bytes || 4 bytes |
2200 // |____________||__________||____________________||_________|
2202 // |Chunk length||Chunk name|| chunk data || CRC sum |
2204 // data is stored in network byte order; ie big endian.
2205 // To get the value, convert to little endian.
2207 memcpy(&cnkLength, pBuf + curPosition, 4);
2208 cnkLength = ntohl(cnkLength);
2210 // Increment position to point to chunk name, which follows the length.
2211 curPosition = curPosition + 4;
2213 // Loop with starting chunk length.
2214 while (curPosition < bufSize - 4)
2216 if (!memcmp((void *)(pBuf + curPosition), (void *)"tRNS", 4))
2220 else if (!memcmp((void *)(pBuf + curPosition), (void *)"IDAT", 4))
2226 curPosition += 4; // chunk name
2227 curPosition += cnkLength;
2228 curPosition += 4; // CRC
2231 // tRNS chunk must be before IDAT chunk.
2232 if (idatFlag || hasAlpha)
2237 if (curPosition >= bufSize - 4)
2242 // read next chunk length
2243 memcpy(&cnkLength, pBuf + curPosition, 4);
2244 cnkLength = ntohl(cnkLength);
2245 curPosition = curPosition + 4;
2252 Tizen::Base::ByteBuffer*
2253 _ImageUtil::ResizeN(const Tizen::Base::ByteBuffer &srcBuf,
2254 MediaPixelFormat pixelFormat,
2255 int srcWidth, int srcHeight,
2256 int dstWidth, int dstHeight)
2259 std::unique_ptr <ByteBuffer> pOutBuf;
2260 result r = E_SUCCESS;
2262 bufSize = GetBufferSize(pixelFormat, dstWidth, dstHeight);
2263 SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
2264 "[%s] Check dimensions (%d x %d) and pixelformat %d", GetErrorMessage(GetLastResult()),
2265 dstWidth, dstHeight, pixelFormat);
2267 pOutBuf.reset(new (std::nothrow) ByteBuffer());
2268 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
2269 "[%s] Failed to create new ByteBuffer", GetErrorMessage(GetLastResult()));
2271 r = pOutBuf->Construct(bufSize);
2272 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2273 "[%s] ByteBuffer.Construct failed", GetErrorMessage(r));
2275 r = Resize(srcBuf, pixelFormat, srcWidth, srcHeight, *pOutBuf.get(), dstWidth, dstHeight);
2276 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2277 "[%s] ImageUtil.Resize", GetErrorMessage(r));
2279 SetLastResult(E_SUCCESS);
2280 return pOutBuf.release();
2284 _ImageUtil::Crop(const Tizen::Base::ByteBuffer &srcBuf,
2285 MediaPixelFormat pixelFormat,
2286 int srcWidth, int srcHeight,
2287 Tizen::Base::ByteBuffer &dstBuf,
2288 int dstX, int dstY, int dstWidth, int dstHeight)
2290 result r = E_SUCCESS;
2291 byte* pInBuffer = null;
2292 byte* pOutBuffer = null;
2293 int copyRowWidth = 0;
2294 int srcRowWidth = 0;
2297 SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
2298 "[E_INVALID_ARG] Invalid src dimension: Should be greater than zero (%d x %d)", srcWidth, srcHeight);
2299 SysTryCatch(NID_MEDIA, dstWidth > 0 && dstHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
2300 "[E_INVALID_ARG] Invalid dst dimension: Should be greater than zero (%d x %d)", dstWidth, dstHeight);
2301 SysTryCatch(NID_MEDIA, dstX >= 0 && dstY >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
2302 "[E_INVALID_ARG] Invalid offset dimension: Should be greater than zero (%d x %d)", dstX, dstY);
2304 SysTryCatch(NID_MEDIA, (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE) ||
2305 (pixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888) ||
2306 (pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888),
2307 r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
2308 "Unsupported pixelFormat: %d", pixelFormat);
2310 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, srcWidth, srcHeight),
2311 r = E_INVALID_ARG, E_INVALID_ARG,
2312 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
2314 SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, srcWidth, srcHeight),
2315 r = E_INVALID_ARG, E_INVALID_ARG,
2316 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
2317 srcBuf.GetLimit(), pixelFormat, srcWidth, srcHeight);
2319 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, dstWidth, dstHeight),
2320 r = E_INVALID_ARG, E_INVALID_ARG,
2321 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", dstWidth, dstHeight);
2323 SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, dstWidth, dstHeight),
2324 r = E_INVALID_ARG, E_INVALID_ARG,
2325 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
2326 dstBuf.GetLimit(), pixelFormat, dstWidth, dstHeight);
2328 SysTryCatch(NID_MEDIA, dstWidth + dstX <= srcWidth , r = E_INVALID_ARG, E_INVALID_ARG,
2329 "Invalid Clip Area : destination \"x\" (%d) exceeds image width (%d).",
2330 dstWidth + dstX, srcWidth);
2332 SysTryCatch(NID_MEDIA, dstHeight + dstY <= srcHeight , r = E_INVALID_ARG, E_INVALID_ARG,
2333 "Invalid Clip Area : destination \"y\" (%d) exceeds image height (%d).",
2334 dstHeight + dstY, srcHeight);
2336 pOutBuffer = (byte *)dstBuf.GetPointer();
2338 if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
2341 // pInBuffer points to the start of the region to be copied to destination.
2342 pInBuffer = (byte *)srcBuf.GetPointer() + (dstY * srcWidth * bpp) + (dstX * bpp);
2343 copyRowWidth = dstWidth * bpp;
2344 srcRowWidth = srcWidth * bpp;
2349 // pInBuffer points to the start of the region to be copied to destination.
2350 pInBuffer = (byte *)srcBuf.GetPointer() + (dstY * srcWidth * bpp) + (dstX * bpp);
2351 copyRowWidth = dstWidth * bpp; // BGRA and RGBA are 4 bytes each.
2352 srcRowWidth = srcWidth * bpp;
2355 for (int i = dstY; i < dstY + dstHeight; i++)
2357 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2358 pOutBuffer += copyRowWidth;
2359 pInBuffer += srcRowWidth;
2362 r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(pixelFormat, dstWidth, dstHeight));
2363 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] ByteBuffer.SetLimit to %d failed.",
2364 GetErrorMessage(r), _ImageUtil::GetBufferSize(pixelFormat, dstWidth, dstHeight));
2372 _ImageUtil::CropBuffer(const byte* srcBuf,
2373 MediaPixelFormat pixelFormat,
2374 int srcWidth, int srcHeight,
2376 int dstX, int dstY, int dstWidth, int dstHeight)
2378 result r = E_SUCCESS;
2379 int copyRowWidth = 0;
2380 int srcRowWidth = 0;
2382 byte* pInBuffer = null;
2383 byte* pOutBuffer = null;
2385 SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
2386 "[E_INVALID_ARG] Invalid src dimension: Should be greater than zero (%d x %d)", srcWidth, srcHeight);
2387 SysTryCatch(NID_MEDIA, dstWidth > 0 && dstHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
2388 "[E_INVALID_ARG] Invalid dst dimension: Should be greater than zero (%d x %d)", dstWidth, dstHeight);
2389 SysTryCatch(NID_MEDIA, dstX >= 0 && dstY >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
2390 "[E_INVALID_ARG] Invalid offset dimension: Should be greater than zero (%d x %d)", dstX, dstY);
2392 SysTryCatch(NID_MEDIA, (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE) ||
2393 (pixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888) ||
2394 (pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888),
2395 r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
2396 "Unsupported pixelFormat: %d", pixelFormat);
2398 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, srcWidth, srcHeight),
2399 r = E_INVALID_ARG, E_INVALID_ARG,
2400 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
2402 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, dstWidth, dstHeight),
2403 r = E_INVALID_ARG, E_INVALID_ARG,
2404 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", dstWidth, dstHeight);
2406 SysTryCatch(NID_MEDIA, dstWidth + dstX <= srcWidth , r = E_INVALID_ARG, E_INVALID_ARG,
2407 "Invalid Clip Area : destination \"x\" (%d) exceeds image width (%d).",
2408 dstWidth + dstX, srcWidth);
2410 SysTryCatch(NID_MEDIA, dstHeight + dstY <= srcHeight , r = E_INVALID_ARG, E_INVALID_ARG,
2411 "Invalid Clip Area : destination \"y\" (%d) exceeds image height (%d).",
2412 dstHeight + dstY, srcHeight);
2414 pOutBuffer = dstBuf;
2416 if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
2419 // pInBuffer points to the start of the region to be copied to destination.
2420 pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
2421 copyRowWidth = dstWidth * bpp;
2422 srcRowWidth = srcWidth * bpp;
2427 // pInBuffer points to the start of the region to be copied to destination.
2428 pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
2429 copyRowWidth = dstWidth * bpp; // BGRA and RGBA are 4 bytes each.
2430 srcRowWidth = srcWidth * bpp;
2433 for (int i = dstY; i < dstY + dstHeight; i++)
2435 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2436 pOutBuffer += copyRowWidth;
2437 pInBuffer += srcRowWidth;
2444 Tizen::Base::ByteBuffer*
2445 _ImageUtil::CropN(const Tizen::Base::ByteBuffer &srcBuf,
2446 MediaPixelFormat pixelFormat,
2447 int srcWidth, int srcHeight,
2449 int dstWidth, int dstHeight)
2452 std::unique_ptr <ByteBuffer> pOutBuf;
2453 result r = E_SUCCESS;
2455 bufSize = GetBufferSize(pixelFormat, dstWidth, dstHeight);
2456 SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
2457 "[%s] Check dimensions (%d x %d) and pixel format (%d)",
2458 GetErrorMessage(GetLastResult()), dstWidth, dstHeight, pixelFormat);
2460 pOutBuf.reset(new (std::nothrow) ByteBuffer());
2461 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
2462 "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
2464 r = pOutBuf->Construct(bufSize);
2465 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2466 "[%s] buf.Construct failed.", GetErrorMessage(r));
2468 r = Crop(srcBuf, pixelFormat, srcWidth, srcHeight, *pOutBuf.get(), dstX, dstY, dstWidth, dstHeight);
2469 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2470 "[%s] ImageUtil.Crop failed.", GetErrorMessage(r));
2472 SetLastResult(E_SUCCESS);
2473 return pOutBuf.release();
2477 _ImageUtil::CropN(const byte *srcBuf,
2478 MediaPixelFormat pixelFormat,
2479 int srcWidth, int srcHeight,
2480 int dstX, int dstY, int dstWidth, int dstHeight)
2483 std::unique_ptr <byte[]> pOutBuf;
2484 result r = E_SUCCESS;
2486 bufSize = GetBufferSize(pixelFormat, dstWidth, dstHeight);
2487 SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
2488 "[%s] Check dimensions (%d x %d) and pixel format (%d)",
2489 GetErrorMessage(GetLastResult()), dstWidth, dstHeight, pixelFormat);
2491 pOutBuf.reset(new (std::nothrow) byte[bufSize]);
2492 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
2493 "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
2495 r = CropBuffer(srcBuf, pixelFormat, srcWidth, srcHeight, pOutBuf.get(), dstX, dstY, dstWidth, dstHeight);
2496 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2497 "[%s] ImageUtil.CropN failed.", GetErrorMessage(r));
2499 SetLastResult(E_SUCCESS);
2500 return pOutBuf.release();
2504 _ImageUtil::RotateN(const byte *srcBuf,
2505 MediaPixelFormat pixelFormat,
2506 int srcWidth, int srcHeight,
2507 ImageRotationType rotate,
2508 int &dstWidth, int &dstHeight)
2511 std::unique_ptr <byte[]> pOutBuf;
2512 result r = E_SUCCESS;
2514 bufSize = GetBufferSize(pixelFormat, srcWidth, srcHeight);
2515 SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
2516 "[%s] Check dimensions (%d x %d) and pixel format (%d)",
2517 GetErrorMessage(GetLastResult()), dstWidth, dstHeight, pixelFormat);
2519 pOutBuf.reset(new (std::nothrow) byte[bufSize]);
2520 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
2521 "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
2523 r = RotateBuffer(srcBuf, pixelFormat, srcWidth, srcHeight, pOutBuf.get(), dstWidth, dstHeight, rotate);
2524 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2525 "[%s] ImageUtil.RotateN failed.", GetErrorMessage(r));
2527 SetLastResult(E_SUCCESS);
2528 return pOutBuf.release();
2532 _ImageUtil::FlipN(const byte* srcBuf,
2533 MediaPixelFormat pixelFormat, int width, int height,
2537 std::unique_ptr <byte[]> pOutBuf;
2538 result r = E_SUCCESS;
2540 bufSize = GetBufferSize(pixelFormat, width, height);
2541 SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
2542 "[%s] Check dimensions (%d x %d) and pixel format (%d)",
2543 GetErrorMessage(GetLastResult()), width, height, pixelFormat);
2545 pOutBuf.reset(new (std::nothrow) byte[bufSize]);
2546 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
2547 "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
2549 r = FlipBuffer(srcBuf, pixelFormat, width, height, pOutBuf.get(), flip);
2550 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2551 "[%s] ImageUtil.FlipN failed.", GetErrorMessage(r));
2553 SetLastResult(E_SUCCESS);
2554 return pOutBuf.release();
2558 _ImageUtil::GetBufferSize(MediaPixelFormat pixelFormat, int width, int height)
2560 typedef struct _Rational
2568 MediaPixelFormat key;
2571 { MEDIA_PIXEL_FORMAT_RGB565LE, {2, 1}},
2572 { MEDIA_PIXEL_FORMAT_RGBA8888, {4, 1}},
2573 { MEDIA_PIXEL_FORMAT_BGRA8888, {4, 1}},
2574 { MEDIA_PIXEL_FORMAT_YUV420P, {3, 2}},
2575 { MEDIA_PIXEL_FORMAT_NV12, {3, 2}},
2576 { MEDIA_PIXEL_FORMAT_YUYV422, {2, 1}},
2577 { MEDIA_PIXEL_FORMAT_BGR888, {3,1}},
2578 { MEDIA_PIXEL_FORMAT_RGB888, {3,1}},
2580 rational ret = {0, 0};
2582 SysTryCatch(NID_MEDIA, width > 0 && height > 0, , E_INVALID_ARG,
2583 "[E_INVALID_ARG] Dimensions should be greater than zero (%d x %d)", width, height);
2585 for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
2587 if (map[i].key == pixelFormat)
2594 SysTryCatch(NID_MEDIA, ret.den != 0, , E_UNSUPPORTED_FORMAT,
2595 "Could not find details for pixelformat %d.", pixelFormat);
2597 SetLastResult(E_SUCCESS);
2598 return width * height * ret.num / ret.den;
2605 _ImageUtil::IsValidDimension(MediaPixelFormat pixelFormat, int width, int height)
2607 MediaPixelFormat fmt[] = {
2608 MEDIA_PIXEL_FORMAT_YUV420P,
2609 MEDIA_PIXEL_FORMAT_NV12,
2610 MEDIA_PIXEL_FORMAT_YUYV422,
2613 for (unsigned int i = 0; i < sizeof(fmt)/sizeof(fmt[0]); i++)
2615 if (fmt[i] == pixelFormat)
2617 if ((width & 0x01) || (height & 0x01))
2624 // return true for other pixel formats
2629 _ImageUtil::ToFfmpegPixelFormat(MediaPixelFormat pixelFmt)
2631 for (unsigned int i = 0; i < sizeof(_PIXEL_FORMAT_MAP)/sizeof(_PIXEL_FORMAT_MAP[0]); i++)
2633 if (pixelFmt == _PIXEL_FORMAT_MAP[i].mediaPixelFmt)
2635 return _PIXEL_FORMAT_MAP[i].pixelFmt;
2638 return PIX_FMT_NONE;
2642 _ImageUtil::ToMediaPixelFormatFromFfmpeg(int pixelFormat)
2644 for (unsigned int i = 0; i < sizeof(_PIXEL_FORMAT_MAP)/sizeof(_PIXEL_FORMAT_MAP[0]); i++)
2646 if (pixelFormat == _PIXEL_FORMAT_MAP[i].pixelFmt)
2648 return _PIXEL_FORMAT_MAP[i].mediaPixelFmt;
2651 return MEDIA_PIXEL_FORMAT_NONE;
2655 _ImageUtil::GetResizedDimension(int srcWidth, int srcHeight, float dstWidth, float dstHeight,
2656 float &outWidth, float &outHeight)
2659 SysTryReturn(NID_MEDIA, (srcWidth > 0 && srcHeight > 0 && dstWidth > 0 && dstHeight > 0),
2660 E_INVALID_ARG, E_INVALID_ARG,
2661 "[E_INVALID_ARG] Dimensions should be greater than zero Source size(%d x %d), \
2662 Destination size(%f x %f)", srcWidth, srcHeight, dstWidth, dstHeight);
2664 double xRatio = Float(dstWidth).ToDouble() / Integer(srcWidth).ToDouble();
2665 double yRatio = Float(dstHeight).ToDouble() / Integer(srcHeight).ToDouble();
2667 if (xRatio >= 1.0 || yRatio >= 1.0)
2669 outWidth = Integer(srcWidth).ToFloat();
2670 outHeight = Integer(srcHeight).ToFloat();
2672 else if (xRatio < yRatio)
2674 outWidth = Double(srcWidth * yRatio).ToFloat();
2675 outHeight = dstHeight;
2679 outWidth = dstWidth;
2680 outHeight = Double(srcHeight * xRatio).ToFloat();