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_JpegTurboDecoder.cpp
20 * @brief This file contains the implementation of _JpegTurboDecoder class.
22 #include <unique_ptr.h>
23 #include <turbojpeg.h>
24 #include <FMediaImageTypes.h>
25 #include <FBaseSysLog.h>
26 #include "FMedia_JpegTurboDecoder.h"
28 namespace Tizen { namespace Media
31 _JpegTurboDecoder::_JpegTurboDecoder(void)
39 __decodingRectWidth = 0;
40 __decodingRectHeight = 0;
41 __isDecodeRegionEnabled = false;
42 __tjDecodingHandle = null;
43 __tjTransformHandle = null;
45 __subSamp = TJSAMP_444;
46 __requestPixelFormat = MEDIA_PIXEL_FORMAT_NONE;
49 _JpegTurboDecoder::~_JpegTurboDecoder(void)
51 if(__tjDecodingHandle)
53 tjDestroy(__tjDecodingHandle);
55 if(__tjTransformHandle)
57 tjDestroy(__tjTransformHandle);
62 _JpegTurboDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
67 __pSrcBuf = const_cast<byte*>(buffer);
68 __srcBufSize = length;
70 __requestPixelFormat = pixelFormat;
72 __tjDecodingHandle = tjInitDecompress();
73 SysTryCatch(NID_MEDIA, __tjDecodingHandle != null, r = E_SYSTEM, E_SYSTEM,
74 "[E_SYSTEM] Turbo JPEG InitDecompress failed : %s", tjGetErrorStr());
76 ret = tjDecompressHeader2(__tjDecodingHandle, __pSrcBuf, __srcBufSize, &__srcWidth, &__srcHeight, &__subSamp);
77 SysTryCatch(NID_MEDIA, ret == 0 , r = E_SYSTEM, E_SYSTEM,
78 "[E_SYSTEM] Turbo JPEG DecompressHeader2 failed : %s", tjGetErrorStr());
80 __tjTransformHandle = tjInitTransform();
81 SysTryCatch(NID_MEDIA, __tjDecodingHandle != null, r = E_SYSTEM, E_SYSTEM,
82 "[E_SYSTEM] Turbo JPEG InitTransform failed : %s", tjGetErrorStr());
87 if ( __tjDecodingHandle )
89 tjDestroy(__tjDecodingHandle);
90 __tjDecodingHandle = null;
92 if ( __tjTransformHandle )
94 tjDestroy(__tjTransformHandle);
95 __tjTransformHandle = null;
101 _JpegTurboDecoder::DecodeN(int& outLength)
105 int tjPixelFormat = 0;
106 byte* pTransBuf = null;
107 tjtransform cropInfo = {};
108 unsigned long dstSize;
109 std::unique_ptr<byte[]> pOutBuf;
111 buffSize = tjBufSize(__srcWidth, __srcHeight, TJSAMP_444);
112 SysTryReturn(NID_MEDIA, buffSize > 0, null, E_INVALID_DATA,
113 "[E_INVALID_DATA] Decoder returned buffer size (%d).", buffSize);
115 pOutBuf.reset(new (std::nothrow) byte[buffSize]);
116 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
117 "[E_OUT_OF_MEMORY] Could not allocate %d bytes.", buffSize);
119 if ( __requestPixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888)
121 tjPixelFormat = TJPF_RGBA;
125 tjPixelFormat = TJPF_BGRA;
127 if (__isDecodeRegionEnabled == true)
129 cropInfo.r.x = __decodingRectX;
130 cropInfo.r.y = __decodingRectY;
131 cropInfo.r.w = __decodingRectWidth;
132 cropInfo.r.h = __decodingRectHeight;
133 cropInfo.op = TJXOP_NONE;
134 cropInfo.options = TJXOPT_CROP;
136 ret = tjTransform(__tjTransformHandle, __pSrcBuf,__srcBufSize, 1, &pTransBuf, &dstSize, &cropInfo, 0);
137 SysTryReturn(NID_MEDIA, ret == 0, null, E_INVALID_DATA,
138 "[E_INVALID_DATA] Turbo JPEG Crop Failed : %s", tjGetErrorStr());
140 ret = tjDecompress2(__tjDecodingHandle, pTransBuf, __srcBufSize, pOutBuf.get(), __decodingRectWidth, __decodingRectWidth* tjPixelSize[tjPixelFormat], __decodingRectHeight, tjPixelFormat, 0);
141 SysTryReturn(NID_MEDIA, ret == 0, null, E_INVALID_DATA,
142 "[E_INVALID_DATA] Turbo JPEG Decompress Failed : %s", tjGetErrorStr());
144 outLength = __decodingRectWidth * __decodingRectHeight * tjPixelSize[tjPixelFormat];
148 ret = tjDecompress2(__tjDecodingHandle, __pSrcBuf, __srcBufSize, pOutBuf.get(), __srcWidth, __srcWidth* tjPixelSize[tjPixelFormat], __srcHeight, tjPixelFormat, 0);
149 SysTryReturn(NID_MEDIA, ret == 0, null, E_INVALID_DATA,
150 "[E_INVALID_DATA] Turbo JPEG Decompress Failed : %s", tjGetErrorStr());
151 outLength = __srcWidth * __srcHeight * tjPixelSize[tjPixelFormat];
154 SetLastResult(E_SUCCESS);
155 return pOutBuf.release();
159 _JpegTurboDecoder::SetDecodingRegion(int x, int y, int width, int height)
161 SysTryReturnResult(NID_MEDIA, ((x >= 0) && (y >= 0) && ((x + width) <= __srcWidth) && ((y + height) <= __srcHeight)),
163 "Invalid Input - Check dimensions and coordinates (x, y) = (%d, %d), width (%d), height (%d), Image dimensions (%d x %d)",
164 x, y, width, height, __srcWidth, __srcHeight);
165 SysTryReturnResult(NID_MEDIA, (!(x%tjMCUWidth[__subSamp]) && !(y%tjMCUHeight[__subSamp])), E_UNSUPPORTED_OPERATION,
166 "To crop this JPEG image using JpegTurbo decoder, x must be a multiple of %d and y must be a multiple of %d",
167 tjMCUWidth[__subSamp], tjMCUHeight[__subSamp]);
170 __decodingRectWidth = width;
171 __decodingRectHeight = height;
172 __isDecodeRegionEnabled = true;
177 _JpegTurboDecoder::GetDimension(int& width, int& height)
180 height = __srcHeight;
186 _JpegTurboDecoder::GetPixelFormat(void)
188 if ( __requestPixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888)
190 return MEDIA_PIXEL_FORMAT_RGBA8888;
194 return MEDIA_PIXEL_FORMAT_BGRA8888;
199 _JpegTurboDecoder::SetScaleDown(int scaleDown)
206 _JpegTurboDecoder::GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
208 return E_UNSUPPORTED_OPERATION;