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_JpegDecoder.cpp
20 * @brief This file contains the implementation of _JpegDecoder class.
26 #include <FMediaImageTypes.h>
27 #include <FBaseSysLog.h>
28 #include "FMedia_JpegDecoder.h"
30 namespace Tizen { namespace Media
33 _JpegDecoder::_JpegDecoder(void)
41 __decodingRectWidth = 0;
42 __decodingRectHeight = 0;
43 __isDecodeRegionEnabled = false;
50 _JpegDecoder::~_JpegDecoder(void)
52 // SAFE_DELETE_ARRAY(__pSrcBuf);
55 jpeg_destroy_decompress(__pDec);
73 _JpegDecoder::JpegErrorExitStatic(struct jpeg_common_struct * pDecInfo)
77 _JpegDecoder *pDec = (_JpegDecoder*)pDecInfo->client_data;
80 pDec->JpegErrorExit();
86 _JpegDecoder::JpegErrorExit(void)
92 _JpegDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
96 SysTryReturnResult(NID_MEDIA, __pDec == null, E_INVALID_STATE, "Already constructed");
98 // TODO: do not copy the source data
99 //__pSrcBuf = new (std::nothrow) byte[length];
100 //SysTryCatch(NID_MEDIA, __pSrcBuf != null, r = E_SYSTEM, E_SYSTEM,
101 // "[E_SYSTEM] new byte:%d", length);
102 // memcpy(__pSrcBuf, buffer, length);
103 __pSrcBuf = (byte*)buffer;
104 __srcBufSize = length;
106 __pDec = new (std::nothrow) jpeg_decompress_struct;
107 SysTryCatch(NID_MEDIA, __pDec != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
108 "[E_OUT_OF_MEMORY] new ", sizeof(jpeg_decompress_struct));
109 __pErr = new (std::nothrow) jpeg_error_mgr;
110 SysTryCatch(NID_MEDIA, __pErr != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
111 "[E_OUT_OF_MEMORY] new ", sizeof(jpeg_error_mgr));
112 __pJmp = new (std::nothrow) __jmp_buf_tag;
113 SysTryCatch(NID_MEDIA, __pJmp != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
114 "[E_OUT_OF_MEMORY] new ", sizeof(__jmp_buf_tag));
116 memset(__pDec, 0, sizeof(jpeg_decompress_struct));
117 memset(__pErr, 0, sizeof(jpeg_error_mgr));
118 memset(__pJmp, 0, sizeof(__jmp_buf_tag));
121 __pDec->err = jpeg_std_error(__pErr);
122 __pErr->error_exit = JpegErrorExitStatic;
123 __pDec->client_data = this;
125 SysTryCatch(NID_MEDIA, !setjmp(__pJmp), r = E_INVALID_DATA, E_INVALID_DATA,
126 "[E_INVALID_DATA] error jump");
128 jpeg_create_decompress(__pDec);
130 // Specify data source for decompression
131 jpeg_mem_src(__pDec, (JOCTET*) __pSrcBuf, __srcBufSize);
133 // Read file header, set default decompression parameters
134 jpeg_read_header(__pDec, TRUE);
136 __srcWidth = __pDec->image_width;
137 __srcHeight = __pDec->image_height;
142 //SAFE_DELETE_ARRAY(__pSrcBuf);
145 jpeg_destroy_decompress(__pDec);
151 _JpegDecoder::DecodeN(int& length)
156 byte* pReturnBuf = null;
160 result r = E_SUCCESS;
162 SysTryCatch(NID_MEDIA, !setjmp(__pJmp), r = E_INVALID_DATA, E_INVALID_DATA,
163 "[E_INVALID_DATA] error jump");
165 // Set decoding option
166 if (__pDec->jpeg_color_space == JCS_GRAYSCALE)
168 __pDec->out_color_space = JCS_GRAYSCALE;
170 else if (__pDec->jpeg_color_space == JCS_YCCK) // YCCK
172 __pDec->out_color_space = JCS_YCCK;
176 __pDec->out_color_space = JCS_YCbCr;
179 // Start decompressor
180 jpeg_start_decompress(__pDec);
182 // Write output buffer
183 __srcWidth = __pDec->output_width;
184 __srcHeight = __pDec->output_height;
186 if (__pDec->output_components == 1) // for grayscale
188 if (__isDecodeRegionEnabled == true)
190 int row_stride = __pDec->output_width;
191 buffSize = __decodingRectWidth * __decodingRectHeight * 3;
193 JSAMPARRAY buffer = (*__pDec->mem->alloc_sarray)((struct jpeg_common_struct *) __pDec, JPOOL_IMAGE, row_stride, 1);
195 pReturnBuf = new (std::nothrow) byte[buffSize];
196 SysTryCatch(NID_MEDIA, pReturnBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
197 "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", buffSize);
199 // Initialize cb and cr to 128, since they need not be considered for gray scale image.
200 memset(pReturnBuf, 128, buffSize);
203 while (__pDec->output_scanline < (__decodingRectY + __decodingRectHeight))
205 jpeg_read_scanlines(__pDec, buffer, 1);
206 if (h >= __decodingRectY)
209 for (int x = __decodingRectX; x < __decodingRectX + __decodingRectWidth; x++)
211 JSAMPLE* p = buffer[0] + x;
214 pReturnBuf[(__decodingRectWidth * outY) + outX] = p[0]; // Y
221 else // if not decoding a region
223 int row_stride = __pDec->output_width;
224 buffSize = __pDec->output_width * __pDec->output_height * 3;
226 JSAMPARRAY buffer = (*__pDec->mem->alloc_sarray)((struct jpeg_common_struct *) __pDec, JPOOL_IMAGE, row_stride, 1);
228 pReturnBuf = new (std::nothrow) byte[buffSize];
229 SysTryCatch(NID_MEDIA, pReturnBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
230 "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", buffSize);
232 // Initialize cb and cr to 128, since they need not be considered for gray scale image.
233 memset(pReturnBuf, 128, buffSize);
236 while (__pDec->output_scanline < __pDec->output_height)
238 jpeg_read_scanlines(__pDec, buffer, 1);
240 for (unsigned int x = 0; x < __pDec->output_width; x++)
242 JSAMPLE* p = buffer[0] + x;
244 pReturnBuf[(__pDec->output_width * h) + x] = p[0]; // Y
250 else if (__pDec->output_components == 4) // YCCK. Need to handle CMYK also.
252 if (__isDecodeRegionEnabled == true)
254 buffSize = __decodingRectWidth * __decodingRectHeight * 3;
255 planarSize = (__decodingRectWidth * __decodingRectHeight);
257 int row_stride = __pDec->output_width * __pDec->output_components;
258 JSAMPARRAY buffer = (*__pDec->mem->alloc_sarray)((struct jpeg_common_struct *) __pDec, JPOOL_IMAGE, row_stride, 1);
260 pReturnBuf = new (std::nothrow) byte[buffSize];
261 SysTryCatch(NID_MEDIA, pReturnBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
262 "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", buffSize);
264 memset(pReturnBuf, 0, buffSize);
267 while (__pDec->output_scanline < (__decodingRectY + __decodingRectHeight))
269 jpeg_read_scanlines(__pDec, buffer, 1);
270 if (h >= __decodingRectY)
273 for (int x = __decodingRectX; x < __decodingRectX + __decodingRectWidth; x++)
275 JSAMPLE* p = buffer[0] + (__pDec->output_components * x);
278 pReturnBuf[(__decodingRectWidth * outY) + outX] = 255 - p[0]; // Y
279 pReturnBuf[(__decodingRectWidth * outY) + planarSize + outX] = 255 - p[1]; // Cb
280 pReturnBuf[(__decodingRectWidth * outY) + (planarSize * 2) + outX] = 255 - p[2];// Cr
290 buffSize = __pDec->output_width * __pDec->output_height * 3;
291 planarSize = __pDec->output_width * __pDec->output_height;
293 int row_stride = __pDec->output_width * __pDec->output_components;
294 JSAMPARRAY buffer = (*__pDec->mem->alloc_sarray)((struct jpeg_common_struct *) __pDec, JPOOL_IMAGE, row_stride, 1);
296 pReturnBuf = new (std::nothrow) byte[buffSize];
297 SysTryCatch(NID_MEDIA, pReturnBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
298 "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", buffSize);
300 memset(pReturnBuf, 0, buffSize);
303 while (__pDec->output_scanline < __pDec->output_height)
305 jpeg_read_scanlines(__pDec, buffer, 1);
307 for (unsigned int x = 0; x < __pDec->output_width; x++)
309 JSAMPLE* p = buffer[0] + (__pDec->output_components * x);
312 pReturnBuf[(__pDec->output_width * h) + x] = 255 - p[0]; // Y
313 pReturnBuf[(__pDec->output_width * h) + planarSize + x] = 255 - p[1]; // Cb
314 pReturnBuf[(__pDec->output_width * h) + (planarSize * 2) + x] = 255 - p[2]; // Cr
320 else // (__pDec->output_components == 3) YUV444
322 if (__isDecodeRegionEnabled == true)
324 buffSize = __decodingRectWidth * __decodingRectHeight * __pDec->output_components;
325 planarSize = (__decodingRectWidth * __decodingRectHeight);
327 int row_stride = __pDec->output_width * __pDec->output_components;
328 JSAMPARRAY buffer = (*__pDec->mem->alloc_sarray)((struct jpeg_common_struct *) __pDec, JPOOL_IMAGE, row_stride, 1);
330 pReturnBuf = new (std::nothrow) byte[buffSize];
331 SysTryCatch(NID_MEDIA, pReturnBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
332 "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", buffSize);
334 memset(pReturnBuf, 0, buffSize);
337 while (__pDec->output_scanline < (__decodingRectY + __decodingRectHeight))
339 jpeg_read_scanlines(__pDec, buffer, 1);
340 if (h >= __decodingRectY)
343 for (int x = __decodingRectX; x < __decodingRectX + __decodingRectWidth; x++)
345 JSAMPLE* p = buffer[0] + 3 * x;
348 pReturnBuf[(__decodingRectWidth * outY) + outX] = p[0]; // Y
349 pReturnBuf[(__decodingRectWidth * outY) + planarSize + outX] = p[1]; // Cb
350 pReturnBuf[(__decodingRectWidth * outY) + (planarSize * 2) + outX] = p[2]; // Cr
360 buffSize = __pDec->output_width * __pDec->output_height * __pDec->output_components;
361 planarSize = __pDec->output_width * __pDec->output_height;
363 int row_stride = __pDec->output_width * __pDec->output_components;
364 JSAMPARRAY buffer = (*__pDec->mem->alloc_sarray)((struct jpeg_common_struct *) __pDec, JPOOL_IMAGE, row_stride, 1);
366 pReturnBuf = new (std::nothrow) byte[buffSize];
367 SysTryCatch(NID_MEDIA, pReturnBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
368 "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", buffSize);
370 memset(pReturnBuf, 0, buffSize);
373 while (__pDec->output_scanline < __pDec->output_height)
375 jpeg_read_scanlines(__pDec, buffer, 1);
377 for (unsigned int x = 0; x < __pDec->output_width; x++)
379 JSAMPLE* p = buffer[0] + 3 * x;
382 pReturnBuf[(__pDec->output_width * h) + x] = p[0]; // Y
383 pReturnBuf[(__pDec->output_width * h) + planarSize + x] = p[1]; // Cb
384 pReturnBuf[(__pDec->output_width * h) + (planarSize * 2) + x] = p[2]; // Cr
392 SetLastResult(E_SUCCESS);
398 _JpegDecoder::SetDecodingRegion(int x, int y, int width, int height)
400 SysTryReturnResult(NID_MEDIA, ((x >= 0) && (y >= 0) && ((x + width) <= __srcWidth) && ((y + height) <= __srcHeight)), E_INVALID_ARG,
401 "Invalid Input - %d %d %d %d src_width - %d src_height - %d", x, y, width, height, __srcWidth, __srcHeight);
404 __decodingRectWidth = width;
405 __decodingRectHeight = height;
406 __isDecodeRegionEnabled = true;
411 _JpegDecoder::GetDimension(int& width, int& height)
414 height = __srcHeight;
420 _JpegDecoder::GetPixelFormat(void)
422 return MEDIA_PIXEL_FORMAT_YUV444P;
426 _JpegDecoder::SetScaleDown(int scaleDown)
433 _JpegDecoder::GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
435 return E_UNSUPPORTED_OPERATION;