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_TiffDecoder.c
20 * @brief This file contains the implementation of _TiffDecoder class.
22 #include <unique_ptr.h>
23 #include <FMediaImageTypes.h>
24 #include <FBaseSysLog.h>
25 #include "FMedia_TiffDecoder.h"
27 using namespace Tizen::Io;
28 using namespace Tizen::Base::Collection;
30 namespace Tizen { namespace Media
33 _TiffDecoder::_TiffDecoder(void)
41 _TiffDecoder::~_TiffDecoder(void)
43 if (__pTiffMemory->pData != null)
45 delete[] __pTiffMemory->pData;
46 __pTiffMemory->pData = null;
49 if (__pTiffHandle != null)
51 TIFFClose(__pTiffHandle);
56 // Tiff call back functions for buffer handling.
58 _TiffDecoder::TiffCbReadData(thandle_t handle, tdata_t pData, tsize_t size)
60 _TiffMemory *pTiffMem = (_TiffMemory*)handle;
61 if (size <= pTiffMem->left)
63 unsigned char *pFrom = pTiffMem->pData + pTiffMem->point;
64 memcpy(pData, pFrom, size);
65 pTiffMem->left = pTiffMem->left - size;
66 pTiffMem->point = pTiffMem->point + size;
73 _TiffDecoder::TiffCbSeekData(thandle_t handle, toff_t amount, int indication)
75 _TiffMemory *pTiffMem = (_TiffMemory*)handle;
79 if (amount <= pTiffMem->size)
81 pTiffMem->point = amount;
82 pTiffMem->left = pTiffMem->size - amount;
91 if (pTiffMem->left - amount <= (signed int)pTiffMem->size || pTiffMem->left >= amount)
93 pTiffMem->point = pTiffMem->point + amount;
94 pTiffMem->left = pTiffMem->left - amount;
103 if (amount >= -pTiffMem->size && amount <= 0)
105 pTiffMem->point = pTiffMem->size - amount;
106 pTiffMem->left = amount;
122 _TiffDecoder::TiffCbGetSize(thandle_t handle)
124 _TiffMemory *pTiffMem = (_TiffMemory*)handle;
125 return pTiffMem->size;
129 _TiffDecoder::TiffCbMemClose(thandle_t)
136 _TiffDecoder::TiffCbMemMapFileproc(thandle_t, tdata_t*, toff_t*)
143 _TiffDecoder::TiffCbMemUnMapFileProc(thandle_t, tdata_t, toff_t)
149 // _TiffDecoder functions.
151 _TiffDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
153 result r = E_SUCCESS;
155 SysTryReturnResult(NID_MEDIA, buffer != null, E_INVALID_ARG,
156 "Input buffer is null");
158 __pTiffMemory = std::unique_ptr<_TiffMemory> (new (std::nothrow)_TiffMemory);
159 SysTryReturnResult(NID_MEDIA, __pTiffMemory.get() != null, E_OUT_OF_MEMORY,
160 "Failed to create _TiffMemory structure.");
162 __pTiffMemory->pData = new (std::nothrow) byte[length];
163 SysTryCatch(NID_MEDIA, __pTiffMemory->pData != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
164 "[E_OUT_OF_MEMORY] Failed to allocate _TiffMemory->pData: %d bytes.", length);
166 memcpy(__pTiffMemory->pData, buffer, length);
168 __pTiffMemory->size = length;
169 __pTiffMemory->left = length;
170 __pTiffMemory->point = 0;
172 __pTiffHandle = TIFFClientOpen("dummy", "r", (void *)__pTiffMemory.get(),
173 TiffCbReadData, TiffCbReadData,
174 TiffCbSeekData, TiffCbMemClose,
176 TiffCbMemMapFileproc, TiffCbMemUnMapFileProc);
177 SysTryCatch(NID_MEDIA, __pTiffHandle != null, r = E_SYSTEM, E_SYSTEM,
178 "[E_SYSTEM] TIFFClientOpen failed.");
180 TIFFGetField(__pTiffHandle, TIFFTAG_IMAGEWIDTH, &__width);
181 SysTryCatch(NID_MEDIA, __width > 0, r = E_SYSTEM, E_SYSTEM,
182 "[E_SYSTEM] Check image, width is zero.");
183 TIFFGetField(__pTiffHandle, TIFFTAG_IMAGELENGTH, &__height);
184 SysTryCatch(NID_MEDIA, __height > 0, r = E_SYSTEM, E_SYSTEM,
185 "[E_SYSTEM] Check image, height is zero.");
191 if (__pTiffMemory->pData != null)
193 delete[] __pTiffMemory->pData;
194 __pTiffMemory->pData = null;
200 _TiffDecoder::DecodeN(int& outLength)
205 byte* pTempDstPtr = null;
206 byte* pTempSrcPtr = null;
208 std::unique_ptr<byte[]> pTempDecodeBuf;
209 std::unique_ptr<byte[]> pOutBuf;
210 SysTryReturn(NID_MEDIA, __pTiffHandle != null, null, E_INVALID_STATE,
211 "Instance is not constructed.");
213 outLength = __width * __height * BYTES_PER_PIXEL_RGBA;
214 pTempDecodeBuf.reset(new (std::nothrow) byte[outLength]);
215 SysTryReturn(NID_MEDIA, pTempDecodeBuf.get() != null, null, E_OUT_OF_MEMORY,
216 "[E_OUT_OF_MEMORY] Could not allocate %d bytes for temp buffer!", outLength);
218 pOutBuf.reset(new (std::nothrow) byte[outLength]);
219 SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
220 "[E_OUT_OF_MEMORY] Could not allocate %d bytes for temp buffer!", outLength);
222 tiffRet = TIFFReadRGBAImage(__pTiffHandle, __width, __height, (uint32*)pTempDecodeBuf.get(), 0);
223 SysTryReturn(NID_MEDIA, tiffRet == 1, null, E_SYSTEM,
224 "[E_SYSTEM] TIFFReadRGBAImage failed.");
226 rowSize = __width * BYTES_PER_PIXEL_RGBA;
227 pTempDstPtr = pOutBuf.get() + ((__height - 1) * rowSize);
228 pTempSrcPtr = pTempDecodeBuf.get();
230 // libtiff returns a vertically flipped image.
231 for (row = 0; row < __height; row++)
233 memcpy(pTempDstPtr, pTempSrcPtr, rowSize);
234 pTempDstPtr -= rowSize;
235 pTempSrcPtr += rowSize;
237 SetLastResult(E_SUCCESS);
238 return pOutBuf.release();
242 _TiffDecoder::SetDecodingRegion(int x, int y, int width, int height)
244 return E_UNSUPPORTED_OPERATION;
248 _TiffDecoder::GetDimension(int& width, int& height)
250 SysTryReturnResult(NID_MEDIA, __pTiffHandle != null, E_INVALID_STATE, "Instance is not constructed.");
255 SetLastResult(E_SUCCESS);
260 _TiffDecoder::GetPixelFormat(void)
262 MediaPixelFormat pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
264 pixelFormat = MEDIA_PIXEL_FORMAT_RGBA8888;
266 SetLastResult(E_SUCCESS);