SET(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/cmake_build_tmp/output)
INCLUDE_DIRECTORIES(
- inc
- src
- src/inc
- /usr/include/chromium
- /usr/include/ecore-1
- /usr/include/eina-1
- /usr/include/eina-1/eina
- /usr/include/evas-1
- /usr/include/media
+ inc
+ src
+ src/inc
+ /usr/include/chromium
+ /usr/include/ecore-1
+ /usr/include/eina-1
+ /usr/include/eina-1/eina
+ /usr/include/evas-1
+ /usr/include/media
/usr/include/osp
/usr/include/osp/base
/usr/include/osp/app
src/FMedia_BmpEncoder.cpp
src/FMedia_SlpUtil.cpp
src/FMedia_MediaUtil.cpp
+ src/FMedia_ExifUtil.cpp
+ src/FMedia_Ffmpeg.cpp
)
## Definitions
TARGET_LINK_LIBRARIES(${this_target} "-L/usr/lib/osp -losp-appfw" )
TARGET_LINK_LIBRARIES(${this_target} "-lglib-2.0" )
TARGET_LINK_LIBRARIES(${this_target} "-leina" )
-TARGET_LINK_LIBRARIES(${this_target} "-lnetwork" )
TARGET_LINK_LIBRARIES(${this_target} "-lcurl" )
TARGET_LINK_LIBRARIES(${this_target} "-lpng -lz" )
TARGET_LINK_LIBRARIES(${this_target} "-lavcodec" )
TARGET_LINK_LIBRARIES(${this_target} "-lcapi-media-image-util" )
TARGET_LINK_LIBRARIES(${this_target} "-lturbojpeg" )
TARGET_LINK_LIBRARIES(${this_target} "-ltiff" )
-
+TARGET_LINK_LIBRARIES(${this_target} "-lexif" )
SET_TARGET_PROPERTIES(${this_target}
PROPERTIES
)
ADD_CUSTOM_COMMAND(TARGET ${this_target}
- POST_BUILD
+ POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${LIBRARY_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX} ${LIBRARY_OUTPUT_PATH}/debug/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX}.${FULLVER}
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX}.${FULLVER} ${LIBRARY_OUTPUT_PATH}/debug/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX}.${MAJORVER}
COMMAND ${CMAKE_STRIP} --strip-unneeded ${LIBRARY_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX}
INSTALL(DIRECTORY ${LIBRARY_OUTPUT_PATH}/ DESTINATION lib/osp
FILES_MATCHING PATTERN "*.so*"
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
- GROUP_EXECUTE GROUP_READ
- WORLD_EXECUTE WORLD_READ)
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ)
INSTALL(DIRECTORY ${LIBRARY_OUTPUT_PATH}/debug/ DESTINATION lib/osp/debug
FILES_MATCHING PATTERN "*"
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
//
/**
- * @file FMediaImageTypes.h
+ * @file FMediaImageTypes.h
* @brief This is the header file for the common types of the Image class.
*
* This header file contains the declarations of the enumerations for the Image class.
IMAGE_ROTATION_90, /**< The 90 degree rotation in clockwise direction */
IMAGE_ROTATION_180, /**< The 180 degree rotation in clockwise direction */
IMAGE_ROTATION_270, /**< The 270 degree rotation in clockwise direction */
-} ;
+};
/**
* @enum ImageFlipType
IMAGE_FLIP_NONE = 0x00, /**< The no-flip type */
IMAGE_FLIP_HORIZONTAL, /**< The horizontal flip */
IMAGE_FLIP_VERTICAL, /**< The vertical flip */
-} ;
+};
/**
* @enum MediaPixelFormat
MEDIA_PIXEL_FORMAT_YUV420P = 0x0200, /**< The YUV420 Planar format */
MEDIA_PIXEL_FORMAT_NV12, /**< The NV12 format */
MEDIA_PIXEL_FORMAT_NV12_TILE, /**< The NV12 tiled format */
- MEDIA_PIXEL_FORMAT_NV21, /**< @if OSPCOMPAT @since 2.0 @endif The NV21 format */
- MEDIA_PIXEL_FORMAT_YUV444P, /**< @if OSPCOMPAT @since 2.0 @endif The YUV444 Planar format */
- MEDIA_PIXEL_FORMAT_YUYV422, /**< @if OSPCOMPAT @since 2.0 @endif The YUYV422 format */
- MEDIA_PIXEL_FORMAT_UYVY422, /**< @if OSPCOMPAT @since 2.0 @endif The UYVY422 format */
- MEDIA_PIXEL_FORMAT_GRAY, /**< @if OSPCOMPAT @since 2.0 @endif The gray pixel format */
+ MEDIA_PIXEL_FORMAT_NV21, /**< @since 2.0 The NV21 format */
+ MEDIA_PIXEL_FORMAT_YUV444P, /**< @since 2.0 The YUV444 Planar format */
+ MEDIA_PIXEL_FORMAT_YUYV422, /**< @since 2.0 The YUYV422 format */
+ MEDIA_PIXEL_FORMAT_UYVY422, /**< @since 2.0 The UYVY422 format */
+ MEDIA_PIXEL_FORMAT_GRAY, /**< @since 2.0 The gray pixel format */
+};
+
+/**
+ * @enum ImageScalingMethod
+ *
+ * Defines the image sacling method.
+ *
+ * @since 2.1
+ */
+enum ImageScalingMethod
+{
+ IMAGE_SCALING_METHOD_FAST_BILINEAR, /** fast bilinear interpolation method */
+ IMAGE_SCALING_METHOD_BILINEAR, /** bilinear interpolation method */
+ IMAGE_SCALING_METHOD_BICUBIC, /** bicubic interpolation method */
+};
+
+/**
+ * @enum ExifOrientation
+ *
+ * Defines the image's EXIF orientation flags.
+ *
+ * @since 2.1
+ */
+enum ExifOrientation
+{
+ EXIF_ORIENTATION_TOP_LEFT = 0x01, /**< The row #0 is top, column #0 is left */
+ EXIF_ORIENTATION_TOP_RIGHT, /**< The row #0 is top, column #0 is right */
+ EXIF_ORIENTATION_BOTTOM_RIGHT, /**< The row #0 is bottom, column #0 is right */
+ EXIF_ORIENTATION_BOTTOM_LEFT, /**< The row #0 is bottom, column #0 is left */
+ EXIF_ORIENTATION_LEFT_TOP, /**< The row #0 is left, column #0 is top */
+ EXIF_ORIENTATION_RIGHT_TOP, /**< The row #0 is right, column #0 is top */
+ EXIF_ORIENTATION_RIGHT_BOTTOM, /**< The row #0 is right, column #0 is bottom */
+ EXIF_ORIENTATION_LEFT_BOTTOM, /**< The row #0 is left, column #0 is bottom */
};
};
Name: osp-image-core
Summary: The Media Image Core library of OSP
-Version: 1.2.0.0
+Version: 1.2.1.0
Release: 1
Group: TO_BE/FILLED_IN
License: TO BE FILLED IN
BuildRequires: pkgconfig(libavutil)
BuildRequires: pkgconfig(libswscale)
BuildRequires: pkgconfig(pango)
+BuildRequires: pkgconfig(evas)
+BuildRequires: pkgconfig(libpng)
BuildRequires: giflib-devel
BuildRequires: libjpeg-turbo-devel
BuildRequires: libtiff-devel
+BuildRequires: libexif-devel
# runtime requires
Requires: osp-appfw
result r = E_SUCCESS;
int res = 0;
- //avcodec_init();
avcodec_register_all();
- __pCodecCtx = avcodec_alloc_context();
- SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_SYSTEM, E_SYSTEM,
- "[E_SYSTEM] avcodec context allocation failed.");
-
__pCodec = avcodec_find_decoder(CODEC_ID_BMP);
- SysTryCatch(NID_MEDIA, __pCodec != null, r = E_SYSTEM, E_SYSTEM,
- "[E_SYSTEM] Failed to find bmp decoder.");
+ SysTryReturnResult(NID_MEDIA, __pCodec != null, E_UNSUPPORTED_CODEC, "Failed to find bmp decoder.");
+
+ __pCodecCtx = avcodec_alloc_context3(__pCodec);
+ SysTryReturnResult(NID_MEDIA, __pCodecCtx != null, E_OUT_OF_MEMORY, "context allocation failed.");
- res = avcodec_open(__pCodecCtx, __pCodec);
+ res = avcodec_open2(__pCodecCtx, __pCodec, null);
SysTryCatch(NID_MEDIA, res >= 0, r = E_SYSTEM, E_SYSTEM,
"[E_SYSTEM] Failed to open bmp decoder.");
result
_BmpDecoder::GetDimension(int& width, int& height)
{
- result r = E_SUCCESS;
+ SysTryReturnResult(NID_MEDIA, __pCodecCtx, E_INVALID_STATE, "Not Constructed.");
- SysTryCatch(NID_MEDIA, __pCodecCtx, r = E_INVALID_STATE,
- E_INVALID_STATE, "[E_INVALID_STATE] Not Constructed.");
+ SysTryReturnResult(NID_MEDIA, __pCodecCtx->width > 0 && __pCodecCtx->height > 0, E_INVALID_STATE,
+ "Invalid dimensions : (%d x %d)", __pCodecCtx->width, __pCodecCtx->height);
width = __pCodecCtx->width;
height = __pCodecCtx->height;
- if ((width <= 0) || (height <= 0))
- {
- SysLog(NID_MEDIA, "Invalid dimensions! Should be greater than zero : (%d x %d)", width, height);
- r = E_SYSTEM;
- }
-
-CATCH:
- return r;
+ return E_SUCCESS;
}
MediaPixelFormat
_BmpDecoder::GetPixelFormat(void)
{
- result r = E_SUCCESS;
MediaPixelFormat pixel_format = MEDIA_PIXEL_FORMAT_NONE;
SysTryReturn(NID_MEDIA, __pCodecCtx, pixel_format, E_INVALID_STATE,
#include "FMedia_BmpEncoder.h"
#include "FMedia_ImageUtil.h"
+using namespace std;
using namespace Tizen::Base;
namespace Tizen { namespace Media
{
+
_BmpEncoder::_BmpEncoder(void)
{
__pCodecCtx = null;
MediaPixelFormat& reqPixelFormat,
int quality)
{
- result r = E_SUCCESS;
+ int res;
SysTryReturnResult(NID_MEDIA, width >= MIN_WIDTH, E_INVALID_ARG,
"Width (%d) < minimum bmp width (%d)", width, MIN_WIDTH);
SysTryReturnResult(NID_MEDIA, quality <= 100, E_INVALID_ARG,
"Quality should be lesser than 100 (%d)", quality);
+ // TODO: add BGRA8888 support
__width = width;
__height = height;
__quality = quality;
reqPixelFormat = MEDIA_PIXEL_FORMAT_BGR888;
__quality = quality;
- r = OpenCodec(width, height, __pixelFormat);
- SysTryCatch(NID_MEDIA, (r == E_SUCCESS), r = E_SYSTEM, E_SYSTEM, "Failed to initialize FFMPEG.");
-
- return E_SUCCESS;
-CATCH:
- return r;
-}
-
-result
-_BmpEncoder::OpenCodec(int width, int height, MediaPixelFormat pixelFormat)
-{
- result r = E_SUCCESS;
- int res = 0;
-
- //avcodec_init();
avcodec_register_all();
- __pCodecCtx = avcodec_alloc_context();
- SysTryCatch(NID_MEDIA, __pCodecCtx != null, r = E_SYSTEM, E_SYSTEM,
- "[E_SYSTEM] avcodec context allocation failed.");
-
__pCodec = avcodec_find_encoder(CODEC_ID_BMP);
- SysTryCatch(NID_MEDIA, __pCodec != null, r = E_SYSTEM, E_SYSTEM,
- "[E_SYSTEM] Failed to find bmp decoder.");
+ SysTryReturnResult(NID_MEDIA, __pCodec != null, E_UNSUPPORTED_CODEC, "Failed to find bmp encoder.");
+
+ __pCodecCtx = avcodec_alloc_context3(__pCodec);
+ SysTryReturnResult(NID_MEDIA, __pCodecCtx != null, E_OUT_OF_MEMORY, "context allocation failed.");
// Context required for opening BMP encoder.
// Specifying output image format
- __pCodecCtx->pix_fmt = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(pixelFormat);
+ __pCodecCtx->pix_fmt = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(__pixelFormat);
// Dimensions of the image
__pCodecCtx->height = height;
__pCodecCtx->width = width;
- res = avcodec_open(__pCodecCtx, __pCodec);
- SysTryCatch(NID_MEDIA, res >= 0, r = E_SYSTEM, E_SYSTEM,
- "[E_SYSTEM] Failed to open bmp decoder.");
-
- return r;
-
-CATCH:
- CloseCodec();
- return r;
-}
+ res = avcodec_open2(__pCodecCtx, __pCodec, null);
+ SysTryReturnResult(NID_MEDIA, res >= 0, E_OUT_OF_MEMORY, "codec open failed:%d", res);
-void
-_BmpEncoder::CloseCodec(void)
-{
- if (__pCodecCtx)
- {
- avcodec_close(__pCodecCtx);
- av_free(__pCodecCtx);
- __pCodecCtx = null;
- __pCodec = null;
- }
+ return E_SUCCESS;
}
Tizen::Base::ByteBuffer*
-_BmpEncoder::EncodeN(const byte* srcBuf, int srcLength)
+_BmpEncoder::EncodeN(const byte* pSrcBuf, int srcLength)
{
result r = E_SUCCESS;
- int outSize = 0;
- int widthPadding = 0;
- int tmpDstLength = 0;
- AVFrame* pVideoFrame = null;
- std::unique_ptr<uint8_t[]> pInputData;
- std::unique_ptr<byte[]> pTmpDstBuf;
- std::unique_ptr<ByteBuffer> pRetBuf;
+ int ret = 0;
+ unique_ptr<AVFrame, _FfmpegDeleter> pVideoFrame(avcodec_alloc_frame(), ffmpegDeleter);
+ unique_ptr<ByteBuffer> pRetBuf(new (std::nothrow) ByteBuffer());
+ unique_ptr<AVPacket, _FfmpegDeleter> pPkt(new (std::nothrow) AVPacket, ffmpegDeleter);
+ int gotOutput;
// TODO: apply pixel format
- SysTryCatch(NID_MEDIA, (srcBuf != null && srcLength > 0), r = E_INVALID_ARG, E_INVALID_ARG,
- "[E_INVALID_ARG] Encode Failed. Check inputs.");
-
- pInputData.reset(new (std::nothrow) byte[srcLength + FF_PADDING_BYTES]);
- SysTryCatch(NID_MEDIA, (pInputData.get() != null), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
- "[E_OUT_OF_MEMORY] Could not allocate memory for input to encoder.");
+ SysTryReturn(NID_MEDIA, pSrcBuf != null && srcLength > 0, null, E_INVALID_ARG,
+ "[E_INVALID_ARG] pSrcBuf=0x%x srcLength=%d", pSrcBuf, srcLength);
- memcpy(pInputData.get(), srcBuf, srcLength);
- memset(pInputData.get() + srcLength, 0, FF_PADDING_BYTES);
-
- pVideoFrame = avcodec_alloc_frame();
- SysTryCatch(NID_MEDIA, (pVideoFrame != null), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
- "[E_OUT_OF_MEMORY] Could not allocate memory for encoder output.");
+ SysTryReturn(NID_MEDIA, pVideoFrame.get() != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] avcodec_alloc_frame() failed");
+ SysTryReturn(NID_MEDIA, pRetBuf.get() != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] new ByteBuffer() failed.");
+ SysTryReturn(NID_MEDIA, pPkt.get() != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] new AVPacket failed.");
// Input buffer is a BGR888, so no need for explicit color conversion
// to BGR888.
// pVideoFrame is the input to encoder.
- pVideoFrame->data[0] = (uint8_t*) pInputData.get();
+ pVideoFrame->data[0] = (uint8_t*)pSrcBuf;
pVideoFrame->data[1] = 0;
pVideoFrame->data[2] = 0;
pVideoFrame->data[3] = 0;
pVideoFrame->linesize[2] = 0;
pVideoFrame->linesize[3] = 0;
- // BMP images have width 4 byte aligned. So, if image width is not a
- // multiple of 4, every row will be padded to make it a multiple of 4.
- // extraBytes = ((dim.width * 3) % 4)
- widthPadding = ((__width * BYTES_PER_PIXEL_RGB) % 4);
- if (widthPadding)
- {
- widthPadding = 4 - widthPadding;
- }
+ av_init_packet(pPkt.get());
+ pPkt->data = NULL; // packet data will be allocated by the encoder
+ pPkt->size = 0;
+ gotOutput = 0;
- tmpDstLength = BMP_HEADER_SIZE_
- + (((__width * BYTES_PER_PIXEL_RGB) + widthPadding) * __height);
+ ret = avcodec_encode_video2(__pCodecCtx, pPkt.get(), pVideoFrame.get(), &gotOutput);
+ SysTryReturn(NID_MEDIA, ret >= 0 && gotOutput > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] Encode Failed:%d %d", ret, gotOutput);
- // Check if destination buffer length is lesser than the minimum buffer size
- // supported by ffmpeg. If not, pass a buffer of size equal to the minimum size.
- if (tmpDstLength < FF_MIN_BUFFER_SIZE)
- {
- tmpDstLength = FF_MIN_BUFFER_SIZE;
- }
+ r = pRetBuf->Construct(pPkt->size);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ByteBuffer.Construct(%d) failed", GetErrorMessage(r), pPkt->size);
- pTmpDstBuf.reset(new (std::nothrow) byte[tmpDstLength]);
- SysTryCatch(NID_MEDIA, (pTmpDstBuf.get() != null), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
- "[E_OUT_OF_MEMORY] Could not allocate memory for encoder output.");
-
- outSize = avcodec_encode_video(__pCodecCtx, (uint8_t*) pTmpDstBuf.get(), (tmpDstLength), pVideoFrame);
- SysTryCatch(NID_MEDIA, outSize > 0, r = E_INVALID_ARG, E_INVALID_ARG,
- "[E_SYSTEM] Encode Failed");
-
- // The data that has been encoded is of length same as dstLength. If they are not equal,
- // something is wrong with the data, or with the encoding.
- SysTryCatch(NID_MEDIA, outSize <= tmpDstLength, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
- "[E_OUT_OF_MEMORY] Insufficient memory for encoder output out (%d) != allocated (%d).", outSize, tmpDstLength);
-
- pRetBuf.reset(new (std::nothrow) ByteBuffer());
- SysTryCatch(NID_MEDIA, pRetBuf.get() != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
- "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
-
- r = pRetBuf->Construct(outSize);
- SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
- "[%s] Propagated. ByteBuffer.Construct failed for %d bytes",
- GetErrorMessage(r), outSize);
-
- r = pRetBuf->SetArray(pTmpDstBuf.get(), 0, outSize);
- SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
- "[%s] Propagated. ByteBuffer.SetArray failed, buffer size = %d",
- GetErrorMessage(r), outSize);
+ r = pRetBuf->SetArray(pPkt->data, 0, pPkt->size);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ByteBuffer.SetArray(%x, 0, %d) failed",
+ GetErrorMessage(r), pPkt->data, pPkt->size);
pRetBuf->Flip();
- av_free(pVideoFrame);
-
return pRetBuf.release();
-
-CATCH:
- if (pVideoFrame != null)
- {
- av_free(pVideoFrame);
- }
- return null;
}
result
private:
- result OpenCodec(int width, int height, MediaPixelFormat pixelFormat);
- void CloseCodec(void);
-
int __width;
int __height;
int __quality;
result
_ColorConverter::Construct(MediaPixelFormat srcFormat, int srcWidth, int srcHeight,
- MediaPixelFormat dstFormat, int dstWidth, int dstHeight)
+ MediaPixelFormat dstFormat, int dstWidth, int dstHeight,
+ ImageScalingMethod scalingMethod)
{
result r = E_SUCCESS;
r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
"[E_UNSUPPORTED_FORMAT] Destination pixel format (%d) is not supported.", __dstFormat);
- //avcodec_init();
avcodec_register_all();
// Create scale context
- __pCvtCtxt = sws_getContext(__srcWidth, __srcHeight, __ffSrcFormat,
- __dstWidth, __dstHeight, __ffDstFormat,
- SWS_FAST_BILINEAR, null, null, null);
-
+ if ( scalingMethod == IMAGE_SCALING_METHOD_BILINEAR)
+ {
+ __pCvtCtxt = sws_getContext(__srcWidth, __srcHeight, __ffSrcFormat,
+ __dstWidth, __dstHeight, __ffDstFormat,
+ SWS_BILINEAR, null, null, null);
+ }
+ else if ( scalingMethod == IMAGE_SCALING_METHOD_BICUBIC)
+ {
+ __pCvtCtxt = sws_getContext(__srcWidth, __srcHeight, __ffSrcFormat,
+ __dstWidth, __dstHeight, __ffDstFormat,
+ SWS_BICUBIC, null, null, null);
+ }
+ else
+ {
+ __pCvtCtxt = sws_getContext(__srcWidth, __srcHeight, __ffSrcFormat,
+ __dstWidth, __dstHeight, __ffDstFormat,
+ SWS_FAST_BILINEAR, null, null, null);
+ }
SysTryReturn(NID_MEDIA, __pCvtCtxt != null, r = E_SYSTEM, E_SYSTEM,
"[E_SYSTEM] sws_getContext failed. src (%d x %d, pix = %d), dst (%d x %d, pix = %d)",
__srcWidth, __srcHeight, __ffSrcFormat,
--- /dev/null
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#include <math.h>
+#include <libexif/exif-byte-order.h>
+#include <libexif/exif-data-type.h>
+#include <libexif/exif-ifd.h>
+#include <libexif/exif-log.h>
+#include <libexif/exif-tag.h>
+#include <libexif/exif-content.h>
+#include <libexif/exif-mnote-data.h>
+#include <libexif/exif-mem.h>
+#include <FBaseSysLog.h>
+#include "FMedia_ExifUtil.h"
+
+namespace Tizen { namespace Media
+{
+
+const wchar_t* const EXIF_TAG_IMAGE_ORIENTATION = L"Exif.Orientation";
+const wchar_t* const EXIF_TAG_IMAGE_GPS_ALTITUDE = L"Exif.Gps.Altitude";
+const wchar_t* const EXIF_TAG_IMAGE_GPS_LONGITUDE = L"Exif.Gps.Longitude";
+const wchar_t* const EXIF_TAG_IMAGE_GPS_LATITUDE = L"Exif.Gps.Latitude";
+
+_ExifUtil::_ExifUtil()
+: __pExifData(null)
+, __pExifLog(null)
+, __orientation(-1)
+, __gpsLongitude(0.0)
+, __gpsLatitude(0.0)
+, __gpsAltitude(0.0)
+, __gpsLongitudeExist(false)
+, __gpsAltitudeExist(false)
+, __gpsLatitudeExist(false)
+, __orientationExist(false)
+{
+}
+
+_ExifUtil::~_ExifUtil()
+{
+ if (__pExifData)
+ {
+ exif_data_free(__pExifData);
+ }
+ if (__pExifLog)
+ {
+ exif_log_free(__pExifLog);
+ }
+}
+
+result _ExifUtil::Construct(const byte* pBuf, int length)
+{
+ result r = E_SUCCESS;
+
+ SysTryCatch(NID_MEDIA, pBuf != null, r = E_INVALID_DATA, E_INVALID_DATA, "[E_INVALID_DATA] Buffer is null. length: %d", length);
+
+ __pExifData = exif_data_new_from_data(pBuf, length);
+ SysTryCatch(NID_MEDIA, __pExifData != null, r = E_INVALID_DATA, E_INVALID_DATA, "[E_INVALID_DATA] exi data is null. length: %d", length);
+
+ __pExifLog = exif_log_new();
+ SysTryCatch(NID_MEDIA, __pExifLog != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] exif_log_new fail");
+
+#if defined _EXIF_UTIL_LOG_
+ //exif_log_set_func(__pExifLog, _ExifUtil::ExifLogFuncStatic, this);
+ //exif_data_log(__pExifData, __pExifLog);
+#endif
+ exif_data_foreach_content(__pExifData, _ExifUtil::ForEachContentStatic, this);
+ return r;
+
+CATCH:
+ if (__pExifLog)
+ {
+ exif_log_free(__pExifLog);
+ }
+ return r;
+}
+
+#if defined _EXIF_UTIL_LOG_
+//void _ExifUtil::ExifLogFuncStatic(ExifLog *log, ExifLogCode code, const char *domain, const char *format, va_list args, void *data)
+//{
+// ((_ExifUtil*)data)->ExifLogFunc(log, code, domain, format, args);
+//}
+
+//void _ExifUtil::ExifLogFunc(ExifLog *log, ExifLogCode code, const char *domain, const char *format, va_list args)
+//{
+// char msg[1024];
+// vsprintf(msg, format, args);
+// TLog("ExifLog : %s", msg);
+//}
+#endif
+
+void _ExifUtil::ForEachContentStatic(struct _ExifContent *pContent, void *pUserData)
+{
+ SysTryReturnVoidResult(NID_MEDIA, pContent != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] ExifContent instance is not available.");
+
+ _ExifUtil* pUtil = static_cast<_ExifUtil*>(pUserData);
+ SysTryReturnVoidResult(NID_MEDIA, pUtil != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] _ExifUtil instance is not available.");
+
+ pUtil->ForEachContent(pContent);
+}
+
+void _ExifUtil::ForEachContent(struct _ExifContent *pContent)
+{
+ SysTryReturnVoidResult(NID_MEDIA, pContent != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] ExifContent instance is not available.");
+
+ exif_content_log(pContent, __pExifLog);
+ exif_content_dump(pContent, 0);
+
+ exif_content_foreach_entry(pContent, _ExifUtil::ForEachEntryStatic, this);
+}
+
+void _ExifUtil::ForEachEntryStatic(struct _ExifEntry *pEntry, void *pUserData)
+{
+ SysTryReturnVoidResult(NID_MEDIA, pEntry != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] ExifEntry instance is not available.");
+
+ _ExifUtil* pUtil = static_cast<_ExifUtil*>(pUserData);
+ SysTryReturnVoidResult(NID_MEDIA, pUtil != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] _ExifUtil instance is not available.");
+
+ pUtil->ForEachEntry(pEntry);
+}
+
+void _ExifUtil::ForEachEntry(struct _ExifEntry *pEntry)
+{
+ SysTryReturnVoidResult(NID_MEDIA, pEntry != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] ExifEntry instance is not available.");
+ SysTryReturnVoidResult(NID_MEDIA, pEntry->parent != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Entry's parent instance is not available.");
+
+ const ExifByteOrder o = exif_data_get_byte_order (pEntry->parent->parent);
+ ExifRational exifRational;
+
+#if defined (_EXIF_UTIL_LOG_)
+ char value[1024];
+#endif
+
+ switch ((int)pEntry->tag)
+ {
+ case EXIF_TAG_ORIENTATION:
+ if (pEntry->format == EXIF_FORMAT_SHORT && pEntry->size == 2)
+ {
+ __orientation = *(short*)(pEntry->data);
+ __orientationExist = true;
+ }
+ break;
+
+ case EXIF_TAG_GPS_LATITUDE:
+ if (pEntry->format == EXIF_FORMAT_RATIONAL)
+ {
+ /*
+ exifRational = exif_get_rational (pEntry->data, o);
+
+ if (exifRational.denominator && exifRational.denominator != 1) {
+ __gpsLatitude = (double)exifRational.numerator / (double)exifRational.denominator;
+ }
+ else
+ {
+ __gpsLatitude = (double)exifRational.numerator;
+ }
+ */
+ __gpsLatitude = 0.0;
+ for (int i = 0; i < (int)pEntry->components; i++)
+ {
+ exifRational = exif_get_rational (pEntry->data + 8 * i, o);
+ if (exifRational.denominator)
+ {
+ __gpsLatitude += ((double)exifRational.numerator / (double)exifRational.denominator) / pow((float)60.0, i);
+ }
+ else
+ {
+ __gpsLatitude += (double)exifRational.numerator / pow((float)60.0, i);
+ }
+ }
+ __gpsLatitudeExist = true;
+ }
+ break;
+
+ case EXIF_TAG_GPS_LONGITUDE:
+ if (pEntry->format == EXIF_FORMAT_RATIONAL)
+ {
+ /*
+ exifRational = exif_get_rational (pEntry->data, o);
+
+ if (exifRational.denominator && exifRational.denominator != 1) {
+ __gpsLatitude = (double)exifRational.numerator / (double)exifRational.denominator;
+ } else {
+ __gpsLatitude = (double)exifRational.numerator;
+ }
+ */
+ __gpsLongitude = 0.0;
+
+ for (int i = 0; i < (int)pEntry->components; i++)
+ {
+ exifRational = exif_get_rational (pEntry->data + 8 * i, o);
+ if (exifRational.denominator && exifRational.denominator != 1)
+ {
+ __gpsLongitude += ((double)exifRational.numerator / (double)exifRational.denominator) / pow((float)60.0, i);
+ }
+ else
+ {
+ __gpsLongitude += (double)exifRational.numerator / pow((float)60.0, i);
+ }
+ }
+ __gpsLongitudeExist = true;
+ }
+ break;
+
+ case EXIF_TAG_GPS_ALTITUDE:
+ if (pEntry->format == EXIF_FORMAT_RATIONAL)
+ {
+ exifRational = exif_get_rational (pEntry->data, o);
+
+ if (exifRational.denominator && exifRational.denominator != 1)
+ {
+ __gpsAltitude = (double)exifRational.numerator / (double)exifRational.denominator;
+ }
+ else
+ {
+ __gpsAltitude = (double)exifRational.numerator;
+ }
+ __gpsAltitudeExist = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+result _ExifUtil::GetValue(const Tizen::Base::String& key, int &value)
+{
+ if (key.Equals(EXIF_TAG_IMAGE_ORIENTATION, true))
+ {
+ SysTryReturn(NID_MEDIA, __orientationExist, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] bool instance is not available. Orientation value was not found.");
+ value = __orientation;
+ }
+ else
+ {
+ SysLogException(NID_MEDIA, E_INVALID_ARG, "[E_INVALID_ARG] Key:%S was wrong.", key.GetPointer());
+ return E_INVALID_ARG;
+ }
+
+ return E_SUCCESS;
+}
+
+result _ExifUtil::GetValue(const Tizen::Base::String& key, double &value)
+{
+ if (key.Equals(EXIF_TAG_IMAGE_GPS_ALTITUDE, true))
+ {
+ SysTryReturn(NID_MEDIA, __gpsAltitudeExist, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] bool instance is not available. Altitude value was not found.");
+ value = __gpsAltitude;
+ }
+ else if (key.Equals(EXIF_TAG_IMAGE_GPS_LONGITUDE, true))
+ {
+ SysTryReturn(NID_MEDIA, __gpsLongitude, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] bool instance is not available. Longitude value was not found.");
+ value = __gpsLongitude;
+ } else if (key.Equals(EXIF_TAG_IMAGE_GPS_LATITUDE, true))
+ {
+ SysTryReturn(NID_MEDIA, __gpsLatitude, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] bool instance is not available. Latitude value was not found.");
+ value = __gpsLatitude;
+ } else
+ {
+ SysLogException(NID_MEDIA, E_INVALID_ARG, "[E_INVALID_ARG] Key:%S was wrong.", key.GetPointer());
+ return E_INVALID_ARG;
+ }
+
+ return E_SUCCESS;
+}
+
+}}
+
--- /dev/null
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/**
+ * @file FMedia_Ffmpeg.cpp
+ * @brief This is the implementation file for the ffmpeg related utility.
+ *
+ * This file contains the implementations for the ffmpeg related utility.
+ *
+ */
+#include <FBaseObject.h>
+#include "FMedia_Ffmpeg.h"
+
+using namespace Tizen::Base;
+
+namespace Tizen { namespace Media
+{
+
+struct _FfmpegDeleter ffmpegDeleter;
+
+}} // Tizen::Media
#include <unique_ptr.h>
#include <FBaseColArrayListT.h>
#include <FBaseSysLog.h>
-#include <FMediaImageTypes.h>
#include <FBaseInteger.h>
#include <FIoFile.h>
#include <FMediaImageTypes.h>
#include "FMedia_TiffDecoder.h"
#include "FMedia_WbmpDecoder.h"
#include "FMedia_ImageUtil.h"
+#include "FMedia_ExifUtil.h"
using namespace Tizen::Base;
using namespace Tizen::Io;
((x == MEDIA_PIXEL_FORMAT_RGB565LE) || (x == MEDIA_PIXEL_FORMAT_BGRA8888) \
|| (x == MEDIA_PIXEL_FORMAT_RGBA8888))
+typedef struct {
+ ImageRotationType rotateType;
+ ImageFlipType flipType;
+ bool dimensionSwitch;
+} _ImageExifInfo;
+
+static const _ImageExifInfo _IMAGE_ROTATE_FLIP_MAP[] = {
+ { IMAGE_ROTATION_0, IMAGE_FLIP_NONE, false }, /* NONE */
+ { IMAGE_ROTATION_0, IMAGE_FLIP_NONE, false }, /* TOP_LEFT */
+ { IMAGE_ROTATION_0, IMAGE_FLIP_VERTICAL, false }, /* TOP_RIGHT */
+ { IMAGE_ROTATION_180, IMAGE_FLIP_NONE, false }, /* BOTTOM_RIGHT */
+ { IMAGE_ROTATION_0, IMAGE_FLIP_HORIZONTAL, false }, /* BOTTOM_LEFT */
+ { IMAGE_ROTATION_90, IMAGE_FLIP_VERTICAL, true }, /* LEFT_TOP */
+ { IMAGE_ROTATION_90, IMAGE_FLIP_NONE, true }, /* RIGHT_TOP */
+ { IMAGE_ROTATION_90, IMAGE_FLIP_HORIZONTAL, true }, /* RIGHT_BOTTOM */
+ { IMAGE_ROTATION_270, IMAGE_FLIP_NONE, true } /* LEFT_BOTTOM */
+};
+
Tizen::Base::ByteBuffer*
_ImageDecoder::DecodeToBufferN(const Tizen::Base::String& filePath,
- MediaPixelFormat pixelFormat, int &width, int &height)
+ MediaPixelFormat pixelFormat, int &width, int &height, bool autoRotate)
{
result r = E_SUCCESS;
+
std::unique_ptr<ByteBuffer> pBuf;
_ImageDecoder dec;
SysTryReturn(NID_MEDIA, File::IsFileExist(filePath), null, E_FILE_NOT_FOUND,
"[E_FILE_NOT_FOUND] filePath:%ls", filePath.GetPointer());
- r = dec.Construct(filePath, pixelFormat);
+ r = dec.Construct(filePath, pixelFormat, IMG_FORMAT_NONE, autoRotate);
SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
"[%s] Decoder construct failed.", GetErrorMessage(r));
__outDim.width = 0;
__outDim.height = 0;
__pSrcBuf = null;
+ __autoRotate = false;
+ __orientationInfo = 0;
}
_ImageDecoder::~_ImageDecoder(void)
result
_ImageDecoder::Construct(const Tizen::Base::String& srcPath,
MediaPixelFormat pixelFormat,
- ImageFormat imgFormat)
+ ImageFormat imgFormat, bool autoRotate)
{
result r = E_SUCCESS;
std::unique_ptr<ByteBuffer> pBuf;
r = Construct(*pBuf.get(), pixelFormat, imgFormat);
SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r));
+
+ if (autoRotate == true)
+ {
+ __autoRotate = true;
+ _ExifUtil imgExif;
+ imgExif.Construct(pBuf->GetPointer(), pBuf->GetCapacity());
+ imgExif.GetValue(EXIF_TAG_IMAGE_ORIENTATION, __orientationInfo);
+ // imgExif.GetValue() will return "r = E_OBJ_NOT_FOUND" if it could not be found exif infomation.
+ // However, the result should be decided by result of construct in this function.
+ SetLastResult(E_SUCCESS);
+ }
return r;
}
result r = E_SUCCESS;
SysTryReturnResult(NID_MEDIA, __pDec.get() == null, E_INVALID_STATE, "Already constructed");
- SysTryCatch(NID_MEDIA,
+ SysTryCatch(NID_MEDIA,
(pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)|| (pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888) ||
(pixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888), r = E_INVALID_ARG, E_INVALID_ARG,
"[E_INVALID_ARG] pixelFormat:%d", pixelFormat);
}
byte*
-_ImageDecoder::DecodeN(int& outLength)
+_ImageDecoder::DecodeN(int& outLength, ImageScalingMethod scalingMethod)
{
result r = E_SUCCESS;
int rawLength = 0;
- byte* outBuf = null;
+ std::unique_ptr<byte[]> pOutBuf;
std::unique_ptr<byte[]> pRawBuf;
+ std::unique_ptr<byte[]> pDstBuf;
SysTryReturn(NID_MEDIA, __pDec.get() != null, null, E_INVALID_STATE, "Not yet constructed");
// Decode
pRawBuf.reset(__pDec->DecodeN(rawLength));
SysTryReturn(NID_MEDIA, pRawBuf.get() != null, null, GetLastResult(),
- "[%s] buffer is null (%x), buffer length is %d.",
+ "[%s] buffer is null (%x), buffer length is %d.",
GetErrorMessage(GetLastResult()),pRawBuf.get(), rawLength);
// Get working dimension
&& (__orgDim.width == __outDim.width)
&& (__orgDim.height == __outDim.height))
{
- outBuf = pRawBuf.release();
+ pOutBuf.swap(pRawBuf);
outLength = rawLength;
}
else
// Converter construction
r = cvt.Construct(__pDec->GetPixelFormat(), __orgDim.width, __orgDim.height,
- __pixelFormat, __outDim.width, __outDim.height);
+ __pixelFormat, __outDim.width, __outDim.height, scalingMethod);
SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
// Convert to output format
- outBuf = cvt.ConvertN(pRawBuf.get(), rawLength, outLength);
+ pOutBuf.reset(cvt.ConvertN(pRawBuf.get(), rawLength, outLength));
r = GetLastResult();
SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
}
+
+ if (__autoRotate == true)
+ {
+ int dstWidth = 0;
+ int dstHeight = 0;
+
+ if (__orientationInfo == EXIF_ORIENTATION_TOP_LEFT || __orientationInfo == 0)
+ {
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+ }
+
+ if (__orientationInfo > EXIF_ORIENTATION_LEFT_BOTTOM || __orientationInfo < EXIF_ORIENTATION_TOP_LEFT)
+ {
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+ }
+
+ pDstBuf.reset(new (std::nothrow) byte[outLength]);
+ SysTryReturn(NID_MEDIA, pDstBuf.get() != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
+
+ ImageRotationType rotateType = _IMAGE_ROTATE_FLIP_MAP[__orientationInfo].rotateType;
+ ImageFlipType flipType = _IMAGE_ROTATE_FLIP_MAP[__orientationInfo].flipType;
+
+ pDstBuf.reset(_ImageUtil::RotateN(pOutBuf.get(), __pixelFormat, __outDim.width, __outDim.height, rotateType, dstWidth, dstHeight));
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] _ImageUtil:Resize", GetErrorMessage(r));
+
+ __outDim.width = dstWidth;
+ __outDim.height = dstHeight;
+
+ pOutBuf.swap(pDstBuf);
+ if (flipType != IMAGE_FLIP_NONE)
+ {
+ pDstBuf.reset(_ImageUtil::FlipN(pOutBuf.get(), __pixelFormat, __outDim.width, __outDim.height, flipType));
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] _ImageUtil:Flip", GetErrorMessage(r));
+
+ pOutBuf.swap(pDstBuf);
+ }
+ }
SetLastResult(E_SUCCESS);
- return outBuf;
+ return pOutBuf.release();
}
// TODO: Change return type to ByteBuffer*
#include <unique_ptr.h>
#include <FBaseSysLog.h>
+#include <FBaseInteger.h>
+#include <FBaseFloat.h>
+#include <FBaseDouble.h>
#include <image_util.h>
#include <mmf/mm_error.h>
#include <mmf/mm_util_imgp.h>
return pOutBuf.release();
}
+byte*
+_ImageUtil::CropN(const byte *srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ int dstX, int dstY, int dstWidth, int dstHeight)
+{
+ int bufSize = 0;
+ std::unique_ptr <byte[]> pOutBuf;
+ result r = E_SUCCESS;
+
+ bufSize = GetBufferSize(pixelFormat, dstWidth, dstHeight);
+ SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
+ "[%s] Check dimensions (%d x %d) and pixel format (%d)",
+ GetErrorMessage(GetLastResult()), dstWidth, dstHeight, pixelFormat);
+
+ pOutBuf.reset(new (std::nothrow) byte[bufSize]);
+ SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
+
+ r = CropBuffer(srcBuf, pixelFormat, srcWidth, srcHeight, pOutBuf.get(), dstX, dstY, dstWidth, dstHeight);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] ImageUtil.CropN failed.", GetErrorMessage(r));
+
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+}
+
+byte*
+_ImageUtil::RotateN(const byte *srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ ImageRotationType rotate,
+ int &dstWidth, int &dstHeight)
+{
+ int bufSize = 0;
+ std::unique_ptr <byte[]> pOutBuf;
+ result r = E_SUCCESS;
+
+ bufSize = GetBufferSize(pixelFormat, srcWidth, srcHeight);
+ SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
+ "[%s] Check dimensions (%d x %d) and pixel format (%d)",
+ GetErrorMessage(GetLastResult()), dstWidth, dstHeight, pixelFormat);
+
+ pOutBuf.reset(new (std::nothrow) byte[bufSize]);
+ SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
+
+ r = RotateBuffer(srcBuf, pixelFormat, srcWidth, srcHeight, pOutBuf.get(), dstWidth, dstHeight, rotate);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] ImageUtil.RotateN failed.", GetErrorMessage(r));
+
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+}
+
+byte*
+_ImageUtil::FlipN(const byte* srcBuf,
+ MediaPixelFormat pixelFormat, int width, int height,
+ ImageFlipType flip)
+{
+ int bufSize = 0;
+ std::unique_ptr <byte[]> pOutBuf;
+ result r = E_SUCCESS;
+
+ bufSize = GetBufferSize(pixelFormat, width, height);
+ SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
+ "[%s] Check dimensions (%d x %d) and pixel format (%d)",
+ GetErrorMessage(GetLastResult()), width, height, pixelFormat);
+
+ pOutBuf.reset(new (std::nothrow) byte[bufSize]);
+ SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
+
+ r = FlipBuffer(srcBuf, pixelFormat, width, height, pOutBuf.get(), flip);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] ImageUtil.FlipN failed.", GetErrorMessage(r));
+
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+}
+
int
_ImageUtil::GetBufferSize(MediaPixelFormat pixelFormat, int width, int height)
{
return MEDIA_PIXEL_FORMAT_NONE;
}
+result
+_ImageUtil::GetResizedDimension(int srcWidth, int srcHeight, float dstWidth, float dstHeight,
+ float &outWidth, float &outHeight)
+{
+
+ SysTryReturn(NID_MEDIA, (srcWidth > 0 && srcHeight > 0 && dstWidth > 0 && dstHeight > 0),
+ E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be greater than zero Source size(%d x %d), \
+ Destination size(%f x %f)", srcWidth, srcHeight, dstWidth, dstHeight);
+
+ double xRatio = Float(dstWidth).ToDouble() / Integer(srcWidth).ToDouble();
+ double yRatio = Float(dstHeight).ToDouble() / Integer(srcHeight).ToDouble();
+
+ if (xRatio >= 1.0 || yRatio >= 1.0)
+ {
+ outWidth = Integer(srcWidth).ToFloat();
+ outHeight = Integer(srcHeight).ToFloat();
+ }
+ else if (xRatio < yRatio)
+ {
+ outWidth = Double(srcWidth * yRatio).ToFloat();
+ outHeight = dstHeight;
+ }
+ else
+ {
+ outWidth = dstWidth;
+ outHeight = Double(srcHeight * xRatio).ToFloat();
+ }
+ return E_SUCCESS;
+}
+
}} // Tizen::Media
CATCH:
if ( __tjDecodingHandle )
+ {
tjDestroy(__tjDecodingHandle);
+ __tjDecodingHandle = null;
+ }
if ( __tjTransformHandle )
+ {
tjDestroy(__tjTransformHandle);
+ __tjTransformHandle = null;
+ }
return r;
}
#define _FMEDIA_INTERNAL_COLORCONVERTER_H_
#include <FMedia_Ffmpeg.h>
+#include <FMediaImageTypes.h>
namespace Tizen { namespace Media
{
* @exception E_SYSTEM A system error has occurred.
*/
result Construct(MediaPixelFormat srcFormat, int srcWidth, int srcHeight,
- MediaPixelFormat dstFormat, int dstWidth, int dstHeight);
+ MediaPixelFormat dstFormat, int dstWidth, int dstHeight,
+ ImageScalingMethod scalingMethod = IMAGE_SCALING_METHOD_FAST_BILINEAR);
public:
/**
--- /dev/null
+//
+// Open Service Platform
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#ifndef __FMEDIA_INTERNAL_EXIF_UTIL_H__
+#define __FMEDIA_INTERNAL_EXIF_UTIL_H__
+
+#include <FOspConfig.h>
+
+#define _EXIF_UTIL_LOG_ 1
+
+namespace Tizen { namespace Media
+{
+
+_OSP_EXPORT_ extern const wchar_t* const EXIF_TAG_IMAGE_ORIENTATION;
+_OSP_EXPORT_ extern const wchar_t* const EXIF_TAG_IMAGE_GPS_ALTITUDE;
+_OSP_EXPORT_ extern const wchar_t* const EXIF_TAG_IMAGE_GPS_LONGITUDE;
+_OSP_EXPORT_ extern const wchar_t* const EXIF_TAG_IMAGE_GPS_LATITUDE;
+
+class _OSP_EXPORT_ _ExifUtil
+ : public Tizen::Base::Object
+{
+public:
+ _ExifUtil();
+ ~_ExifUtil();
+
+ result Construct(const byte *buf, int length);
+ result GetValue(const Tizen::Base::String& key, int &value);
+ result GetValue(const Tizen::Base::String& key, double &value);
+
+protected:
+ void ForEachEntry(struct _ExifEntry *pEntry);
+ static void ForEachEntryStatic(struct _ExifEntry *pEntry, void *pUserData);
+
+ void ForEachContent(struct _ExifContent *pContent);
+ static void ForEachContentStatic(struct _ExifContent *pContent, void *pUserData);
+
+#if defined _EXIF_UTIL_LOG_
+// static void ExifLogFuncStatic(ExifLog *log, ExifLogCode code, const char *domain, const char *format, va_list args, void *data);
+// void ExifLogFunc(ExifLog *log, ExifLogCode code, const char *domain, const char *format, va_list args);
+#endif
+
+private:
+ struct _ExifData*__pExifData;
+ struct _ExifLog*__pExifLog;
+
+ short __orientation;
+ double __gpsLongitude;
+ double __gpsLatitude;
+ float __gpsAltitude;
+
+ bool __gpsLongitudeExist;
+ bool __gpsAltitudeExist;
+ bool __gpsLatitudeExist;
+ bool __orientationExist;
+};
+
+}}
+
+#endif
#include <libswscale/swscale.h>
};
+#include <FOspConfig.h>
+
+namespace Tizen { namespace Media
+{
+
+struct _FfmpegDeleter
+{
+ void operator() (AVCodecContext* pCodecCtxt) const
+ {
+ if (pCodecCtxt != null)
+ {
+ avcodec_close(pCodecCtxt);
+ av_free(pCodecCtxt);
+ pCodecCtxt = null;
+ }
+ }
+
+ void operator() (AVFrame* pFrame) const
+ {
+ if (pFrame != null)
+ {
+ av_free(pFrame);
+ pFrame = null;
+ }
+ }
+
+ void operator() (AVPacket* pPacket) const
+ {
+ if (pPacket != null)
+ {
+ av_free_packet(pPacket);
+ delete pPacket;
+ pPacket = null;
+ }
+ }
+};
+
+_OSP_EXPORT_ extern struct _FfmpegDeleter ffmpegDeleter;
+
+}} // Tizen::Media
+
#endif
*/
static Tizen::Base::ByteBuffer*
DecodeToBufferN(const Tizen::Base::String& filePath, MediaPixelFormat pixelFormat,
- int &width, int &height);
+ int &width, int &height, bool autoRotate = false);
/**
* Decodes a region of image data into the decoded byte buffer container without resizing. @n
*/
result Construct(const Tizen::Base::String& srcPath,
MediaPixelFormat pixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888,
- ImageFormat imgFormat = IMG_FORMAT_NONE);
+ ImageFormat imgFormat = IMG_FORMAT_NONE,
+ bool autoRotate = false);
/**
* Initializes this instance of ImageDecode.
* @exception E_SUCCESS The method is successful.
* @remark
*/
- byte* DecodeN(int& outLength);
+ byte* DecodeN(int& outLength, ImageScalingMethod scalingMethod = IMAGE_SCALING_METHOD_FAST_BILINEAR);
/**
* Decodes image buffer.
int width;
int height;
} __outDim;
+ bool __autoRotate;
+ int __orientationInfo;
MediaPixelFormat __pixelFormat;
std::unique_ptr<Tizen::Base::ByteBuffer> __pSrcBuf;
static int ToFfmpegPixelFormat(MediaPixelFormat pixelFmt);
static MediaPixelFormat ToMediaPixelFormatFromFfmpeg(int pixelFormat);
+
+ static byte* CropN(const byte *srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ int dstX, int dstY, int dstWidth, int dstHeight);
+
+ static byte* RotateN(const byte *srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ ImageRotationType rotate,
+ int &dstWidth, int &dstHeight);
+
+ static byte* FlipN(const byte* srcBuf,
+ MediaPixelFormat pixelFormat, int width, int height,
+ ImageFlipType flip);
+
+ static result GetResizedDimension(int srcWidth, int srcHeight,
+ float dstWidth, float dstHeight,
+ float &outWidth, float &outHeight);
+
private:
_ImageUtil();