merge with master
authorJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:16:50 +0000 (01:16 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:16:50 +0000 (01:16 +0900)
17 files changed:
CMakeLists.txt
inc/FMediaImageTypes.h
packaging/osp-image-core.spec
src/FMedia_BmpDecoder.cpp [changed mode: 0644->0755]
src/FMedia_BmpEncoder.cpp [changed mode: 0644->0755]
src/FMedia_BmpEncoder.h [changed mode: 0644->0755]
src/FMedia_ColorConverter.cpp
src/FMedia_ExifUtil.cpp [new file with mode: 0644]
src/FMedia_Ffmpeg.cpp [new file with mode: 0755]
src/FMedia_ImageDecoder.cpp
src/FMedia_ImageUtil.cpp
src/FMedia_JpegTurboDecoder.cpp
src/inc/FMedia_ColorConverter.h
src/inc/FMedia_ExifUtil.h [new file with mode: 0644]
src/inc/FMedia_Ffmpeg.h
src/inc/FMedia_ImageDecoder.h
src/inc/FMedia_ImageUtil.h

index 150dc48..5abb7b6 100755 (executable)
@@ -5,15 +5,15 @@ SET (this_target osp-image-core)
 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
@@ -38,6 +38,8 @@ SET (${this_target}_SOURCE_FILES
        src/FMedia_BmpEncoder.cpp
        src/FMedia_SlpUtil.cpp
        src/FMedia_MediaUtil.cpp
+       src/FMedia_ExifUtil.cpp
+       src/FMedia_Ffmpeg.cpp
 )
 
 ## Definitions
@@ -59,7 +61,6 @@ SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -
 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" )
@@ -73,7 +74,7 @@ TARGET_LINK_LIBRARIES(${this_target} "-lecore_evas" )
 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 
@@ -83,7 +84,7 @@ SET_TARGET_PROPERTIES(${this_target}
        )
 
 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}
@@ -93,8 +94,8 @@ ADD_CUSTOM_COMMAND(TARGET ${this_target}
 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                                          
index ad9ad38..7ea9ea8 100644 (file)
@@ -16,7 +16,7 @@
 //
 
 /**
- * @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.
@@ -59,7 +59,7 @@ enum ImageRotationType
        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
@@ -73,7 +73,7 @@ enum ImageFlipType
        IMAGE_FLIP_NONE = 0x00,             /**< The no-flip type */
        IMAGE_FLIP_HORIZONTAL,              /**< The horizontal flip */
        IMAGE_FLIP_VERTICAL,                /**< The vertical flip */
-} ;
+};
 
 /**
  * @enum       MediaPixelFormat
@@ -94,11 +94,44 @@ 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  */
 };
 
 };
index 160e7a6..1eb4e2b 100755 (executable)
@@ -3,7 +3,7 @@
 
 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
@@ -19,9 +19,12 @@ BuildRequires:  pkgconfig(libavformat)
 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  
old mode 100644 (file)
new mode 100755 (executable)
index d671d32..b40cea0
@@ -65,18 +65,15 @@ _BmpDecoder::OpenCodec(void)
        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.");
 
@@ -223,28 +220,20 @@ _BmpDecoder::SetDecodingRegion(int x, int y, int width, int height)
 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,
old mode 100644 (file)
new mode 100755 (executable)
index 820a75a..00cede8
 #include "FMedia_BmpEncoder.h"
 #include "FMedia_ImageUtil.h"
 
