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_RGB565LE) || ( x == MEDIA_PIXEL_FORMAT_GRAY) \
47 || (x == MEDIA_PIXEL_FORMAT_BGRA8888) || (x == MEDIA_PIXEL_FORMAT_RGBA8888) \
48 || (x == MEDIA_PIXEL_FORMAT_BGR888) || (x == MEDIA_PIXEL_FORMAT_RGB888) \
49 || ( x == MEDIA_PIXEL_FORMAT_YUV444P) \
50 || (x == MEDIA_PIXEL_FORMAT_YUYV422) || (x == MEDIA_PIXEL_FORMAT_UYVY422) \
51 || (x == MEDIA_PIXEL_FORMAT_YUV420P) \
52 || (x == MEDIA_PIXEL_FORMAT_NV12) || (x == MEDIA_PIXEL_FORMAT_NV21))
54 #define IS_VALID_BUF(buf, format, w, h) \
55 (_ImageUtil::GetBufferSize(format, w, h) <= buf.GetCapacity())
59 MediaPixelFormat mediaPixelFmt;
64 static const _PixelFormatMap _PIXEL_FORMAT_MAP[] =
66 { MEDIA_PIXEL_FORMAT_RGB565LE, PIX_FMT_RGB565LE, 2 },
67 { MEDIA_PIXEL_FORMAT_BGRA8888, PIX_FMT_BGRA, 4 },
68 { MEDIA_PIXEL_FORMAT_RGBA8888, PIX_FMT_RGBA, 4 },
69 { MEDIA_PIXEL_FORMAT_RGB565BE, PIX_FMT_RGB565BE, 2 },
70 { MEDIA_PIXEL_FORMAT_RGB888, PIX_FMT_RGB24, 3 },
71 { MEDIA_PIXEL_FORMAT_BGR888, PIX_FMT_BGR24, 3 },
72 { MEDIA_PIXEL_FORMAT_YUV420P, PIX_FMT_YUV420P, 1.5 },
73 { MEDIA_PIXEL_FORMAT_YUV444P, PIX_FMT_YUV444P, 3 },
74 { MEDIA_PIXEL_FORMAT_YUYV422, PIX_FMT_YUYV422, 2 },
75 { MEDIA_PIXEL_FORMAT_UYVY422, PIX_FMT_UYVY422, 2 },
76 { MEDIA_PIXEL_FORMAT_NV12, PIX_FMT_NV12, 1.5 },
77 { MEDIA_PIXEL_FORMAT_NV12_TILE, PIX_FMT_NV12, 1.5 },
78 { MEDIA_PIXEL_FORMAT_NV21, PIX_FMT_NV21, 1.5 },
79 { MEDIA_PIXEL_FORMAT_GRAY, PIX_FMT_GRAY8, 1 }
82 static const int _BPP_RGB565 = 2;
83 static const int _BPP_RGB888 = 3;
84 static const int _BPP_ARGB8888 = 4;
85 static const int _BPP_YUV444 = 3;
86 static const float _BPP_YUV420 = 1.5;
87 static const float _BPP_NV12 = 1.5;
90 * Input is assumed to be 8888
91 * pDataIn => Input ARGB/BGRA/RGBA 8888 Buffer
92 * pDataOut => Output buffer, allocated by caller
93 * inWidth => Input Width
94 * inHeight => Input Height
95 * outWidth => Output Width
96 * outHeight => Output Height
99 _ImageUtil::Resize8888(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
109 byte* pOutput = pDataOut;
110 byte* pOut = pDataOut;
111 const byte* pIn = null;
113 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
114 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
115 "[E_OUT_OF_MEMORY] Could not allocate memory.");
117 /* Calculate X Scale factor */
118 scaleX = inWidth * 256 / outWidth;
120 /* Calculate Y Scale factor, aspect ratio is not maintained */
121 scaleY = inHeight * 256 / outHeight;
123 for (j = 0; j < outWidth; j++)
125 /* Get input index based on column scale factor */
127 /* To get more optimization, this is calculated once and
128 * is placed in a LUT and used for indexing
130 pColLUT [j] = ((j * scaleX) >> 8) * _BPP_ARGB8888;
135 for (i = 0; i < outHeight; i++)
137 /* Get input routWidth index based on routWidth scale factor */
138 iRow = (i * scaleY >> 8) * inWidth * _BPP_ARGB8888;
140 /* Loop could be unrolled for more optimization */
141 for (j = 0; j < (outWidth); j++)
143 /* Get input index based on column scale factor */
144 iIndex = iRow + pColLUT [j];
146 pIn = pDataIn + iIndex;
158 * Input is assumed to be RGB888
159 * pDataIn => Input RGB888 Buffer
160 * pDataOut => Output buffer, allocated by caller
161 * inWidth => Input Width
162 * inHeight => Input Height
163 * outWidth => Output Width
164 * outHeight => Output Height
167 _ImageUtil::ResizeRGB888(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
177 byte* pOutput = pDataOut;
178 byte* pOut = pDataOut;
179 const byte* pIn = null;
181 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
182 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
183 "[E_OUT_OF_MEMORY] Could not allocate memory.");
185 /* Calculate X Scale factor */
186 scaleX = inWidth * 256 / outWidth;
188 /* Calculate Y Scale factor, aspect ratio is not maintained */
189 scaleY = inHeight * 256 / outHeight;
191 for (j = 0; j < outWidth; j++)
193 /* Get input index based on column scale factor */
195 /* To get more optimization, this is calculated once and
196 * is placed in a LUT and used for indexing
198 pColLUT[j] = ((j * scaleX) >> 8) * _BPP_RGB888;
203 for (i = 0; i < outHeight; i++)
205 /* Get input routWidth index based on routWidth scale factor */
206 iRow = (i * scaleY >> 8) * inWidth * _BPP_RGB888;
208 /* Loop could be unrolled for more optimization */
209 for (j = 0; j < (outWidth); j++)
211 /* Get input index based on column scale factor */
212 iIndex = iRow + pColLUT [j];
213 pIn = pDataIn + iIndex;
225 * Input is assumed to be RGB565
226 * pDataIn => Input RGB565 Buffer
227 * pDataOut => Output RGB565 Buffer (memory is assumed to be already allocated)
228 * inWidth => Input Width
229 * inHeight => Input Height
230 * outWidth => Output Width
231 * outHeight => Output Height
234 _ImageUtil::ResizeRGB565(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
244 byte* pOutput = pDataOut;
245 byte* pOut = pDataOut;
246 const byte* pIn = null;
248 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
249 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
250 "[E_OUT_OF_MEMORY] Could not allocate memory.");
252 /* Calculate X Scale factor */
253 scaleX = inWidth * 256 / outWidth;
255 /* Calculate Y Scale factor, aspect ratio is not maintained */
256 scaleY = inHeight * 256 / outHeight;
258 for (j = 0; j < outWidth; j++)
260 /* Get input index based on column scale factor */
262 /* To get more optimization, this is calculated once and
263 * is placed in a LUT and used for indexing
265 pColLUT [j] = ((j * scaleX) >> 8) * _BPP_RGB565;
270 for (i = 0; i < outHeight; i++)
272 /* Get input row index based on row scale factor */
273 iRow = (i * scaleY >> 8) * inWidth * _BPP_RGB565;
275 /* Loop could be unrolled for more optimization */
276 for (j = 0; j < (outWidth); j++)
278 /* Get input index based on column scale factor */
279 iIndex = iRow + pColLUT [j];
281 pIn = pDataIn + iIndex;
291 * Input is assumed to be GRAY8
292 * pDataIn => Input GRAY8 Buffer
293 * pDataOut => Output GRAY8 Buffer (memory is assumed to be already allocated)
294 * inWidth => Input Width
295 * inHeight => Input Height
296 * outWidth => Output Width
297 * outHeight => Output Height
300 _ImageUtil::ResizeGray(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
310 byte* pOutput = pDataOut;
311 byte* pOut = pDataOut;
312 const byte* pIn = null;
314 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
315 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
316 "[E_OUT_OF_MEMORY] Could not allocate memory.");
318 /* Calculate X Scale factor */
319 scaleX = inWidth * 256 / outWidth;
321 /* Calculate Y Scale factor, aspect ratio is not maintained */
322 scaleY = inHeight * 256 / outHeight;
324 for (j = 0; j < outWidth; j++)
326 /* Get input index based on column scale factor */
328 /* To get more optimization, this is calculated once and
329 * is placed in a LUT and used for indexing
331 pColLUT [j] = ((j * scaleX) >> 8);
336 for (i = 0; i < outHeight; i++)
338 /* Get input row index based on row scale factor */
339 iRow = (i * scaleY >> 8) * inWidth;
341 /* Loop could be unrolled for more optimization */
342 for (j = 0; j < (outWidth); j++)
344 /* Get input index based on column scale factor */
345 iIndex = iRow + pColLUT [j];
347 pIn = pDataIn + iIndex;
356 * Input is assumed to be YUV444
357 * pDataIn => Input YUV444 Buffer
358 * pDataOut => Output buffer, allocated by caller
359 * inWidth => Input Width
360 * inHeight => Input Height
361 * outWidth => Output Width
362 * outHeight => Output Height
365 _ImageUtil::ResizeYUV444(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
375 int ipixelcount = inWidth * inHeight;
376 int opixelcount = outWidth * outHeight;
377 byte* pOutput = pDataOut;
381 const byte* pInY = null;
382 const byte* pInU = null;
383 const byte* pInV = null;
385 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
386 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
387 "[E_OUT_OF_MEMORY] Could not allocate memory.");
389 /* Calculate X Scale factor */
390 scaleX = inWidth * 256 / outWidth;
392 /* Calculate Y Scale factor, aspect ratio is not maintained */
393 scaleY = inHeight * 256 / outHeight;
395 for (j = 0; j < outWidth; j++)
397 /* Get input index based on column scale factor */
399 /* To get more optimization, this is calculated once and
400 * is placed in a LUT and used for indexing
402 pColLUT[j] = ((j * scaleX) >> 8);
406 pOutU = pOutY + opixelcount;
407 pOutV = pOutU + opixelcount;
410 pInU = pInY + ipixelcount;
411 pInV = pInU + ipixelcount;
413 for (i = 0; i < outHeight; i++)
415 /* Get input row index based on row scale factor */
416 iRow = (i * scaleY >> 8) * inWidth;
418 /* Loop could be unrolled for more optimization */
419 for (j = 0; j < outWidth; j++)
421 /* Get input index based on column scale factor */
422 iIndex = iRow + pColLUT [j];
424 *(pOutY++) = *(pInY + iIndex);
425 *(pOutU++) = *(pInU + iIndex);
426 *(pOutV++) = *(pInV + iIndex);
434 * Input is assumed to be either YUYV422 or UYVY422
435 * pDataIn => Input YUYV422 or UYVY422 Buffer
436 * pDataOut => Output buffer, allocated by caller
437 * inWidth => Input Width
438 * inHeight => Input Height
439 * outWidth => Output Width
440 * outHeight => Output Height
443 _ImageUtil::ResizeYUYV422(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
446 return Resize8888(pDataIn, pDataOut, inWidth/2, inHeight, outWidth/2, outHeight);
450 * Input is assumed to be YUV420P
451 * pDataIn => Input YUV420P Buffer
452 * pDataOut => Output buffer, allocated by caller
453 * inWidth => Input Width
454 * inHeight => Input Height
455 * outWidth => Output Width
456 * outHeight => Output Height
459 _ImageUtil::ResizeYUV420P(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
469 int ipixelcount = inWidth * inHeight;
470 int opixelcount = outWidth * outHeight;
471 byte* pOutput = pDataOut;
476 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
477 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
478 "[E_OUT_OF_MEMORY] Could not allocate memory.");
480 /* Calculate X Scale factor */
481 scaleX = inWidth * 256 / outWidth;
483 /* Calculate Y Scale factor, aspect ratio is not maintained */
484 scaleY = inHeight * 256 / outHeight;
486 for (j = 0; j < outWidth; j++)
488 /* Get input index based on column scale factor */
490 /* To get more optimization, this is calculated once and
491 * is placed in a LUT and used for indexing
493 pColLUT[j] = ((j * scaleX) >> 8);
498 for (i = 0; i < outHeight; i++)
500 /* Get input row index based on row scale factor */
501 iRow = (i * scaleY >> 8) * inWidth;
503 /* Loop could be unrolled for more optimization */
504 for (j = 0; j < (outWidth); j++)
506 /* Get input index based on column scale factor */
507 iIndex = iRow + pColLUT[j];
509 *pOutY++ = pDataIn[iIndex];
513 pOutU = pOutput + opixelcount;
514 pOutV = pOutU + (opixelcount/4);
516 for (i = 0; i < (outHeight + 1) / 2; i++)
518 /* Get input row index based on row scale factor */
519 iRow = (i * scaleY >> 8) * inWidth/2;
521 /* Loop could be unrolled for more optimization */
522 for (j = 0; j < (outWidth)/2; j++)
524 /* Get input index based on column scale factor */
525 iIndex = iRow + pColLUT[j];
527 *pOutU++ = pDataIn[iIndex + ipixelcount];
528 *pOutV++ = pDataIn[iIndex + ipixelcount + (ipixelcount/4)];
536 * Input is assumed to be NV12
537 * pDataIn => Input NV12 Buffer
538 * pDataOut => Output buffer, allocated by caller
539 * inWidth => Input Width
540 * inHeight => Input Height
541 * outWidth => Output Width
542 * outHeight => Output Height
545 _ImageUtil::ResizeNV12(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
555 int ipixelcount = inWidth * inHeight;
556 int opixelcount = outWidth * outHeight;
557 byte* pOutput = pDataOut;
561 std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
562 SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
563 "[E_OUT_OF_MEMORY] Could not allocate memory.");
565 /* Calculate X Scale factor */
566 scaleX = inWidth * 256 / outWidth;
568 /* Calculate Y Scale factor, aspect ratio is not maintained */
569 scaleY = inHeight * 256 / outHeight;
571 for (j = 0; j < outWidth; j++)
573 /* Get input index based on column scale factor */
575 /* To get more optimization, this is calculated once and
576 * is placed in a LUT and used for indexing
578 pColLUT[j] = ((j * scaleX) >> 8);
583 for (i = 0; i < outHeight; i++)
585 /* Get input row index based on row scale factor */
586 iRow = (i * scaleY >> 8) * inWidth;
588 /* Loop could be unrolled for more optimization */
589 for (j = 0; j < (outWidth); j++)
591 /* Get input index based on column scale factor */
592 iIndex = iRow + pColLUT[j];
594 *pOutY++ = pDataIn[iIndex];
598 pOutUV = pOutput + opixelcount;
600 for (i = 0; i < (outHeight + 1) / 2; i++)
602 /* Get input row index based on row scale factor */
603 iRow = (i * scaleY >> 8) * inWidth;
605 /* Loop could be unrolled for more optimization */
606 for (j = 0; j < (outWidth + 1)/2; j++)
608 /* Get input index based on column scale factor */
609 iIndex = iRow + (pColLUT[j] * 2);
611 *pOutUV++ = pDataIn[iIndex + ipixelcount];
612 *pOutUV++ = pDataIn[iIndex + ipixelcount + 1];
620 _ImageUtil::ResizeBuffer(const byte* pInBuf, MediaPixelFormat pixelFormat,
621 int srcWidth, int srcHeight, byte* pOutBuf, int dstWidth, int dstHeight)
623 result r = E_SUCCESS;
628 case MEDIA_PIXEL_FORMAT_RGBA8888:
630 case MEDIA_PIXEL_FORMAT_BGRA8888:
632 r = Resize8888(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
636 case MEDIA_PIXEL_FORMAT_RGB888:
638 r = ResizeRGB888(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
642 case MEDIA_PIXEL_FORMAT_RGB565LE:
644 r = ResizeRGB565(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
648 case MEDIA_PIXEL_FORMAT_GRAY:
650 r = ResizeGray(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
654 case MEDIA_PIXEL_FORMAT_YUV444P:
656 r = ResizeYUV444(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
660 case MEDIA_PIXEL_FORMAT_YUYV422:
662 case MEDIA_PIXEL_FORMAT_UYVY422:
664 r = ResizeYUYV422(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
668 case MEDIA_PIXEL_FORMAT_YUV420P:
670 r = ResizeYUV420P(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
674 case MEDIA_PIXEL_FORMAT_NV12:
676 case MEDIA_PIXEL_FORMAT_NV21:
678 r = ResizeNV12(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
683 r = E_UNSUPPORTED_FORMAT;
690 _ImageUtil::RotateBuffer(const byte* srcBuf, MediaPixelFormat pixelFormat,
691 int width, int height, byte* dstBuf, int& outWidth, int& outHeight,
692 ImageRotationType rotate)
694 result r = E_SUCCESS;
697 mm_util_img_format colorFormat = MM_UTIL_IMG_FMT_NUM;
698 mm_util_img_rotate_type rotation = MM_UTIL_ROTATE_NUM;
700 image_util_colorspace_e colorFormat = IMAGE_UTIL_COLORSPACE_RGB565;
701 image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
704 SysTryCatch(NID_MEDIA, width > 0 && height > 0, r = E_INVALID_ARG, E_INVALID_ARG,
705 "[E_INVALID_ARG] Invalid dimension: Should be greater than zero: (%d x %d)",
708 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
709 "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
711 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, width, height),
712 r = E_INVALID_ARG, E_INVALID_ARG,
713 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", width, height);
715 if (rotate == IMAGE_ROTATION_0)
717 int length = GetBufferSize(pixelFormat, width, height);
718 memcpy(dstBuf, srcBuf, length);
722 // Set output dimensions;
723 if ((rotate == IMAGE_ROTATION_90) || (rotate == IMAGE_ROTATION_270))
736 case MEDIA_PIXEL_FORMAT_GRAY:
740 byte* pSrcBuf = (byte *)srcBuf;
741 byte* pDstBuf = (byte *)dstBuf;
742 byte* pTmpOutCol = null;
746 case IMAGE_ROTATION_90:
748 // Copying from all source rows to destination columns.
749 for (rowCount = 0; rowCount < height; rowCount++)
751 // pTmpOutCol points to the top of the output column being filled.
752 pTmpOutCol = pDstBuf + (outWidth - 1) - rowCount;
754 for (colCount = 0; colCount < width; colCount++)
756 *pTmpOutCol = *pSrcBuf++;
757 pTmpOutCol += outWidth;
762 case IMAGE_ROTATION_180:
764 // Copying all source rows to destination columns.
765 for (rowCount = 0; rowCount < height; rowCount++)
767 // pTmpOutCol points to the bottom of the column being filled.
768 pTmpOutCol = pDstBuf + ((outWidth * outHeight) - 1) - (rowCount * outWidth);
770 for (colCount = 0; colCount < width; colCount++)
772 *pTmpOutCol-- = *pSrcBuf++;
777 case IMAGE_ROTATION_270:
779 // Copying all source rows to destination columns.
780 for (rowCount = 0; rowCount < height; rowCount++)
782 // pTmpOutCol points to the bottom of the column being filled.
783 pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
785 for (colCount = 0; colCount < width; colCount++)
787 *pTmpOutCol = *pSrcBuf++;
788 pTmpOutCol -= outWidth;
798 case MEDIA_PIXEL_FORMAT_RGB888:
802 byte* pSrcBuf = (byte *)srcBuf;
803 byte* pDstBuf = (byte *)dstBuf;
804 byte* pTmpOutCol = null;
808 case IMAGE_ROTATION_90:
810 // Copying from all source rows to destination columns.
811 for (rowCount = 0; rowCount < height; rowCount++)
813 // pTmpOutCol points to the top of the output column being filled.
814 pTmpOutCol = pDstBuf + outWidth * 3 - 1 - rowCount * 3;
816 for (colCount = 0; colCount < width / 2; colCount++)
818 pTmpOutCol = pTmpOutCol - 2;
819 *pTmpOutCol++ = *pSrcBuf++; // copied R byte
820 *pTmpOutCol++ = *pSrcBuf++; // copied G byte
821 *pTmpOutCol = *pSrcBuf++; // copied B byte
822 pTmpOutCol += outWidth * 3;
824 pTmpOutCol = pTmpOutCol - 2;
825 *pTmpOutCol++ = *pSrcBuf++; // copied R byte
826 *pTmpOutCol++ = *pSrcBuf++; // copied G byte
827 *pTmpOutCol = *pSrcBuf++; // copied B byte
828 pTmpOutCol += outWidth * 3;
833 case IMAGE_ROTATION_180:
835 // Copying all source rows to destination columns.
836 for (rowCount = 0; rowCount < height; rowCount++)
838 // pTmpOutCol points to the bottom of the column being filled.
839 pTmpOutCol = pDstBuf + ((outWidth * outHeight * 3) - 1) - (rowCount * outWidth * 3);
841 for (colCount = 0; colCount < width / 2; colCount++)
843 pTmpOutCol -= 2; // move to R byte of pixel
844 *pTmpOutCol++ = *pSrcBuf++; // copied R
845 *pTmpOutCol++ = *pSrcBuf++; // copied G
846 *pTmpOutCol = *pSrcBuf++; // copied B
847 pTmpOutCol -= 3; // move to next pixel to get copied
849 pTmpOutCol -= 2; // move to R byte of pixel
850 *pTmpOutCol++ = *pSrcBuf++; // copied R
851 *pTmpOutCol++ = *pSrcBuf++; // copied G
852 *pTmpOutCol = *pSrcBuf++; // copied B
853 pTmpOutCol -= 3; // move to next pixel to get copied
858 case IMAGE_ROTATION_270:
860 // Copying all source rows to destination columns.
861 for (rowCount = 0; rowCount < height; rowCount++)
863 // pTmpOutCol points to the bottom of the column being filled.
864 pTmpOutCol = pDstBuf + (outWidth * 3 * (outHeight - 1)) + rowCount * 3;
866 for (colCount = 0; colCount < width / 2; colCount++)
868 *pTmpOutCol++ = *pSrcBuf++; // copied R
869 *pTmpOutCol++ = *pSrcBuf++; // copied G
870 *pTmpOutCol = *pSrcBuf++; // copied B
871 pTmpOutCol -= 2; // take pointer back to R
872 pTmpOutCol -= outWidth * 3;
874 *pTmpOutCol++ = *pSrcBuf++; // copied R
875 *pTmpOutCol++ = *pSrcBuf++; // copied G
876 *pTmpOutCol = *pSrcBuf++; // copied B
877 pTmpOutCol -= 2; // take pointer back to R
878 pTmpOutCol -= outWidth * 3;
888 case MEDIA_PIXEL_FORMAT_RGB565LE:
892 case IMAGE_ROTATION_90:
896 unsigned short* pSrcBuf = (unsigned short *)srcBuf;
897 unsigned short* pDstBuf = (unsigned short *)dstBuf;
898 unsigned short* pTmpOutCol = null;
900 // Copying from all source rows to destination columns.
901 for (rowCount = 0; rowCount < height; rowCount++)
903 // pTmpOutCol points to the top of the output column being filled.
904 pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
906 for (colCount = 0; colCount < width; colCount++)
908 *pTmpOutCol = *pSrcBuf++;
909 pTmpOutCol += outWidth;
915 case IMAGE_ROTATION_180:
918 unsigned short* pSrcBuf = (unsigned short *)srcBuf;
919 unsigned short* pDstBuf = (unsigned short *)dstBuf;
921 // pDstBuf points to the bottom right corner of the output image.
922 pDstBuf += (outWidth * outHeight) - 1;
924 for (pixCount = (width * height); pixCount > 0; pixCount--)
926 *pDstBuf = *pSrcBuf++;
932 case IMAGE_ROTATION_270:
936 unsigned short* pSrcBuf = (unsigned short *)srcBuf;
937 unsigned short* pDstBuf = (unsigned short *)dstBuf;
938 unsigned short* pTmpOutCol = null;
940 // Copying all source rows to destination columns.
941 for (rowCount = 0; rowCount < height; rowCount++)
943 // pTmpOutCol points to the bottom of the column being filled.
944 pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
946 for (colCount = 0; colCount < width; colCount++)
948 *pTmpOutCol = *pSrcBuf++;
949 pTmpOutCol -= outWidth;
960 case MEDIA_PIXEL_FORMAT_RGBA8888:
962 case MEDIA_PIXEL_FORMAT_BGRA8888:
966 case IMAGE_ROTATION_90:
970 unsigned int* pSrcBuf = (unsigned int *)srcBuf;
971 unsigned int* pDstBuf = (unsigned int *)dstBuf;
972 unsigned int* pTmpOutCol = null;
974 // Copying from all source rows to destination columns.
975 for (rowCount = 0; rowCount < height; rowCount++)
977 // pTmpOutCol points to the top of the output column being filled.
978 pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
980 for (colCount = 0; colCount < width; colCount++)
982 *pTmpOutCol = *pSrcBuf++;
983 pTmpOutCol += outWidth;
989 case IMAGE_ROTATION_180:
992 unsigned int* pSrcBuf = (unsigned int *)srcBuf;
993 unsigned int* pDstBuf = (unsigned int *)dstBuf;
995 // pDstBuf points to the bottom right corner of the output image.
996 pDstBuf += (outWidth * outHeight) - 1;
998 for (pixCount = (width * height); pixCount > 0; pixCount--)
1000 *pDstBuf = *pSrcBuf++;
1006 case IMAGE_ROTATION_270:
1010 unsigned int* pSrcBuf = (unsigned int *)srcBuf;
1011 unsigned int* pDstBuf = (unsigned int *)dstBuf;
1012 unsigned int* pTmpOutCol = null;
1014 // Copying all source rows to destination columns.
1015 for (rowCount = 0; rowCount < height; rowCount++)
1017 // pTmpOutCol points to the bottom of the column being filled.
1018 pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
1020 for (colCount = 0; colCount < width; colCount++)
1022 *pTmpOutCol = *pSrcBuf++;
1023 pTmpOutCol -= outWidth;
1034 case MEDIA_PIXEL_FORMAT_YUV420P:
1038 byte* pDstY = (byte *)dstBuf;
1039 byte* pDstU = pDstY + outWidth * outHeight;
1040 byte* pDstV = pDstU + (outWidth / 2) * (outHeight / 2);
1042 byte* pSrcY = (byte *) srcBuf;
1043 byte* pSrcU = pSrcY + width * height;
1044 byte* pSrcV = pSrcU + (width /2) * ( height / 2);
1045 byte* pTmpOutColY = null;
1046 byte* pTmpOutColU = null;
1047 byte* pTmpOutColV = null;
1050 case IMAGE_ROTATION_90:
1052 // Copying from all source rows to destination columns of Y plane.
1053 for (rowCount = 0; rowCount < height / 2; rowCount++)
1055 // pTmpOutCol points to the top of the output column being filled.
1056 pTmpOutColU = pDstU + (outWidth / 2) - 1 - rowCount;
1057 pTmpOutColV = pDstV + (outWidth / 2) - 1 - rowCount;
1058 pTmpOutColY = pDstY + outWidth - 1 - rowCount;
1059 for (colCount = 0; colCount < width / 2; colCount++)
1061 *pTmpOutColU = *pSrcU++;
1062 pTmpOutColU += outWidth / 2;
1063 *pTmpOutColV = *pSrcV++;
1064 pTmpOutColV += outWidth / 2;
1065 *pTmpOutColY = *pSrcY++;
1066 pTmpOutColY += outWidth;
1068 for (colCount = width / 2; colCount < width; colCount++)
1070 *pTmpOutColY = *pSrcY++;
1071 pTmpOutColY += outWidth;
1074 for (rowCount = height / 2; rowCount < height; rowCount++)
1076 pTmpOutColY = pDstY + outWidth - 1 - rowCount;
1077 for (colCount = 0; colCount < width; colCount++)
1079 *pTmpOutColY = *pSrcY++;
1080 pTmpOutColY += outWidth;
1085 case IMAGE_ROTATION_180:
1087 // Copying from all source rows to destination columns of Y plane.
1088 pTmpOutColY = pDstY + outWidth * outHeight - 1;
1089 pTmpOutColU = pDstU + (outWidth / 2) * (outHeight / 2) - 1;
1090 pTmpOutColV = pDstV + (outWidth / 2) * (outHeight / 2) - 1;
1091 for (colCount = 0; colCount < (outWidth / 2 * outHeight / 2); colCount++)
1093 *pTmpOutColY-- = *pSrcY++;
1094 *pTmpOutColU-- = *pSrcU++;
1095 *pTmpOutColV-- = *pSrcV++;
1097 for (colCount = (outWidth / 2 * outHeight / 2); colCount < (outWidth * outHeight); colCount++)
1099 *pTmpOutColY-- = *pSrcY++;
1103 case IMAGE_ROTATION_270:
1106 // Copying from all source rows to destination columns of Y plane.
1107 for (rowCount = 0; rowCount < height / 2; rowCount++)
1109 // pTmpOutCol points to the top of the output column being filled.
1110 pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
1111 pTmpOutColU = pDstU + (outWidth / 2) * (outHeight / 2 - 1) + rowCount;
1112 pTmpOutColV = pDstV + (outWidth / 2) * (outHeight / 2 - 1) + rowCount;
1113 for (colCount = 0; colCount < width / 2; colCount++)
1115 *pTmpOutColY = *pSrcY++;
1116 pTmpOutColY -= outWidth;
1117 *pTmpOutColU = *pSrcU++;
1118 pTmpOutColU -= outWidth / 2;
1119 *pTmpOutColV = *pSrcV++;
1120 pTmpOutColV -= outWidth / 2;
1122 for (colCount = width / 2; colCount < width; colCount++)
1124 *pTmpOutColY = *pSrcY++;
1125 pTmpOutColY -= outWidth;
1128 for (rowCount = height / 2; rowCount < height; rowCount++)
1130 pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
1131 // pTmpOutCol points to the top of the output column being filled.
1132 for (colCount = 0; colCount < width; colCount++)
1134 *pTmpOutColY = *pSrcY++;
1135 pTmpOutColY -= outWidth;
1145 case MEDIA_PIXEL_FORMAT_NV12:
1147 case MEDIA_PIXEL_FORMAT_NV21:
1151 byte* pDstY = (byte *)dstBuf;
1152 short* pDstUV = (short* )(pDstY + outWidth * outHeight);
1154 byte* pSrcY = (byte* ) srcBuf;
1155 short* pSrcUV = (short* )(pSrcY + width * height);
1156 byte* pTmpOutColY = null;
1157 short* pTmpOutColUV = null;
1161 case IMAGE_ROTATION_90:
1163 // Copying from all source rows to destination columns of Y plane.
1164 for (rowCount = 0; rowCount < height / 2; rowCount++)
1166 // pTmpOutCol points to the top of the output column being filled.
1167 pTmpOutColUV = pDstUV + (outWidth / 2) - 1 - rowCount;
1168 pTmpOutColY = pDstY + outWidth - 1 - rowCount;
1169 for (colCount = 0; colCount < width / 2; colCount++)
1171 *pTmpOutColUV = *pSrcUV++;
1172 pTmpOutColUV += outWidth / 2 ;
1173 *pTmpOutColY = *pSrcY++;
1174 pTmpOutColY += outWidth;
1176 for (colCount = width / 2; colCount < width; colCount++)
1178 *pTmpOutColY = *pSrcY++;
1179 pTmpOutColY += outWidth;
1182 for (rowCount = height / 2; rowCount < height; rowCount++)
1184 // pTmpOutCol points to the top of the output column being filled.
1185 pTmpOutColY = pDstY + outWidth - 1 - rowCount;
1186 for (colCount = 0; colCount < width; colCount++)
1188 *pTmpOutColY = *pSrcY++;
1189 pTmpOutColY += outWidth;
1194 case IMAGE_ROTATION_180:
1196 // Copying from all source rows to destination columns of Y plane.
1197 pTmpOutColY = pDstY + outWidth * outHeight - 1;
1198 pTmpOutColUV = pDstUV + (outWidth / 2) * (outHeight / 2) - 1;
1199 for (colCount = 0; colCount < (outWidth / 2 * outHeight / 2); colCount++)
1201 *pTmpOutColY-- = *pSrcY++;
1202 *pTmpOutColUV-- = *pSrcUV++;
1204 for (colCount = (outWidth / 2 * outHeight / 2); colCount < outWidth * outHeight; colCount++)
1206 *pTmpOutColY-- = *pSrcY++;
1210 case IMAGE_ROTATION_270:
1212 // Copying from all source rows to destination columns of Y plane.
1213 for (rowCount = 0; rowCount < height / 2; rowCount++)
1215 // pTmpOutCol points to the top of the output column being filled.
1216 pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
1217 pTmpOutColUV = pDstUV + (outWidth / 2) * (outHeight / 2 - 1) + rowCount;
1218 for (colCount = 0; colCount < width / 2; colCount++)
1220 *pTmpOutColY = *pSrcY++;
1221 pTmpOutColY -= outWidth;
1222 *pTmpOutColUV = *pSrcUV++;
1223 pTmpOutColUV -= outWidth / 2;
1225 for (colCount = width / 2; colCount < width; colCount++)
1227 *pTmpOutColY = *pSrcY++;
1228 pTmpOutColY -= outWidth;
1231 for (rowCount = height / 2; rowCount < height; rowCount++)
1233 // pTmpOutCol points to the top of the output column being filled.
1234 pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
1235 for (colCount = 0; colCount < width; colCount++)
1237 *pTmpOutColY = *pSrcY++;
1238 pTmpOutColY -= outWidth;
1248 case MEDIA_PIXEL_FORMAT_YUV444P:
1252 byte* pDstY = (byte *)dstBuf;
1253 byte* pDstU = pDstY + outWidth * outHeight;
1254 byte* pDstV = pDstU + outWidth * outHeight;
1256 byte* pSrcY = (byte *) srcBuf;
1257 byte* pSrcU = pSrcY + width * height;
1258 byte* pSrcV = pSrcU + width * height;
1259 byte* pTmpOutColY = null;
1260 byte* pTmpOutColU = null;
1261 byte* pTmpOutColV = null;
1265 case IMAGE_ROTATION_90:
1267 // Copying from all source rows to destination columns of Y plane.
1268 for (rowCount = 0; rowCount < height; rowCount++)
1270 // pTmpOutCol points to the top of the output column being filled.
1271 pTmpOutColU = pDstU + outWidth - 1 - rowCount;
1272 pTmpOutColV = pDstV + outWidth - 1 - rowCount;
1273 pTmpOutColY = pDstY + outWidth - 1 - rowCount;
1274 for (colCount = 0; colCount < width / 2; colCount++)
1276 *pTmpOutColU = *pSrcU++;
1277 pTmpOutColU += outWidth;
1278 *pTmpOutColV = *pSrcV++;
1279 pTmpOutColV += outWidth;
1280 *pTmpOutColY = *pSrcY++;
1281 pTmpOutColY += outWidth;
1283 *pTmpOutColU = *pSrcU++;
1284 pTmpOutColU += outWidth;
1285 *pTmpOutColV = *pSrcV++;
1286 pTmpOutColV += outWidth;
1287 *pTmpOutColY = *pSrcY++;
1288 pTmpOutColY += outWidth;
1293 case IMAGE_ROTATION_180:
1295 // Copying from all source rows to destination columns of Y plane.
1296 pTmpOutColY = pDstY + outWidth * outHeight - 1;
1297 pTmpOutColU = pDstU + outWidth * outHeight - 1;
1298 pTmpOutColV = pDstV + outWidth * outHeight - 1;
1299 for (colCount = (outWidth * outHeight); colCount > 0; colCount--)
1301 *pTmpOutColY-- = *pSrcY++;
1302 *pTmpOutColU-- = *pSrcU++;
1303 *pTmpOutColV-- = *pSrcV++;
1307 case IMAGE_ROTATION_270:
1309 // Copying from all source rows to destination columns of Y plane.
1310 for (rowCount = 0; rowCount < height; rowCount++)
1312 // pTmpOutCol points to the top of the output column being filled.
1313 pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
1314 pTmpOutColU = pDstU + (outWidth * (outHeight - 1)) + rowCount;
1315 pTmpOutColV = pDstV + (outWidth * (outHeight - 1)) + rowCount;
1316 for (colCount = 0; colCount < width / 2; colCount++)
1318 *pTmpOutColY = *pSrcY++;
1319 pTmpOutColY -= outWidth;
1320 *pTmpOutColU = *pSrcU++;
1321 pTmpOutColU -= outWidth;
1322 *pTmpOutColV = *pSrcV++;
1323 pTmpOutColV -= outWidth;
1325 *pTmpOutColY = *pSrcY++;
1326 pTmpOutColY -= outWidth;
1327 *pTmpOutColU = *pSrcU++;
1328 pTmpOutColU -= outWidth;
1329 *pTmpOutColV = *pSrcV++;
1330 pTmpOutColV -= outWidth;
1340 case MEDIA_PIXEL_FORMAT_YUYV422:
1344 byte* pSrcBuf = const_cast<byte*>(srcBuf);
1345 byte* pDstBuf = dstBuf;
1346 byte* pTmpOutCol = null;
1347 byte* pTmpOut = null;
1351 case IMAGE_ROTATION_90:
1353 pTmpOutCol = pDstBuf + (outWidth * 2);
1354 // Copying from all source rows to destination columns.
1355 for (rowCount = 0; rowCount < height; rowCount += 2)
1357 // pTmpOutCol points to the top of the output column being filled.
1359 pTmpOut = pTmpOutCol;
1360 pSrcBuf = const_cast<byte*>(srcBuf) + (width * 2 * rowCount);
1361 for (colCount = 0; colCount < width / 2 ; colCount++)
1364 y0 u0 y1 v1 y2 u2 y0 v1
1366 y2 u2 y3 v3 y3 u2 y1 v1
1368 pTmpOut[0] = pSrcBuf[(width * 2)]; // copied y2
1369 pTmpOut[1] = pSrcBuf[(width * 2) + 1]; // copied u2
1370 pTmpOut[2] = pSrcBuf[0]; // copied y0
1371 pTmpOut[3] = pSrcBuf[3]; // copied v1
1372 pTmpOut += outWidth * 2;
1374 pTmpOut[0] = pSrcBuf[(width * 2) + 2]; // copied y3
1375 pTmpOut[1] = pSrcBuf[(width * 2) + 1]; // copied u2
1376 pTmpOut[2] = pSrcBuf[2]; // copied y1
1377 pTmpOut[3] = pSrcBuf[3]; // copied v1
1378 pTmpOut += outWidth * 2;
1385 case IMAGE_ROTATION_180:
1387 // Copying all source rows to destination rows in reverse.
1388 // pTmpOut points to the end of last row: u0y1 v1y0
1389 pTmpOut = pDstBuf + (outWidth * outHeight * 2) - 4;
1390 for (rowCount = 0; rowCount < height; rowCount++)
1392 for (colCount = 0; colCount < width / 2; colCount++)
1395 y0 u0 y1 v1 => y1 u1 y0 v0
1397 pTmpOut[0] = pSrcBuf[2]; // copied y1
1398 pTmpOut[1] = pSrcBuf[1]; // copied u0
1399 pTmpOut[2] = pSrcBuf[0]; // copied y0
1400 pTmpOut[3] = pSrcBuf[3]; // copied v1
1407 case IMAGE_ROTATION_270:
1409 // Copying all source rows to destination columns.
1410 pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1) * 2);
1411 for (rowCount = 0; rowCount < height; rowCount += 2)
1413 pTmpOut = pTmpOutCol;
1414 pSrcBuf = const_cast<byte*>(srcBuf) + (width * 2 * rowCount);
1415 // pTmpOutCol points to the bottom of the column being filled.
1416 for (colCount = 0; colCount < width / 2; colCount++)
1419 y0 u0 y1 v1 y1 u0 y3 v3
1421 y2 u2 y3 v3 y0 u0 y2 v3
1423 pTmpOut[0] = pSrcBuf[0]; // copied y0
1424 pTmpOut[1] = pSrcBuf[1]; // copied u0
1425 pTmpOut[2] = pSrcBuf[(width * 2) + 2]; // copied y3
1426 pTmpOut[3] = pSrcBuf[(width * 2) + 3]; // copied v3
1427 pTmpOut -= outWidth * 2;
1429 pTmpOut[0] = pSrcBuf[2]; // copied y1
1430 pTmpOut[1] = pSrcBuf[1]; // copied u0
1431 pTmpOut[2] = pSrcBuf[(width * 2)]; // copied y2
1432 pTmpOut[3] = pSrcBuf[(width * 2) + 3]; // copied v3
1433 pTmpOut -= outWidth * 2;
1448 case MEDIA_PIXEL_FORMAT_UYVY422:
1452 byte* pSrcBuf = const_cast<byte*>(srcBuf);
1453 byte* pDstBuf = dstBuf;
1454 byte* pTmpOutCol = null;
1455 byte* pTmpOut = null;
1459 case IMAGE_ROTATION_90:
1461 pTmpOutCol = pDstBuf + (outWidth * 2);
1462 // Copying from all source rows to destination columns.
1463 for (rowCount = 0; rowCount < height; rowCount += 2)
1465 // pTmpOutCol points to the top of the output column being filled.
1467 pTmpOut = pTmpOutCol;
1468 pSrcBuf = const_cast<byte*>(srcBuf) + (width * 2 * rowCount);
1469 for (colCount = 0; colCount < width / 2 ; colCount++)
1472 u0 y0 v1 y1 u2 y2 v1 y0
1474 u2 y2 v3 y3 u2 y3 v1 y1
1477 pTmpOut[0] = pSrcBuf[(width * 2)]; // copied u2
1478 pTmpOut[1] = pSrcBuf[(width * 2) + 1]; // copied y2
1479 pTmpOut[2] = pSrcBuf[2]; // copied v1
1480 pTmpOut[3] = pSrcBuf[1]; // copied y0
1481 pTmpOut += outWidth * 2;
1483 pTmpOut[0] = pSrcBuf[(width * 2)]; // copied u2
1484 pTmpOut[1] = pSrcBuf[(width * 2) + 3]; // copied y3
1485 pTmpOut[2] = pSrcBuf[2]; // copied v1
1486 pTmpOut[3] = pSrcBuf[3]; // copied y1
1487 pTmpOut += outWidth * 2;
1494 case IMAGE_ROTATION_180:
1496 // Copying all source rows to destination rows in reverse.
1497 // pTmpOut points to the end of last row: u0y1 v1y0
1498 pTmpOut = pDstBuf + (outWidth * outHeight * 2) - 4;
1499 for (rowCount = 0; rowCount < height; rowCount++)
1501 for (colCount = 0; colCount < width / 2; colCount++)
1504 u0 y0 v1 y1 => u0 y1 v1 y0
1506 pTmpOut[0] = pSrcBuf[0]; // copied u0
1507 pTmpOut[1] = pSrcBuf[3]; // copied y1
1508 pTmpOut[2] = pSrcBuf[2]; // copied v1
1509 pTmpOut[3] = pSrcBuf[1]; // copied y0
1516 case IMAGE_ROTATION_270:
1518 // Copying all source rows to destination columns.
1519 pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1) * 2);
1520 for (rowCount = 0; rowCount < height; rowCount += 2)
1522 pTmpOut = pTmpOutCol;
1523 pSrcBuf = const_cast<byte*>(srcBuf) + (width * 2 * rowCount);
1524 // pTmpOutCol points to the bottom of the column being filled.
1525 for (colCount = 0; colCount < width / 2; colCount++)
1528 u0 y0 v1 y1 u0 y1 v3 y3
1530 u2 y2 v3 y3 u0 y0 v3 y2
1533 pTmpOut[0] = pSrcBuf[0]; // copied u0
1534 pTmpOut[1] = pSrcBuf[1]; // copied y0
1535 pTmpOut[2] = pSrcBuf[(width * 2) + 2]; // copied v3
1536 pTmpOut[3] = pSrcBuf[(width * 2) + 1]; // copied y2
1537 pTmpOut -= outWidth * 2;
1539 pTmpOut[0] = pSrcBuf[0]; // copied u0
1540 pTmpOut[1] = pSrcBuf[3]; // copied y1
1541 pTmpOut[2] = pSrcBuf[(width * 2) + 2]; // copied v3
1542 pTmpOut[3] = pSrcBuf[(width * 2) + 3]; // copied y3
1543 pTmpOut -= outWidth * 2;
1561 colorFormat = _SlpUtil::ToMmUtilImgFormat(pixelFormat);
1562 rotation = _SlpUtil::ToMmUtilRotateType(rotate);
1564 ret = mm_util_rotate_image((unsigned char*)srcBuf, width, height, colorFormat,
1565 (unsigned char*)dstBuf, (unsigned int *)&outWidth, (unsigned int *)&outHeight, rotation);
1567 SysTryCatch(NID_MEDIA, ret == 0, r = E_SYSTEM, E_SYSTEM,
1568 "mm_util_rotate_image: %0x", ret);
1572 colorFormat = _SlpUtil::ToColorspace(pixelFormat);
1573 rotation = _SlpUtil::ToRotation(rotate);
1575 ret = image_util_transform(dstBuf, &outWidth, &outHeight, rotation,
1576 srcBuf, width, height, colorFormat);
1578 SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
1579 "[E_SYSTEM] util_transform failed: %0x", ret);
1592 _ImageUtil::FlipBuffer(const byte* srcBuf, MediaPixelFormat pixelFormat,
1593 int width, int height,
1594 byte* dstBuf, ImageFlipType flip)
1596 result r = E_SUCCESS;
1599 mm_util_img_format colorFormat = MM_UTIL_IMG_FMT_NUM;
1600 mm_util_img_rotate_type rotation = MM_UTIL_ROTATE_NUM;
1602 unsigned int outWidth = 0;
1603 unsigned int outHeight = 0;
1605 image_util_colorspace_e colorFormat = IMAGE_UTIL_COLORSPACE_RGB565;
1606 image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
1611 SysTryCatch(NID_MEDIA, width > 0 && height > 0, r = E_INVALID_ARG, E_INVALID_ARG,
1612 "[E_INVALID_ARG] Invalid dimension: Should be greater than zero: (%d x %d)",
1615 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
1616 "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
1618 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, width, height),
1619 r = E_INVALID_ARG, E_INVALID_ARG,
1620 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", width, height);
1622 if (flip == IMAGE_FLIP_NONE)
1624 int length = GetBufferSize(pixelFormat, width, height);
1625 memcpy(dstBuf, srcBuf, length);
1629 // Set output dimensions;
1633 switch (pixelFormat)
1635 case MEDIA_PIXEL_FORMAT_GRAY:
1637 if (flip == IMAGE_FLIP_HORIZONTAL)
1641 byte* pSrcBuf = (byte *)srcBuf;
1642 byte* pDstBuf = (byte *)dstBuf;
1643 // pTmpOutRow points to last column of first row of destination.
1644 byte* pTmpOutRow = pDstBuf + width - 1;
1646 for (rowCount = 0; rowCount < height; rowCount++)
1648 for (colCount = 0; colCount < width; colCount++)
1650 *pTmpOutRow-- = *pSrcBuf++; // copy source row in reverse to destination.
1652 pTmpOutRow += (2 * outWidth);
1658 byte* pSrcBuf = (byte *)srcBuf;
1659 byte* pDstBuf = (byte *)dstBuf;
1660 // pTmpOutRow points to the start of last row in destination buffer.
1661 byte* pTmpOutRow = pDstBuf + (width * (height - 1));
1663 for (rowCount = 0; rowCount < height; rowCount++)
1665 // copy one row worth of data.
1666 memcpy(pTmpOutRow, pSrcBuf, sizeof(byte) * width);
1667 pTmpOutRow -= width; // go to one higher row.
1668 pSrcBuf += width; // go to next row.
1673 case MEDIA_PIXEL_FORMAT_RGB565LE:
1675 if (flip == IMAGE_FLIP_HORIZONTAL)
1679 unsigned short* pSrcBuf = (unsigned short *)srcBuf;
1680 unsigned short* pDstBuf = (unsigned short *)dstBuf;
1681 // pTmpOutRow points to last column of first row of destination.
1682 unsigned short* pTmpOutRow = pDstBuf + width - 1;
1684 for (rowCount = 0; rowCount < height; rowCount++)
1686 for (colCount = 0; colCount < width; colCount++)
1688 *pTmpOutRow-- = *pSrcBuf++; // copy source row in reverse to destination.
1690 pTmpOutRow += (2 * outWidth);
1696 unsigned short* pSrcBuf = (unsigned short *)srcBuf;
1697 unsigned short* pDstBuf = (unsigned short *)dstBuf;
1698 // pTmpOutRow points to the start of last row in destination buffer.
1699 unsigned short* pTmpOutRow = pDstBuf + (width * (height - 1));
1701 for (rowCount = 0; rowCount < height; rowCount++)
1703 // copy one row worth of data.
1704 memcpy(pTmpOutRow, pSrcBuf, sizeof(unsigned short) * width);
1705 pTmpOutRow -= width; // go to one higher row.
1706 pSrcBuf += width; // go to next row.
1711 case MEDIA_PIXEL_FORMAT_RGB888:
1713 if (flip == IMAGE_FLIP_HORIZONTAL)
1717 byte* pSrcBuf = (byte *)srcBuf;
1718 byte* pDstBuf = (byte *)dstBuf;
1719 // pTmpOutRow points to last column of first row of destination.
1720 byte* pTmpOutRow = NULL;// pDstBuf + width * 3;
1722 for (rowCount = 0; rowCount < height; rowCount++)
1724 pTmpOutRow = pDstBuf + (rowCount + 1) * width * 3 - 3;
1725 for (colCount = 0; colCount < width; colCount++)
1727 *pTmpOutRow++ = *pSrcBuf++; // copy source row in reverse to destination.
1728 *pTmpOutRow++ = *pSrcBuf++; // copy source row in reverse to destination.
1729 *pTmpOutRow = *pSrcBuf++; // copy source row in reverse to destination.
1737 byte* pSrcBuf = (byte *)srcBuf;
1738 byte* pDstBuf = (byte *)dstBuf;
1739 // pTmpOutRow points to the start of last row in destination buffer.
1740 byte* pTmpOutRow = pDstBuf + (width * 3 * (height - 1));
1742 for (rowCount = 0; rowCount < height; rowCount++)
1744 // copy one row worth of data.
1745 memcpy(pTmpOutRow, pSrcBuf, sizeof(byte) * 3 * width);
1746 pTmpOutRow -= width*3; // go to one higher row.
1747 pSrcBuf += width*3; // go to next row.
1752 case MEDIA_PIXEL_FORMAT_RGBA8888:
1754 case MEDIA_PIXEL_FORMAT_BGRA8888:
1756 if (flip == IMAGE_FLIP_HORIZONTAL)
1760 unsigned int* pSrcBuf = (unsigned int *)srcBuf;
1761 unsigned int* pDstBuf = (unsigned int *)dstBuf;
1762 // pTmpOutRow points to last column of first row of destination.
1763 unsigned int* pTmpOutRow = pDstBuf + width - 1;
1765 for (rowCount = 0; rowCount < height; rowCount++)
1767 for (colCount = 0; colCount < width; colCount++)
1769 *pTmpOutRow-- = *pSrcBuf++; // copy source row in reverse to destination.
1771 pTmpOutRow += (2 * outWidth);
1777 unsigned int* pSrcBuf = (unsigned int *)srcBuf;
1778 unsigned int* pDstBuf = (unsigned int *)dstBuf;
1779 // pTmpOutRow points to the start of last row in destination buffer.
1780 unsigned int* pTmpOutRow = pDstBuf + (width * (height - 1));
1782 for (rowCount = 0; rowCount < height; rowCount++)
1784 // copy one row worth of data.
1785 memcpy(pTmpOutRow, pSrcBuf, sizeof(unsigned int) * width);
1786 pTmpOutRow -= width; // go to one higher row.
1787 pSrcBuf += width; // go to next row.
1792 case MEDIA_PIXEL_FORMAT_YUV420P:
1794 byte* pDstY = (byte *)dstBuf;
1795 byte* pDstU = pDstY + width * height;
1796 byte* pDstV = pDstU + (width / 2) * (height / 2);
1798 byte* pSrcY = (byte *) srcBuf;
1799 byte* pSrcU = pSrcY + width * height;
1800 byte* pSrcV = pSrcU + (width / 2) * ( height / 2);
1801 byte* pTmpOutY = null;
1802 byte* pTmpOutU = null;
1803 byte* pTmpOutV = null;
1805 if (flip == IMAGE_FLIP_HORIZONTAL)
1809 // pTmpOut* points to last column of first row of destination.
1810 pTmpOutY = pDstY + width - 1;
1811 pTmpOutU = pDstU + width / 2 - 1;
1812 pTmpOutV = pDstV + width / 2 - 1;
1814 for (rowCount = 0; rowCount < height ; rowCount++)
1816 for (colCount = 0; colCount < width; colCount++)
1818 *pTmpOutY-- = *pSrcY++; // copy source row in reverse to destination.
1820 pTmpOutY += (2 * width);
1822 for (rowCount = 0; rowCount < height/2 ; rowCount++)
1824 for (colCount = 0; colCount < width/2; colCount++)
1826 *pTmpOutU-- = *pSrcU++; // copy source row in reverse to destination.
1827 *pTmpOutV-- = *pSrcV++; // copy source row in reverse to destination.
1829 pTmpOutU += (width);
1830 pTmpOutV += (width);
1836 // pTmpOut* points to last column of first row of destination.
1837 pTmpOutY = pDstY + (height - 1) * width;
1838 pTmpOutU = pDstU + (height / 2 - 1) * width / 2;
1839 pTmpOutV = pDstV + (height / 2 - 1) * width / 2;
1841 for (rowCount = 0; rowCount < height / 2; rowCount++)
1843 memcpy(pTmpOutY, pSrcY, sizeof(byte) * width);
1844 memcpy(pTmpOutU, pSrcU, sizeof(byte) * width / 2 );
1845 memcpy(pTmpOutV, pSrcV, sizeof(byte) * width / 2 );
1849 pTmpOutU -= (width / 2);
1850 pSrcU += (width / 2);
1851 pTmpOutV -= (width / 2);
1852 pSrcV += (width / 2);
1854 for (rowCount = height / 2; rowCount < height; rowCount++)
1856 memcpy(pTmpOutY, pSrcY, sizeof(byte) * width);
1863 case MEDIA_PIXEL_FORMAT_NV12:
1865 case MEDIA_PIXEL_FORMAT_NV21:
1867 byte* pDstY = (byte *)dstBuf;
1868 short* pDstUV = (short* )(pDstY + width * height);
1870 byte* pSrcY = (byte* ) srcBuf;
1871 short* pSrcUV = (short* )(pSrcY + width * height);
1873 byte* pTmpOutY = null;
1874 short* pTmpOutUV = null;
1876 if (flip == IMAGE_FLIP_HORIZONTAL)
1880 // pTmpOut* points to last column of first row of destination.
1881 pTmpOutY = pDstY + width - 1;
1882 pTmpOutUV = pDstUV + width / 2 - 1;
1884 for (rowCount = 0; rowCount < height / 2; rowCount++)
1886 for (colCount = 0; colCount < width / 2; colCount++)
1888 *pTmpOutY-- = *pSrcY++; // copy source row in reverse to destination.
1889 *pTmpOutUV-- = *pSrcUV++; // copy source row in reverse to destination.
1891 for (colCount = width / 2; colCount < width; colCount++)
1893 *pTmpOutY-- = *pSrcY++;
1895 pTmpOutY += (2 * width);
1896 pTmpOutUV += (width);
1898 for (rowCount = height / 2; rowCount < height; rowCount++)
1900 for (colCount = 0; colCount < width; colCount++)
1902 *pTmpOutY-- = *pSrcY++;
1904 pTmpOutY += (2 * width);
1910 // pTmpOut* points to last column of first row of destination.
1911 pTmpOutY = pDstY + (height - 1) * width;
1912 pTmpOutUV = pDstUV + (height / 2 - 1) * width / 2;
1914 for (rowCount = 0; rowCount < height / 2; rowCount++)
1916 memcpy(pTmpOutY, pSrcY, sizeof(byte) * width);
1917 memcpy(pTmpOutUV, pSrcUV, sizeof(short) * width / 2 );
1921 pTmpOutUV -= width / 2;
1922 pSrcUV += width / 2;
1924 for (rowCount = height / 2; rowCount < height; rowCount++)
1926 memcpy(pTmpOutY, pSrcY, sizeof(byte) * width);
1933 case MEDIA_PIXEL_FORMAT_YUV444P:
1935 byte* pDstY = (byte *)dstBuf;
1936 byte* pDstU = pDstY + width * height;
1937 byte* pDstV = pDstU + width * height;
1939 byte* pSrcY = (byte *) srcBuf;
1940 byte* pSrcU = pSrcY + width * height;
1941 byte* pSrcV = pSrcU + width * height;
1942 byte* pTmpOutY = null;
1943 byte* pTmpOutU = null;
1944 byte* pTmpOutV = null;
1945 if (flip == IMAGE_FLIP_HORIZONTAL)
1949 // pTmpOut* points to last column of first row of destination.
1950 pTmpOutY = pDstY + width - 1;
1951 pTmpOutU = pDstU + width - 1;
1952 pTmpOutV = pDstV + width - 1;
1954 for (rowCount = 0; rowCount < height; rowCount++)
1956 for (colCount = 0; colCount < width ; colCount++)
1958 *pTmpOutY-- = *pSrcY++; // copy source row in reverse to destination.
1959 *pTmpOutU-- = *pSrcU++; // copy source row in reverse to destination.
1960 *pTmpOutV-- = *pSrcV++; // copy source row in reverse to destination.
1962 pTmpOutY += (2 * width);
1963 pTmpOutU += (2 * width);
1964 pTmpOutV += (2 * width);
1970 // pTmpOut* points to last column of first row of destination.
1971 pTmpOutY = pDstY + (height - 1) * width;
1972 pTmpOutU = pDstU + (height - 1) * width;
1973 pTmpOutV = pDstV + (height - 1) * width;
1975 for (rowCount = 0; rowCount < height; rowCount++)
1977 memcpy(pTmpOutY, pSrcY, sizeof(byte) * width);
1978 memcpy(pTmpOutU, pSrcU, sizeof(byte) * width);
1979 memcpy(pTmpOutV, pSrcV, sizeof(byte) * width);
1991 case MEDIA_PIXEL_FORMAT_YUYV422:
1993 case MEDIA_PIXEL_FORMAT_UYVY422:
1995 byte* pSrcBuf = const_cast<byte*>(srcBuf);
1996 byte* pDstBuf = dstBuf;
1997 byte* pTmpOut = null;
1999 if (flip == IMAGE_FLIP_HORIZONTAL)
2003 // pTmpOut points to last column of first row of destination.
2004 pTmpOut = pDstBuf + (width * 2) - 4;
2006 for (rowCount = 0; rowCount < height; rowCount++)
2008 for (colCount = 0; colCount < width / 2; colCount++)
2010 pTmpOut[0] = pSrcBuf[0]; // u0
2011 pTmpOut[1] = pSrcBuf[3]; // y1
2012 pTmpOut[2] = pSrcBuf[2]; // v1
2013 pTmpOut[3] = pSrcBuf[1]; // y0
2018 pTmpOut += 4 * width;
2024 // pTmpOut points to last column of first row of destination.
2025 pTmpOut = pDstBuf + ((height - 1) * width * 2);
2027 for (rowCount = 0; rowCount < height; rowCount++)
2029 memcpy(pTmpOut, pSrcBuf, 2 * width);
2030 pTmpOut -= width * 2;
2031 pSrcBuf += width * 2;
2040 colorFormat = _SlpUtil::ToMmUtilImgFormat(pixelFormat);
2041 rotation = _SlpUtil::ToMmUtilRotateType(flip);
2043 ret = mm_util_rotate_image((unsigned char*)srcBuf, width, height, colorFormat,
2044 (unsigned char*)dstBuf, &outWidth, &outHeight, rotation);
2046 SysTryCatch(NID_MEDIA, ret == 0, r = E_SYSTEM, E_SYSTEM,
2047 "mm_util_rotate_image failed with error code: %0x", ret);
2049 colorFormat = _SlpUtil::ToColorspace(pixelFormat);
2050 rotation = _SlpUtil::ToRotation(flip);
2052 ret = image_util_transform(dstBuf, &outWidth, &outHeight, rotation,
2053 srcBuf, width, height, colorFormat);
2054 SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
2055 "util_transform failed with error code: %0x", ret);
2065 _ImageUtil::ConvertPixelFormat(const ByteBuffer& srcBuf,
2066 MediaPixelFormat srcFormat, int srcWidth, int srcHeight,
2067 ByteBuffer& dstBuf, MediaPixelFormat dstFormat)
2069 result r = E_SUCCESS;
2073 image_util_colorspace_e srcColor = IMAGE_UTIL_COLORSPACE_RGB565;
2074 image_util_colorspace_e dstColor = IMAGE_UTIL_COLORSPACE_RGB565;
2076 SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
2077 "[E_INVALID_ARG] Invalid dimension: Should be greater than zero. (%d x %d)", srcWidth, srcHeight);
2079 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(srcFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
2080 "[E_UNSUPPORTED_FORMAT] Unsupported srcPixelFormat:%d", srcFormat);
2081 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(dstFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
2082 "[E_UNSUPPORTED_FORMAT] Unsupported dstPixelFormat:%d", dstFormat);
2084 SysTryCatch(NID_MEDIA, IsValidDimension(srcFormat, srcWidth, srcHeight),
2085 r = E_INVALID_ARG, E_INVALID_ARG,
2086 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
2088 SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, dstFormat, srcWidth, srcHeight),
2089 r = E_INVALID_ARG, E_INVALID_ARG,
2090 "[E_INVALID_ARG] Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
2091 dstBuf.GetLimit(), dstFormat, srcWidth, srcHeight);
2093 srcColor = _SlpUtil::ToColorspace(srcFormat);
2094 dstColor = _SlpUtil::ToColorspace(dstFormat);
2096 ret = image_util_convert_colorspace((unsigned char*) dstBuf.GetPointer(), dstColor,
2097 (byte*)srcBuf.GetPointer(), srcWidth, srcHeight, srcColor);
2098 SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
2099 "[E_SYSTEM] convert_colorspace failed with error code %d", ret);
2100 r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(dstFormat, srcWidth, srcHeight));
2101 SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
2102 "[%s] SetLimit to %d failed for buffer.", GetErrorMessage(r),
2103 _ImageUtil::GetBufferSize(dstFormat, srcWidth, srcHeight));
2108 int dstWidth = srcWidth;
2109 int dstHeight = srcHeight;
2110 int width = srcWidth;
2112 int srcLength = srcBuf.GetCapacity();
2115 std::unique_ptr<byte []> pDstBuf;
2116 struct SwsContext* pCvtCtxt = null;
2117 // Get ffmpeg format type
2118 PixelFormat ffSrcFormat = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(srcFormat);
2119 PixelFormat ffDstFormat = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(dstFormat);
2121 SysTryReturn(NID_MEDIA, srcWidth > 0 && srcHeight > 0, E_INVALID_ARG, E_INVALID_ARG,
2122 "[E_INVALID_ARG] Invalid dimension: Should be greater that zero (%d x %d)", srcWidth, srcHeight);
2124 SysTryReturn(NID_MEDIA, ffSrcFormat != PIX_FMT_NONE, E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
2125 "[E_UNSUPPORTED_FORMAT] Unsupported srcPixelFormat: %d", srcFormat);
2126 SysTryReturn(NID_MEDIA, ffDstFormat != PIX_FMT_NONE, E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
2127 "[E_UNSUPPORTED_FORMAT] Unsupported dstPixelFormat: %d", dstFormat);
2129 SysTryReturn(NID_MEDIA, IsValidDimension(srcFormat, srcWidth, srcHeight),
2130 E_INVALID_ARG, E_INVALID_ARG,
2131 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
2133 SysTryReturn(NID_MEDIA, IS_VALID_BUF(srcBuf, srcFormat, srcWidth, srcHeight),
2134 E_INVALID_ARG, E_INVALID_ARG,
2135 "[E_INVALID_ARG] Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
2136 srcBuf.GetLimit(), srcFormat, srcWidth, srcHeight);
2138 SysTryReturn(NID_MEDIA, IsValidDimension(dstFormat, srcWidth, srcHeight),
2139 E_INVALID_ARG, E_INVALID_ARG,
2140 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
2142 SysTryReturn(NID_MEDIA, IS_VALID_BUF(dstBuf, dstFormat, srcWidth, srcHeight),
2143 E_INVALID_ARG, E_INVALID_ARG,
2144 "[E_INVALID_ARG] Invalid dst buffer size (%d) for pixelformat (%d) and size (%d x %d)",
2145 dstBuf.GetLimit(), dstFormat, srcWidth, srcHeight);
2147 av_log_set_level (AV_LOG_QUIET);
2148 avcodec_register_all();
2153 std::unique_ptr<byte []> pSrcBufUPtr;
2154 const byte* pSrcData = null;
2155 byte* pDstData = null;
2161 size = GetBufferSize(srcFormat, srcWidth, srcHeight);
2163 pSrcBufUPtr.reset(new (std::nothrow) byte[size]);
2164 pSrcBuf = pSrcBufUPtr.get();
2165 SysTryReturn(NID_MEDIA, pSrcBuf != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
2166 "[E_OUT_OF_MEMORY] Couldn't allocate buffer");
2167 memset(pSrcBuf, 0, size);
2169 pSrcData = srcBuf.GetPointer();
2170 SysTryReturn(NID_MEDIA, pSrcData != null, GetLastResult(), GetLastResult(),
2171 "[%s] ByteBuffer::GetPointer() returned null", GetErrorMessage(GetLastResult()));
2175 // Create a new buffer with input buffer, padded to increase width to be 8 pixels wide.
2176 for (row = 0; row < srcHeight; row++)
2178 memcpy(pDstData, pSrcData, srcWidth);
2180 pSrcData += srcWidth;
2186 pSrcBuf = (const_cast<byte *>(srcBuf.GetPointer()));
2187 SysTryReturn(NID_MEDIA, pSrcBuf != null, GetLastResult(), GetLastResult(),
2188 "[%s] srcBuf.GetPointer failed", GetErrorMessage(GetLastResult()));
2193 // Create scale context
2194 pCvtCtxt = sws_getContext(srcWidth, srcHeight, ffSrcFormat,
2195 dstWidth, dstHeight, ffDstFormat,
2196 SWS_BICUBIC, NULL, NULL, NULL);
2198 SysTryReturn(NID_MEDIA, pCvtCtxt != null, E_SYSTEM, E_SYSTEM,
2199 "[E_SYSTEM] sws_getContext failed for src size (%d x %d), pix (%d), and dst size (%d x %d), pix (%d)",
2200 srcWidth, srcHeight, ffSrcFormat,
2201 dstWidth, dstHeight, ffDstFormat);
2203 // Calculate src/dest size
2204 size = avpicture_get_size(ffSrcFormat, srcWidth, srcHeight);
2205 SysTryReturn(NID_MEDIA, size <= srcLength, E_INVALID_ARG, E_INVALID_ARG,
2206 "[E_INVALID_ARG] underflow: Required buffer size (%d) < given buffer size (%d), for pix (%d), (%d x %d)",
2207 size, srcLength, srcFormat, srcWidth, srcHeight);
2209 size = avpicture_get_size(ffDstFormat, dstWidth, dstHeight);
2210 SysTryReturn(NID_MEDIA, size >= 0, E_FAILURE, E_FAILURE,
2211 "[E_FAILURE] Not able find size of dest frame for pix (%d), size (%d x %d)");
2213 pDstBuf.reset(new (std::nothrow) byte[size]);
2214 SysTryReturn(NID_MEDIA, pDstBuf.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
2215 "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", size);
2218 memset(&srcFrame, 0, sizeof(srcFrame));
2219 memset(&dstFrame, 0, sizeof(dstFrame));
2221 // Fill source frame
2222 avpicture_fill((AVPicture*)&srcFrame, (byte*)pSrcBuf, ffSrcFormat, srcWidth, srcHeight);
2225 avpicture_fill((AVPicture*)&dstFrame, (byte*)pDstBuf.get(), ffDstFormat, dstWidth, dstHeight);
2228 sws_scale(pCvtCtxt, srcFrame.data, srcFrame.linesize, 0, srcHeight,
2229 dstFrame.data, dstFrame.linesize);
2231 if (width == srcWidth)
2233 r = dstBuf.SetArray(pDstBuf.get(), 0, dstLength);
2234 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
2235 "[%s] Propagated.", GetErrorMessage(r));
2240 // The padding must be removed from output buffer.
2242 std::unique_ptr<byte []> pUnpadded;
2243 byte *pSrcData = null;
2244 byte *pDstData = null;
2247 size = GetBufferSize(srcFormat, srcWidth, srcHeight);
2249 pUnpadded.reset(new (std::nothrow) byte[size]);
2250 SysTryReturn(NID_MEDIA, pUnpadded.get() != null, E_OUT_OF_MEMORY,
2251 E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Couldn't allocate buffer");
2252 memset(pUnpadded.get(), 0, size);
2254 pSrcData = pDstBuf.get();
2256 pDstData = pUnpadded.get();
2258 // Create a new buffer with input buffer, padded to increase width to be 8 pixels wide.
2259 for (row = 0; row < srcHeight; row++)
2261 memcpy(pDstData, pSrcData, srcWidth);
2262 pDstData += srcWidth;
2266 r = dstBuf.SetArray(pUnpadded.get(), 0, size);
2267 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r,
2268 r, "[%s] Propagated.", GetErrorMessage(r));
2272 if (pCvtCtxt != NULL)
2274 sws_freeContext(pCvtCtxt);
2287 _ImageUtil::Resize(const ByteBuffer& srcBuf,
2288 MediaPixelFormat pixelFormat,
2289 int srcWidth, int srcHeight,
2291 int dstWidth, int dstHeight)
2293 result r = E_SUCCESS;
2294 unsigned int outWidth = dstWidth;
2295 unsigned int outHeight = dstHeight;
2296 byte* pDataOut = null;
2298 SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
2299 "Invalid src dimension: Should be greater than zero: (%d x %d)", srcWidth, srcHeight);
2300 SysTryCatch(NID_MEDIA, dstWidth > 0 && dstHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
2301 "Invalid dst dimension: Should be greater than zero: (%d x %d)", dstWidth, dstHeight);
2303 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
2304 "Unsupported pixelFormat: %d", pixelFormat);
2306 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, srcWidth, srcHeight),
2307 r = E_INVALID_ARG, E_INVALID_ARG,
2308 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
2310 SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, srcWidth, srcHeight),
2311 r = E_INVALID_ARG, E_INVALID_ARG,
2312 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
2313 srcBuf.GetLimit(), pixelFormat, srcWidth, srcHeight);
2315 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, dstWidth, dstHeight),
2316 r = E_INVALID_ARG, E_INVALID_ARG,
2317 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", dstWidth, dstHeight);
2319 SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, dstWidth, dstHeight),
2320 r = E_INVALID_ARG, E_INVALID_ARG,
2321 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
2322 dstBuf.GetLimit(), pixelFormat, dstWidth, dstHeight);
2324 pDataOut = const_cast<byte*>(dstBuf.GetPointer());
2326 r = ResizeBuffer(const_cast<byte*>(srcBuf.GetPointer()), pixelFormat,
2327 srcWidth, srcHeight, pDataOut, dstWidth, dstHeight);
2328 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Resize failed.", GetErrorMessage(r));
2330 r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
2331 SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
2332 "[%s] dstBuf.SetLimit to %d failed.", GetErrorMessage(r),
2333 _ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
2340 _ImageUtil::Rotate(const ByteBuffer& srcBuf,
2341 MediaPixelFormat pixelFormat,
2342 int width, int height,
2344 ImageRotationType rotate)
2346 result r = E_SUCCESS;
2350 SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, width, height),
2351 r = E_INVALID_ARG, E_INVALID_ARG,
2352 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
2353 srcBuf.GetLimit(), pixelFormat, width, height);
2355 SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, width, height),
2356 r = E_INVALID_ARG, E_INVALID_ARG,
2357 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
2358 dstBuf.GetLimit(), pixelFormat, width, height);
2360 if (rotate == IMAGE_ROTATION_0)
2362 r = dstBuf.SetArray(srcBuf.GetPointer(), 0, srcBuf.GetLimit());
2363 SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
2364 "[%s] dstBuf.SetArray failed. SrcBuffer = %d, SrcBuffer.Limit = %d, dstBuffer.Position = %d, dstBuffer.Capacity = %d.",
2365 GetErrorMessage(r), srcBuf.GetPointer(), srcBuf.GetLimit(), dstBuf.GetPosition(), dstBuf.GetCapacity());
2370 // Set output dimensions;
2371 if ((rotate == IMAGE_ROTATION_90) || (rotate == IMAGE_ROTATION_270))
2382 return RotateBuffer((byte *)srcBuf.GetPointer(), pixelFormat, width, height,
2383 (byte *)dstBuf.GetPointer(), outWidth, outHeight, rotate);
2389 _ImageUtil::Flip(const ByteBuffer& srcBuf, MediaPixelFormat pixelFormat,
2390 int width, int height,
2391 ByteBuffer& dstBuf, ImageFlipType flip)
2393 result r = E_SUCCESS;
2395 SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, width, height),
2396 r = E_INVALID_ARG, E_INVALID_ARG,
2397 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
2398 srcBuf.GetLimit(), pixelFormat, width, height);
2400 SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, width, height),
2401 r = E_INVALID_ARG, E_INVALID_ARG,
2402 "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
2403 dstBuf.GetLimit(), pixelFormat, width, height);
2405 if (flip == IMAGE_FLIP_NONE)
2407 r = dstBuf.SetArray(srcBuf.GetPointer(), 0, srcBuf.GetLimit());
2408 SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
2409 "[%s] dstBuf.SetArray failed: source (%x %d), dst (%d %d)",
2410 srcBuf.GetPointer(), srcBuf.GetLimit(),
2411 dstBuf.GetPosition(), dstBuf.GetCapacity());
2416 return FlipBuffer((byte *)srcBuf.GetPointer(), pixelFormat, width, height,(byte *) dstBuf.GetPointer(),flip);
2422 Tizen::Media::ImageFormat
2423 _ImageUtil::GetImageFormat(const Tizen::Base::String& srcImageFile)
2425 ImageFormat imgFormat;
2426 ByteBuffer* pBuf = null;
2428 pBuf = _MediaUtil::FileToBufferN(srcImageFile, _ImageUtil::MinImageFormatLength());
2429 SysSecureTryCatch(NID_MEDIA, pBuf != null, , GetLastResult(),
2430 "[%s] _MediaUtil::FileToBufferN failed for %ls.",
2431 GetErrorMessage(GetLastResult()), srcImageFile.GetPointer());
2433 imgFormat = GetImageFormat(*pBuf);
2443 return IMG_FORMAT_NONE;
2448 _ImageUtil::HasAlphaChannel(const Tizen::Base::String& srcImageFile)
2450 bool hasAlpha = false;
2451 ByteBuffer* pBuf = null;
2453 pBuf = _MediaUtil::FileToBufferN(srcImageFile);
2454 SysSecureTryCatch(NID_MEDIA, pBuf != null, , GetLastResult(),
2455 "[%s] _MediaUtil::FileToBufferN failed for %ls.",
2456 GetErrorMessage(GetLastResult()), srcImageFile.GetPointer());
2457 hasAlpha = HasAlphaChannel(*pBuf);
2468 // For check image format
2469 static byte _PNG_HEADER[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
2470 static byte _JPEG_HEADER[] = { 0xFF, 0xD8 }; // support only JFIF.
2471 static byte _GIF_HEADER[] = { 'G', 'I', 'F' };
2472 static byte _TIFF_HEADER[][4] = { { 0x49, 0x49, 0x2A, 0x00 }, { 0x4D, 0x4D, 0x00, 0x2A } };
2473 static byte _BMP_HEADER[] = { 'B', 'M' };
2474 static byte _WBMP_HEADER[] = { 0x00, 0x00 };
2476 static const int MIN_IMAGE_FORMAT_LENGTH = sizeof(_PNG_HEADER);
2479 _ImageUtil::MinImageFormatLength(void)
2481 return MIN_IMAGE_FORMAT_LENGTH;
2485 _ImageUtil::GetImageFormat(const Tizen::Base::ByteBuffer& srcBuf)
2487 const byte* pBuf = null;
2494 { _PNG_HEADER, sizeof(_PNG_HEADER), IMG_FORMAT_PNG },
2495 { _JPEG_HEADER, sizeof(_JPEG_HEADER), IMG_FORMAT_JPG },
2496 { _BMP_HEADER, sizeof(_BMP_HEADER), IMG_FORMAT_BMP },
2497 { _GIF_HEADER, sizeof(_GIF_HEADER), IMG_FORMAT_GIF },
2498 { _TIFF_HEADER[0], sizeof(_TIFF_HEADER[0]), IMG_FORMAT_TIFF },
2499 { _TIFF_HEADER[1], sizeof(_TIFF_HEADER[1]), IMG_FORMAT_TIFF },
2500 { _WBMP_HEADER, sizeof(_WBMP_HEADER), IMG_FORMAT_WBMP },
2502 ImageFormat fmt = IMG_FORMAT_NONE;
2503 SysTryCatch(NID_MEDIA, &srcBuf != null, , E_INVALID_ARG,
2504 "[E_INVALID_ARG] srcBuf is null");
2505 SysTryCatch(NID_MEDIA, srcBuf.GetLimit() >= MIN_IMAGE_FORMAT_LENGTH, , E_INVALID_DATA,
2506 "[E_INVALID_DATA] data is too small:%d < %d", srcBuf.GetLimit(), MIN_IMAGE_FORMAT_LENGTH);
2508 pBuf = (const byte*) (srcBuf.GetPointer());
2509 SysTryCatch(NID_MEDIA, pBuf != null, , E_INVALID_ARG,
2510 "[E_INVALID_ARG] Could not get file header.");
2511 for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
2513 if (memcmp(pBuf, map[i].pHeader, map[i].size) == 0)
2515 fmt = map[i].format;
2519 if ((fmt == IMG_FORMAT_WBMP) && (pBuf[2] == 0 || pBuf[2] == 1 || pBuf[2] == 2) && pBuf[3] == 0 )
2521 fmt = IMG_FORMAT_NONE;
2527 return IMG_FORMAT_NONE;
2531 _ImageUtil::HasAlphaChannel(const Tizen::Base::ByteBuffer& srcBuf)
2533 ImageFormat imgFormat = IMG_FORMAT_NONE;
2534 const byte* pBuf = null;
2535 bool idatFlag = false;
2536 bool hasAlpha = false;
2537 unsigned int cnkLength = 0;
2538 int curPosition = 0;
2542 SysTryReturn(NID_MEDIA, &srcBuf != null, hasAlpha, E_INVALID_ARG,
2543 "[E_INVALID_ARG] srcBuf is null");
2545 imgFormat = GetImageFormat(srcBuf);
2547 SysTryReturn(NID_MEDIA, imgFormat == IMG_FORMAT_PNG, hasAlpha, E_UNSUPPORTED_FORMAT,
2548 "[E_UNSUPPORTED_FORMAT] The file is not of PNG format.");
2550 pBuf = (const byte*)srcBuf.GetPointer();
2551 bufSize = srcBuf.GetCapacity();
2554 // 25 means, Png ID(8byte) + IHDR length(4byte) + IHDR(4byte) +
2555 // Width(4byte) + Height(4byte) + Bitdepth(1byte) and next 1byte is
2557 // If color type is between 4 and 7, it uses alpha channel.
2558 SysTryReturn(NID_MEDIA, bufSize > (curPosition + 4), hasAlpha, E_UNSUPPORTED_FORMAT,
2559 "[E_INVALID_DATA] data size is too small: %d < %d", bufSize, curPosition + 4);
2561 value = pBuf[curPosition];
2562 if ((4 <= value) && (value <= 7))
2566 else if (value == 3)
2568 // check tRNS chunck existance if color type is 3(indexed palette).
2569 // 25byte + remained IHDR 3byte(filter mode etc.) = 28byte
2570 // 28byte + ?(4byte)
2572 // Chunk length(4byte)+ chunk name(4byte) + length(value of chunk length) + CRC(4byte)
2573 // chunk can be pHYs, sBIT, gAMA, cHRM, tRNS, etc (before IDAT)
2574 SysTryReturn(NID_MEDIA, bufSize > (curPosition + 4), hasAlpha, E_INVALID_DATA,
2575 "[E_INVALID_DATA] data size is too small: %d < %d", bufSize, curPosition + 4);
2577 // Structure of chunk:
2578 // |<----------------- A single chunk ---------------------->|
2579 // |_________________________________________________________|
2580 // | 4 bytes || 4 bytes || chunk length bytes || 4 bytes |
2581 // |____________||__________||____________________||_________|
2583 // |Chunk length||Chunk name|| chunk data || CRC sum |
2585 // data is stored in network byte order; ie big endian.
2586 // To get the value, convert to little endian.
2588 memcpy(&cnkLength, pBuf + curPosition, 4);
2589 cnkLength = ntohl(cnkLength);
2591 // Increment position to point to chunk name, which follows the length.
2592 curPosition = curPosition + 4;
2594 // Loop with starting chunk length.
2595 while (curPosition < bufSize - 4)
2597 if (!memcmp((void *)(pBuf + curPosition), (void *)"tRNS", 4))
2601 else if (!memcmp((void *)(pBuf + curPosition), (void *)"IDAT", 4))
2607 curPosition += 4; // chunk name
2608 curPosition += cnkLength;
2609 curPosition += 4; // CRC
2612 // tRNS chunk must be before IDAT chunk.
2613 if (idatFlag || hasAlpha)
2618 if (curPosition >= bufSize - 4)
2623 // read next chunk length
2624 memcpy(&cnkLength, pBuf + curPosition, 4);
2625 cnkLength = ntohl(cnkLength);
2626 curPosition = curPosition + 4;
2633 Tizen::Base::ByteBuffer*
2634 _ImageUtil::ResizeN(const Tizen::Base::ByteBuffer &srcBuf,
2635 MediaPixelFormat pixelFormat,
2636 int srcWidth, int srcHeight,
2637 int dstWidth, int dstHeight)
2640 std::unique_ptr <ByteBuffer> pOutBuf;
2641 result r = E_SUCCESS;
2643 bufSize = GetBufferSize(pixelFormat, dstWidth, dstHeight);
2644 SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
2645 "[%s] Check dimensions (%d x %d) and pixelformat %d", GetErrorMessage(GetLastResult()),
2646 dstWidth, dstHeight, pixelFormat);
2648 pOutBuf.reset(new (std::nothrow) ByteBuffer());
2649 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
2650 "[%s] Failed to create new ByteBuffer", GetErrorMessage(GetLastResult()));
2652 r = pOutBuf->Construct(bufSize);
2653 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2654 "[%s] ByteBuffer.Construct failed", GetErrorMessage(r));
2656 r = Resize(srcBuf, pixelFormat, srcWidth, srcHeight, *pOutBuf.get(), dstWidth, dstHeight);
2657 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2658 "[%s] ImageUtil.Resize", GetErrorMessage(r));
2660 SetLastResult(E_SUCCESS);
2661 return pOutBuf.release();
2665 _ImageUtil::Crop(const Tizen::Base::ByteBuffer &srcBuf,
2666 MediaPixelFormat pixelFormat,
2667 int srcWidth, int srcHeight,
2668 Tizen::Base::ByteBuffer &dstBuf,
2669 int dstX, int dstY, int dstWidth, int dstHeight)
2671 result r = E_SUCCESS;
2673 r = CropBuffer(srcBuf.GetPointer(), pixelFormat, srcWidth, srcHeight,
2674 const_cast<byte*>(dstBuf.GetPointer()), dstX, dstY, dstWidth, dstHeight);
2675 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] _ImageUtil::CropBuffer failed.",
2676 GetErrorMessage(r));
2678 r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(pixelFormat, dstWidth, dstHeight));
2679 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] ByteBuffer.SetLimit to %d failed.",
2680 GetErrorMessage(r), _ImageUtil::GetBufferSize(pixelFormat, dstWidth, dstHeight));
2687 _ImageUtil::CropBuffer(const byte* srcBuf,
2688 MediaPixelFormat pixelFormat,
2689 int srcWidth, int srcHeight,
2691 int dstX, int dstY, int dstWidth, int dstHeight)
2693 result r = E_SUCCESS;
2694 int copyRowWidth = 0;
2695 int srcRowWidth = 0;
2697 byte* pInBuffer = null;
2698 byte* pOutBuffer = null;
2700 SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
2701 "[E_INVALID_ARG] Invalid src dimension: Should be greater than zero (%d x %d)", srcWidth, srcHeight);
2702 SysTryCatch(NID_MEDIA, dstWidth > 0 && dstHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
2703 "[E_INVALID_ARG] Invalid dst dimension: Should be greater than zero (%d x %d)", dstWidth, dstHeight);
2704 SysTryCatch(NID_MEDIA, dstX >= 0 && dstY >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
2705 "[E_INVALID_ARG] Invalid offset dimension: Should be greater than zero (%d x %d)", dstX, dstY);
2707 SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
2708 "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
2710 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, srcWidth, srcHeight),
2711 r = E_INVALID_ARG, E_INVALID_ARG,
2712 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
2714 SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, dstWidth, dstHeight),
2715 r = E_INVALID_ARG, E_INVALID_ARG,
2716 "[E_INVALID_ARG] Dimensions should be even (%d x %d).", dstWidth, dstHeight);
2718 SysTryCatch(NID_MEDIA, IsValidCoordinate(pixelFormat, dstX, dstY),
2719 r = E_INVALID_ARG, E_INVALID_ARG,
2720 "[E_INVALID_ARG] Source location must be even (%d, %d).", dstX, dstY);
2722 SysTryCatch(NID_MEDIA, dstWidth + dstX <= srcWidth , r = E_INVALID_ARG, E_INVALID_ARG,
2723 "Invalid Clip Area : destination \"x\" (%d) exceeds image width (%d).",
2724 dstWidth + dstX, srcWidth);
2726 SysTryCatch(NID_MEDIA, dstHeight + dstY <= srcHeight , r = E_INVALID_ARG, E_INVALID_ARG,
2727 "Invalid Clip Area : destination \"y\" (%d) exceeds image height (%d).",
2728 dstHeight + dstY, srcHeight);
2730 pOutBuffer = dstBuf;
2734 case MEDIA_PIXEL_FORMAT_GRAY:
2737 // pInBuffer points to the start of the region to be copied to destination.
2738 pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
2739 copyRowWidth = dstWidth * bpp;
2740 srcRowWidth = srcWidth * bpp;
2741 for (int i = dstY; i < dstY + dstHeight; i++)
2743 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2744 pOutBuffer += copyRowWidth;
2745 pInBuffer += srcRowWidth;
2749 case MEDIA_PIXEL_FORMAT_RGB565LE:
2752 // pInBuffer points to the start of the region to be copied to destination.
2753 pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
2754 copyRowWidth = dstWidth * bpp;
2755 srcRowWidth = srcWidth * bpp;
2756 for (int i = dstY; i < dstY + dstHeight; i++)
2758 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2759 pOutBuffer += copyRowWidth;
2760 pInBuffer += srcRowWidth;
2764 case MEDIA_PIXEL_FORMAT_RGB888:
2766 case MEDIA_PIXEL_FORMAT_BGR888:
2769 // pInBuffer points to the start of the region to be copied to destination.
2770 pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
2771 copyRowWidth = dstWidth * bpp;
2772 srcRowWidth = srcWidth * bpp;
2773 for (int i = dstY; i < dstY + dstHeight; i++)
2775 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2776 pOutBuffer += copyRowWidth;
2777 pInBuffer += srcRowWidth;
2781 case MEDIA_PIXEL_FORMAT_RGBA8888:
2783 case MEDIA_PIXEL_FORMAT_BGRA8888:
2786 // pInBuffer points to the start of the region to be copied to destination.
2787 pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
2788 copyRowWidth = dstWidth * bpp; // BGRA and RGBA are 4 bytes each.
2789 srcRowWidth = srcWidth * bpp;
2790 for (int i = dstY; i < dstY + dstHeight; i++)
2792 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2793 pOutBuffer += copyRowWidth;
2794 pInBuffer += srcRowWidth;
2798 case MEDIA_PIXEL_FORMAT_YUV444P:
2801 // pInBuffer points to the start of the region to be copied to destination.
2802 pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
2803 copyRowWidth = dstWidth * bpp;
2804 srcRowWidth = srcWidth * bpp;
2805 for (int i = dstY; i < dstY + dstHeight; i++)
2807 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2808 memcpy(pOutBuffer + (dstWidth * dstHeight), pInBuffer + (srcWidth * srcHeight), copyRowWidth);
2809 memcpy(pOutBuffer + (2 * dstWidth * dstHeight), pInBuffer + (2 * srcWidth * srcHeight), copyRowWidth);
2810 pOutBuffer += copyRowWidth;
2811 pInBuffer += srcRowWidth;
2815 case MEDIA_PIXEL_FORMAT_YUYV422:
2817 case MEDIA_PIXEL_FORMAT_UYVY422:
2820 // pInBuffer points to the start of the region to be copied to destination.
2821 pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
2822 copyRowWidth = dstWidth * bpp;
2823 srcRowWidth = srcWidth * bpp;
2824 if ((dstX % 2) == 0)
2826 for (int i = dstY; i < dstY + dstHeight; i++)
2828 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2829 pOutBuffer += copyRowWidth;
2830 pInBuffer += srcRowWidth;
2835 case MEDIA_PIXEL_FORMAT_YUV420P:
2838 // pInBuffer points to the start of the region to be copied to destination.
2839 pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
2840 copyRowWidth = dstWidth * bpp;
2841 srcRowWidth = srcWidth * bpp;
2842 for (int i = dstY; i < dstY + dstHeight; i++)
2844 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2845 pOutBuffer += copyRowWidth;
2846 pInBuffer += srcRowWidth;
2849 pOutBuffer = dstBuf + (dstWidth * dstHeight);
2850 pInBuffer = const_cast<byte*>(srcBuf) + (srcWidth * srcHeight) + (dstY/2 * srcWidth/2) + (dstX/2);
2853 for (int i = 0; i < dstHeight/2; i++)
2855 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2856 memcpy(pOutBuffer + (dstWidth * dstHeight)/4, pInBuffer + (srcWidth * srcHeight)/4, copyRowWidth);
2857 pOutBuffer += copyRowWidth;
2858 pInBuffer += srcRowWidth;
2862 case MEDIA_PIXEL_FORMAT_NV12:
2864 case MEDIA_PIXEL_FORMAT_NV21:
2867 // pInBuffer points to the start of the region to be copied to destination.
2868 pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
2869 copyRowWidth = dstWidth * bpp;
2870 srcRowWidth = srcWidth * bpp;
2871 for (int i = dstY; i < dstY + (dstHeight)/2; i++)
2873 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2874 memcpy(pOutBuffer + (dstWidth * dstHeight), pInBuffer + (srcWidth * srcHeight), copyRowWidth);
2875 pOutBuffer += copyRowWidth;
2876 pInBuffer += srcRowWidth;
2878 for (int i = dstY + (dstHeight + 1)/2; i < dstY + dstHeight; i++)
2880 memcpy(pOutBuffer, pInBuffer, copyRowWidth);
2881 pOutBuffer += copyRowWidth;
2882 pInBuffer += srcRowWidth;
2887 r = E_UNSUPPORTED_FORMAT;
2894 Tizen::Base::ByteBuffer*
2895 _ImageUtil::CropN(const Tizen::Base::ByteBuffer &srcBuf,
2896 MediaPixelFormat pixelFormat,
2897 int srcWidth, int srcHeight,
2899 int dstWidth, int dstHeight)
2902 std::unique_ptr <ByteBuffer> pOutBuf;
2903 result r = E_SUCCESS;
2905 bufSize = GetBufferSize(pixelFormat, dstWidth, dstHeight);
2906 SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
2907 "[%s] Check dimensions (%d x %d) and pixel format (%d)",
2908 GetErrorMessage(GetLastResult()), dstWidth, dstHeight, pixelFormat);
2910 pOutBuf.reset(new (std::nothrow) ByteBuffer());
2911 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
2912 "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
2914 r = pOutBuf->Construct(bufSize);
2915 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2916 "[%s] buf.Construct failed.", GetErrorMessage(r));
2918 r = Crop(srcBuf, pixelFormat, srcWidth, srcHeight, *pOutBuf.get(), dstX, dstY, dstWidth, dstHeight);
2919 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2920 "[%s] ImageUtil.Crop failed.", GetErrorMessage(r));
2922 SetLastResult(E_SUCCESS);
2923 return pOutBuf.release();
2927 _ImageUtil::CropN(const byte *srcBuf,
2928 MediaPixelFormat pixelFormat,
2929 int srcWidth, int srcHeight,
2930 int dstX, int dstY, int dstWidth, int dstHeight)
2933 std::unique_ptr <byte[]> pOutBuf;
2934 result r = E_SUCCESS;
2936 bufSize = GetBufferSize(pixelFormat, dstWidth, dstHeight);
2937 SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
2938 "[%s] Check dimensions (%d x %d) and pixel format (%d)",
2939 GetErrorMessage(GetLastResult()), dstWidth, dstHeight, pixelFormat);
2941 pOutBuf.reset(new (std::nothrow) byte[bufSize]);
2942 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
2943 "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
2945 r = CropBuffer(srcBuf, pixelFormat, srcWidth, srcHeight, pOutBuf.get(), dstX, dstY, dstWidth, dstHeight);
2946 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2947 "[%s] ImageUtil.CropN failed.", GetErrorMessage(r));
2949 SetLastResult(E_SUCCESS);
2950 return pOutBuf.release();
2954 _ImageUtil::RotateN(const byte *srcBuf,
2955 MediaPixelFormat pixelFormat,
2956 int srcWidth, int srcHeight,
2957 ImageRotationType rotate,
2958 int &dstWidth, int &dstHeight)
2961 std::unique_ptr <byte[]> pOutBuf;
2962 result r = E_SUCCESS;
2964 bufSize = GetBufferSize(pixelFormat, srcWidth, srcHeight);
2965 SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
2966 "[%s] Check dimensions (%d x %d) and pixel format (%d)",
2967 GetErrorMessage(GetLastResult()), dstWidth, dstHeight, pixelFormat);
2969 pOutBuf.reset(new (std::nothrow) byte[bufSize]);
2970 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
2971 "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
2973 r = RotateBuffer(srcBuf, pixelFormat, srcWidth, srcHeight, pOutBuf.get(), dstWidth, dstHeight, rotate);
2974 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
2975 "[%s] ImageUtil.RotateN failed.", GetErrorMessage(r));
2977 SetLastResult(E_SUCCESS);
2978 return pOutBuf.release();
2982 _ImageUtil::FlipN(const byte* srcBuf,
2983 MediaPixelFormat pixelFormat, int width, int height,
2987 std::unique_ptr <byte[]> pOutBuf;
2988 result r = E_SUCCESS;
2990 bufSize = GetBufferSize(pixelFormat, width, height);
2991 SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
2992 "[%s] Check dimensions (%d x %d) and pixel format (%d)",
2993 GetErrorMessage(GetLastResult()), width, height, pixelFormat);
2995 pOutBuf.reset(new (std::nothrow) byte[bufSize]);
2996 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
2997 "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
2999 r = FlipBuffer(srcBuf, pixelFormat, width, height, pOutBuf.get(), flip);
3000 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
3001 "[%s] ImageUtil.FlipN failed.", GetErrorMessage(r));
3003 SetLastResult(E_SUCCESS);
3004 return pOutBuf.release();
3008 _ImageUtil::GetBufferSize(MediaPixelFormat pixelFormat, int width, int height)
3010 typedef struct _Rational
3018 MediaPixelFormat key;
3021 { MEDIA_PIXEL_FORMAT_RGB565LE, {2, 1}},
3022 { MEDIA_PIXEL_FORMAT_RGBA8888, {4, 1}},
3023 { MEDIA_PIXEL_FORMAT_BGRA8888, {4, 1}},
3024 { MEDIA_PIXEL_FORMAT_YUV420P, {3, 2}},
3025 { MEDIA_PIXEL_FORMAT_GRAY, {1, 1}},
3026 { MEDIA_PIXEL_FORMAT_NV12, {3, 2}},
3027 { MEDIA_PIXEL_FORMAT_NV21, {3, 2}},
3028 { MEDIA_PIXEL_FORMAT_YUV444P, {3, 1}},
3029 { MEDIA_PIXEL_FORMAT_YUYV422, {2, 1}},
3030 { MEDIA_PIXEL_FORMAT_UYVY422, {2, 1}},
3031 { MEDIA_PIXEL_FORMAT_BGR888, {3,1}},
3032 { MEDIA_PIXEL_FORMAT_RGB888, {3,1}},
3034 rational ret = {0, 0};
3036 SysTryCatch(NID_MEDIA, width > 0 && height > 0, , E_INVALID_ARG,
3037 "[E_INVALID_ARG] Dimensions should be greater than zero (%d x %d)", width, height);
3039 for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
3041 if (map[i].key == pixelFormat)
3048 SysTryCatch(NID_MEDIA, ret.den != 0, , E_UNSUPPORTED_FORMAT,
3049 "Could not find details for pixelformat %d.", pixelFormat);
3051 SetLastResult(E_SUCCESS);
3053 return width * height * ret.num / ret.den;
3060 _ImageUtil::IsValidDimension(MediaPixelFormat pixelFormat, int width, int height)
3062 MediaPixelFormat fmt[] = {
3063 MEDIA_PIXEL_FORMAT_YUV420P,
3064 MEDIA_PIXEL_FORMAT_NV12,
3065 MEDIA_PIXEL_FORMAT_NV21,
3066 MEDIA_PIXEL_FORMAT_YUYV422,
3067 MEDIA_PIXEL_FORMAT_UYVY422,
3070 for (unsigned int i = 0; i < sizeof(fmt)/sizeof(fmt[0]); i++)
3072 if (fmt[i] == pixelFormat)
3074 if ((width & 0x01) || (height & 0x01))
3081 // return true for other pixel formats
3086 _ImageUtil::IsValidCoordinate(MediaPixelFormat pixelFormat, int XLoc, int YLoc)
3088 if ((MEDIA_PIXEL_FORMAT_YUV420P == pixelFormat) ||
3089 (MEDIA_PIXEL_FORMAT_NV12 == pixelFormat) ||
3090 (MEDIA_PIXEL_FORMAT_NV21 == pixelFormat))
3092 if ((XLoc & 0x01) || (YLoc & 0x01))
3099 if ((MEDIA_PIXEL_FORMAT_YUYV422 == pixelFormat) ||
3100 (MEDIA_PIXEL_FORMAT_UYVY422 == pixelFormat))
3108 // return true for other pixel formats
3113 _ImageUtil::ToFfmpegPixelFormat(MediaPixelFormat pixelFmt)
3115 for (unsigned int i = 0; i < sizeof(_PIXEL_FORMAT_MAP)/sizeof(_PIXEL_FORMAT_MAP[0]); i++)
3117 if (pixelFmt == _PIXEL_FORMAT_MAP[i].mediaPixelFmt)
3119 return _PIXEL_FORMAT_MAP[i].pixelFmt;
3122 return PIX_FMT_NONE;
3126 _ImageUtil::ToMediaPixelFormatFromFfmpeg(int pixelFormat)
3128 for (unsigned int i = 0; i < sizeof(_PIXEL_FORMAT_MAP)/sizeof(_PIXEL_FORMAT_MAP[0]); i++)
3130 if (pixelFormat == _PIXEL_FORMAT_MAP[i].pixelFmt)
3132 return _PIXEL_FORMAT_MAP[i].mediaPixelFmt;
3135 return MEDIA_PIXEL_FORMAT_NONE;
3139 _ImageUtil::GetResizedDimension(int srcWidth, int srcHeight, float dstWidth, float dstHeight,
3140 float &outWidth, float &outHeight)
3143 SysTryReturn(NID_MEDIA, (srcWidth > 0 && srcHeight > 0 && dstWidth > 0 && dstHeight > 0),
3144 E_INVALID_ARG, E_INVALID_ARG,
3145 "[E_INVALID_ARG] Dimensions should be greater than zero Source size(%d x %d), \
3146 Destination size(%f x %f)", srcWidth, srcHeight, dstWidth, dstHeight);
3148 double xRatio = Float(dstWidth).ToDouble() / Integer(srcWidth).ToDouble();
3149 double yRatio = Float(dstHeight).ToDouble() / Integer(srcHeight).ToDouble();
3151 if (xRatio >= 1.0 || yRatio >= 1.0)
3153 outWidth = Integer(srcWidth).ToFloat();
3154 outHeight = Integer(srcHeight).ToFloat();
3156 else if (xRatio < yRatio)
3158 outWidth = Double(srcWidth * yRatio).ToFloat();
3159 outHeight = dstHeight;
3163 outWidth = dstWidth;
3164 outHeight = Double(srcHeight * xRatio).ToFloat();
3170 _ImageUtil::PremultiplyAlpha(byte* data, int length, MediaPixelFormat pixelFormat)
3172 unsigned int *pPixel = (unsigned int*)data;
3173 for (int i = 0; i < length / 4; i++)
3175 unsigned int a = 1 + (*pPixel >> 24);
3176 *pPixel = (*pPixel & 0xff000000) +
3177 (((((*pPixel) >> 8) & 0xff) * a) & 0xff00) +
3178 (((((*pPixel) & 0x00ff00ff) * a) >> 8) & 0x00ff00ff);