+using namespace std;
 using namespace Tizen::Base;
 
 namespace Tizen { namespace Media
 {
 
+
 _BmpEncoder::_BmpEncoder(void)
 {
        __pCodecCtx = null;
@@ -61,7 +63,7 @@ _BmpEncoder::Construct(int width, int height,
                                           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);
@@ -72,6 +74,7 @@ _BmpEncoder::Construct(int width, int height,
        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;
@@ -79,93 +82,50 @@ _BmpEncoder::Construct(int width, int height,
        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;
@@ -174,63 +134,23 @@ _BmpEncoder::EncodeN(const byte* srcBuf, int srcLength)
        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
old mode 100644 (file)
new mode 100755 (executable)
index 497b175..0df1317
@@ -93,9 +93,6 @@ protected:
 
 
 private:
-       result OpenCodec(int width, int height, MediaPixelFormat pixelFormat);
-       void CloseCodec(void);
-
        int __width;
        int __height;
        int __quality;
index 4ed14a3..eec16ee 100644 (file)
@@ -65,7 +65,8 @@ _ColorConverter::~_ColorConverter(void)
 
 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;
 
@@ -117,14 +118,27 @@ _ColorConverter::Construct(MediaPixelFormat srcFormat, int srcWidth, int srcHeig
                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,
diff --git a/src/FMedia_ExifUtil.cpp b/src/FMedia_ExifUtil.cpp
new file mode 100644 (file)
index 0000000..29478a3
--- /dev/null
@@ -0,0 +1,279 @@
+//
+// 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;
+}
+
+}}
+
diff --git a/src/FMedia_Ffmpeg.cpp b/src/FMedia_Ffmpeg.cpp
new file mode 100755 (executable)
index 0000000..b7f342e
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// 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
index c67f59c..a6499bc 100644 (file)
@@ -23,7 +23,6 @@
 #include <unique_ptr.h>
 #include <FBaseColArrayListT.h>
 #include <FBaseSysLog.h>
-#include <FMediaImageTypes.h>
 #include <FBaseInteger.h>
 #include <FIoFile.h>
 #include <FMediaImageTypes.h>
@@ -38,6 +37,7 @@
 #include "FMedia_TiffDecoder.h"
 #include "FMedia_WbmpDecoder.h"
 #include "FMedia_ImageUtil.h"
+#include "FMedia_ExifUtil.h"
 
 using namespace Tizen::Base;
 using namespace Tizen::Io;
@@ -49,11 +49,30 @@ namespace Tizen { namespace Media
        ((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;
 
@@ -62,7 +81,7 @@ _ImageDecoder::DecodeToBufferN(const Tizen::Base::String& filePath,
        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));
 
@@ -204,6 +223,8 @@ _ImageDecoder::_ImageDecoder(void)
        __outDim.width = 0;
        __outDim.height = 0;
        __pSrcBuf = null;
+       __autoRotate = false;
+       __orientationInfo = 0;
 }
 
 _ImageDecoder::~_ImageDecoder(void)
@@ -260,7 +281,7 @@ _ImageDecoder::CreateDecoderN(ImageFormat srcFormat)
 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;
@@ -272,6 +293,17 @@ _ImageDecoder::Construct(const Tizen::Base::String& srcPath,
 
        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;
 }
 
@@ -283,7 +315,7 @@ _ImageDecoder::Construct(const Tizen::Base::ByteBuffer& srcBuf,
        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);
@@ -327,18 +359,19 @@ CATCH:
 }
 
 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
@@ -353,7 +386,7 @@ _ImageDecoder::DecodeN(int& outLength)
                && (__orgDim.width == __outDim.width)
                && (__orgDim.height == __outDim.height))
        {
-               outBuf = pRawBuf.release();
+               pOutBuf.swap(pRawBuf);
                outLength = rawLength;
        }
        else
@@ -362,16 +395,57 @@ _ImageDecoder::DecodeN(int& outLength)
 
                // 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*
index 5f22cc8..dbba81d 100644 (file)
@@ -22,6 +22,9 @@
 
 #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>
@@ -2470,6 +2473,87 @@ _ImageUtil::CropN(const Tizen::Base::ByteBuffer &srcBuf,
        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)
 {
@@ -2567,4 +2651,35 @@ _ImageUtil::ToMediaPixelFormatFromFfmpeg(int pixelFormat)
        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
index d4d861f..45c5cb8 100644 (file)
@@ -85,9 +85,15 @@ _JpegTurboDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pi
 
 CATCH:
        if ( __tjDecodingHandle )
+       {
                tjDestroy(__tjDecodingHandle);
+               __tjDecodingHandle = null;
+       }
        if ( __tjTransformHandle )
+       {
                tjDestroy(__tjTransformHandle);
+               __tjTransformHandle = null;
+       }
        return r;
 }
 
index 71e8ae7..56acb8c 100644 (file)
@@ -26,6 +26,7 @@
 #define _FMEDIA_INTERNAL_COLORCONVERTER_H_
 
 #include <FMedia_Ffmpeg.h>
+#include <FMediaImageTypes.h>
 
 namespace Tizen { namespace Media
 {
@@ -49,7 +50,8 @@ public:
         * @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:
        /**
diff --git a/src/inc/FMedia_ExifUtil.h b/src/inc/FMedia_ExifUtil.h
new file mode 100644 (file)
index 0000000..4074714
--- /dev/null
@@ -0,0 +1,72 @@
+//
+// 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
index 363c3bd..d6fa52a 100644 (file)
@@ -44,5 +44,46 @@ extern "C" {
 #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
index 0d6401e..a9cff01 100644 (file)
@@ -70,7 +70,7 @@ public:
         */
        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
@@ -159,7 +159,8 @@ public:
         */
        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.
@@ -183,7 +184,7 @@ public:
         * @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.
@@ -266,6 +267,8 @@ private:
                int width;
                int height;
        } __outDim;
+       bool __autoRotate;
+       int __orientationInfo;
        MediaPixelFormat __pixelFormat;
        std::unique_ptr<Tizen::Base::ByteBuffer> __pSrcBuf;
 
index f4bf486..e9bd8a8 100644 (file)
@@ -135,6 +135,26 @@ public:
        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();