--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+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
+ /usr/include/osp
+ /usr/include/osp/base
+ /usr/include/osp/app
+ /usr/include/osp/net
+ /usr/include/osp/security
+ /usr/include/osp/io
+ )
+
+SET (${this_target}_SOURCE_FILES
+ src/FMedia_ImageDecoder.cpp
+ src/FMedia_BmpDecoder.cpp
+ src/FMedia_PngDecoder.cpp
+ src/FMedia_GifDecoder.cpp
+ src/FMedia_JpegTurboDecoder.cpp
+ src/FMedia_TiffDecoder.cpp
+ src/FMedia_WbmpDecoder.cpp
+ src/FMedia_ImageEncoder.cpp
+ src/FMedia_JpegTurboEncoder.cpp
+ src/FMedia_ColorConverter.cpp
+ src/FMedia_ImageUtil.cpp
+ src/FMedia_PngEncoder.cpp
+ src/FMedia_BmpEncoder.cpp
+ src/FMedia_SlpUtil.cpp
+ src/FMedia_MediaUtil.cpp
+)
+
+## Definitions
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall" )
+
+## SET C COMPILER FLAGS
+SET(CMAKE_C_FLAGS "${OSP_DEBUG_FLAGS} ${OSP_OPT_FLAGS} ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}")
+
+## SET CPP COMPILER FLAGS
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
+SET(CMAKE_CXX_FLAGS "${OSP_DEBUG_FLAGS} ${OSP_OPT_FLAGS} ${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}")
+
+## Create Library
+ADD_LIBRARY (${this_target} SHARED ${${this_target}_SOURCE_FILES})
+
+## SET LINKER FLAGS
+SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -Wl,--as-needed")
+
+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} "-lswscale" )
+TARGET_LINK_LIBRARIES(${this_target} "-lavutil" )
+TARGET_LINK_LIBRARIES(${this_target} "-lgif" )
+TARGET_LINK_LIBRARIES(${this_target} "-lmmutil_imgp" )
+TARGET_LINK_LIBRARIES(${this_target} "-lecore" )
+TARGET_LINK_LIBRARIES(${this_target} "-levas" )
+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" )
+
+
+SET_TARGET_PROPERTIES(${this_target}
+ PROPERTIES
+ VERSION ${FULLVER}
+ SOVERSION ${MAJORVER}
+ CLEAN_DIRECT_OUTPUT 1
+ )
+
+ADD_CUSTOM_COMMAND(TARGET ${this_target}
+ 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}
+ COMMENT "strip ${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)
+INSTALL(DIRECTORY ${LIBRARY_OUTPUT_PATH}/debug/ DESTINATION lib/osp/debug
+ FILES_MATCHING PATTERN "*"
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ)
+
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/inc/ DESTINATION include/osp FILES_MATCHING PATTERN "*.h")
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/src/inc/ DESTINATION include/osp/media FILES_MATCHING PATTERN "*.h")
+
+# pkgconfig file
+CONFIGURE_FILE(${this_target}.pc.in ${CMAKE_SOURCE_DIR}/${this_target}.pc @ONLY)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/${this_target}.pc DESTINATION lib/pkgconfig)
--- /dev/null
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
--- /dev/null
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE file for Apache License terms and conditions.
--- /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 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.
+ */
+
+#ifndef _FMEDIA_IMAGE_TYPES_H_
+#define _FMEDIA_IMAGE_TYPES_H_
+
+namespace Tizen { namespace Media
+{
+
+/**
+ * @enum ImageFormat
+ *
+ * Defines the image formats.
+ *
+ * @since 2.0
+ */
+enum ImageFormat
+{
+ IMG_FORMAT_NONE = -1, /**< No image format type */
+ IMG_FORMAT_JPG = 0, /**< The JPEG image format type*/
+ IMG_FORMAT_PNG, /**< The PNG image format type*/
+ IMG_FORMAT_GIF, /**< The GIF image format type*/
+ IMG_FORMAT_BMP, /**< The BMP image format type*/
+ IMG_FORMAT_TIFF, /**< The TIFF image format type*/
+ IMG_FORMAT_WBMP, /**< The WBMP image format type*/
+};
+
+/**
+ * @enum ImageRotationType
+ *
+ * Defines the types of rotation.
+ *
+ * @since 2.0
+ */
+enum ImageRotationType
+{
+ IMAGE_ROTATION_0 = 0x00, /**< The no-rotation */
+ 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
+ *
+ * Defines the type of flip.
+ *
+ * @since 2.0
+ */
+enum ImageFlipType
+{
+ IMAGE_FLIP_NONE = 0x00, /**< The no-flip type */
+ IMAGE_FLIP_HORIZONTAL, /**< The horizontal flip */
+ IMAGE_FLIP_VERTICAL, /**< The vertical flip */
+} ;
+
+/**
+ * @enum MediaPixelFormat
+ *
+ * Defines the pixel formats of the media data.
+ *
+ * @since 2.0
+ */
+enum MediaPixelFormat
+{
+ MEDIA_PIXEL_FORMAT_NONE = 0x0000, // The undefined pixel format
+ MEDIA_PIXEL_FORMAT_RGB565LE = 0x0001, /**< The RGB565 little-endian format */
+ MEDIA_PIXEL_FORMAT_RGB565BE, /**< The RGB565 big-endian format */
+ MEDIA_PIXEL_FORMAT_RGB888 = 0x0100, /**< The RGB888 format */
+ MEDIA_PIXEL_FORMAT_BGR888, /**< The BGR888 format */
+ MEDIA_PIXEL_FORMAT_RGBA8888, /**< The RGBA8888 format */
+ MEDIA_PIXEL_FORMAT_BGRA8888, /**< The BGRA8888 format */
+ 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 */
+};
+
+};
+}; // Tizen::Media
+
+
+#endif
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
\ No newline at end of file
--- /dev/null
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=/usr/lib/osp
+includedir=/usr/include/osp
+
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
\ No newline at end of file
--- /dev/null
+%define debug_package %{nil}
+%define __strip /bin/true
+
+Name: osp-image-core
+Summary: The Media Image Core library of OSP
+Version: 1.2.0.0
+Release: 1
+Group: TO_BE/FILLED_IN
+License: TO BE FILLED IN
+Source0: %{name}-%{version}.tar.gz
+BuildRequires: cmake
+BuildRequires: pkgconfig(chromium)
+BuildRequires: pkgconfig(capi-media-image-util)
+BuildRequires: pkgconfig(osp-appfw)
+BuildRequires: osp-appfw-internal-devel
+BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(libavcodec)
+BuildRequires: pkgconfig(libavformat)
+BuildRequires: pkgconfig(libavutil)
+BuildRequires: pkgconfig(libswscale)
+BuildRequires: pkgconfig(pango)
+BuildRequires: giflib-devel
+BuildRequires: libjpeg-turbo-devel
+BuildRequires: libtiff-devel
+
+# runtime requires
+Requires: osp-appfw
+
+Provides: libosp-image-core.so.1
+
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description
+The Media Image Core library of OSP
+
+%package devel
+Summary: The Media Image Core library of OSP (Development)
+Group: TO_BE/FILLED_IN
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+The Media Image Core library of OSP (DEV)
+
+%package internal-devel
+Summary: osp media image core internel (Internal)
+Group: TO_BE/FILLED_IN
+Requires: %{name} = %{version}-%{release}
+
+%description internal-devel
+The Media Image Core library of OSP (Internal-DEV)
+
+%package debug
+Summary: The Media Image Core library of OSP (Development)
+Group: TO_BE/FILLED_IN
+Requires: %{name} = %{version}-%{release}
+
+%description debug
+The Media Image Core library of OSP (DEV)
+
+%prep
+%setup -q
+
+%build
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+%ifarch %{ix86}
+CXXFLAGS="$CXXFLAGS -D_OSP_DEBUG_ -D_OSP_X86_ -D_OSP_EMUL_" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DOBS=1 -DFULLVER=%{version} -DMAJORVER=${MAJORVER} -DARCH=x86
+%else
+CXXFLAGS="-O2 -g -pipe -Wall -fno-exceptions -Wformat -Wformat-security -Wl,--as-needed -fmessage-length=0 -march=armv7-a -mtune=cortex-a8 -mlittle-endian -mfpu=neon -mfloat-abi=softfp -D__SOFTFP__ -mthumb -Wa,-mimplicit-it=thumb -funwind-tables -D_OSP_DEBUG_ -D_OSP_ARMEL_" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DOBS=1 -DFULLVER=%{version} -DMAJORVER=${MAJORVER} -DARCH=arm
+%endif
+
+# Call make instruction with smp support
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+cp %{_builddir}/%{name}-%{version}/LICENSE.APLv2.0 %{buildroot}/usr/share/license/%{name}
+
+%make_install
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest osp-image-core.manifest
+/usr/share/license/%{name}
+%{_libdir}/osp/libosp-image-core.so*
+
+%files devel
+%{_includedir}/osp/*.h
+%{_libdir}/pkgconfig/osp-image-core.pc
+
+%files internal-devel
+%{_includedir}/osp/media/*.h
+
+%files debug
+%{_libdir}/osp/debug/*.so*
+
--- /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_BmpDecoder.c
+ * @brief This file contains the implementation of _BmpDecoder class.
+ */
+#include <unique_ptr.h>
+#include <FBaseSysLog.h>
+#include <FMediaImageTypes.h>
+#include "FMedia_Ffmpeg.h"
+#include "FMedia_BmpDecoder.h"
+#include "FMedia_ImageUtil.h"
+
+using namespace Tizen::Io;
+using namespace Tizen::Base::Collection;
+
+namespace Tizen { namespace Media
+{
+
+static const int _INPUT_BUFFER_PADDING_SIZE = FF_INPUT_BUFFER_PADDING_SIZE;
+
+_BmpDecoder::_BmpDecoder(void)
+ : __pCodecCtx(null)
+ , __pCodec(null)
+ , __pVideoFrame(null)
+ , __pSrcBuf(null)
+ , __srcLength(0)
+ , __pixelFormat(MEDIA_PIXEL_FORMAT_NONE)
+{
+}
+
+_BmpDecoder::~_BmpDecoder(void)
+{
+ if (__pCodecCtx)
+ {
+ avcodec_flush_buffers(__pCodecCtx);
+ avcodec_close(__pCodecCtx);
+ av_free(__pCodecCtx);
+ }
+
+ if (__pVideoFrame)
+ {
+ av_free(__pVideoFrame);
+ }
+}
+
+result
+_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.");
+
+ res = avcodec_open(__pCodecCtx, __pCodec);
+ SysTryCatch(NID_MEDIA, res >= 0, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] Failed to open bmp decoder.");
+
+ // AVCodecContext parameters
+ if (__pCodec->capabilities & CODEC_CAP_TRUNCATED)
+ {
+ __pCodecCtx->flags |= CODEC_FLAG_TRUNCATED;
+ }
+
+ // Allocate memory for decoder output.
+ __pVideoFrame = avcodec_alloc_frame();
+ SysTryCatch(NID_MEDIA, __pVideoFrame != null, r = E_OUT_OF_MEMORY,
+ E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Output buffer allocation failed");
+
+ return r;
+
+CATCH:
+ CloseCodec();
+
+ return r;
+}
+
+void
+_BmpDecoder::CloseCodec(void)
+{
+ if (__pCodecCtx)
+ {
+ avcodec_close(__pCodecCtx);
+ av_free(__pCodecCtx);
+ __pCodecCtx = null;
+ __pCodec = null;
+ }
+
+ //__inputPacket.size = 0;
+ //SAFE_DELETE_ARRAY(__inputPacket.data);
+}
+
+result
+_BmpDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
+{
+ result r = E_SUCCESS;
+ // uint8_t* pInputData = null;
+ int res = 0;
+ int gotPicture = 0;
+ AVPacket pkt;
+
+ SysTryCatch(NID_MEDIA, buffer != null, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] buffer is null.");
+
+ SysTryCatch(NID_MEDIA, length > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] length is zero.");
+
+ // _TRY_CATCH_INVALID_STATE(!__pCodecCtx);
+ SysTryCatch(NID_MEDIA, !__pCodecCtx, r = E_INVALID_STATE, E_INVALID_STATE,
+ "[E_INVALID_STATE] Already Constructed");
+
+ // Initialize ffmpeg.
+ r = OpenCodec();
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] Could not initialize FFMPEG.");
+
+ // Forming the input packet for decoder.
+ av_init_packet(&pkt);
+ // Decoder input must end in a padding of 8 zeroes.
+ pkt.size = length + _INPUT_BUFFER_PADDING_SIZE;
+ __pSrcBuf.reset(new (std::nothrow) byte[pkt.size]);
+ SysTryCatch(NID_MEDIA, __pSrcBuf.get() != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes for input frame.", pkt.size);
+ memcpy(__pSrcBuf.get(), buffer, length);
+ memset(__pSrcBuf.get() + length, 0, _INPUT_BUFFER_PADDING_SIZE);
+ pkt.data = (uint8_t*)__pSrcBuf.get();
+
+ // NOTE:
+ // Decoding has been done in Construct instead of in DecodeN
+ // function because GetDimension is called in the _ImageDecoderImpl
+ // function, before decode. Since dimensions are not available
+ // till the image is decoded, decode is done here.
+ // If "avcodec_decode_video2" must be moved to "DecodeN",
+ // then the sequence of calls in _ImageDecoderImpl should be changed.
+ //
+
+ res = avcodec_decode_video2(__pCodecCtx, __pVideoFrame, &gotPicture, &pkt);
+ // avcodec_decode_video2 returns res greater than zero on success.
+ SysTryCatch(NID_MEDIA, res > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Decode Failed");
+ // The value of gotPicture is non zero if a frame is found.
+ SysTryCatch(NID_MEDIA, gotPicture, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Decode Failed");
+
+ // Dimensions are __pCodecCtx->width and __pCodecCtx->height.
+ return r;
+
+CATCH:
+ CloseCodec();
+ return r;
+}
+
+byte*
+_BmpDecoder::DecodeN(int& outLength)
+{
+ int resFfmpeg = 0;
+
+ std::unique_ptr<byte[]> pOutBuf;
+
+ SysTryReturn(NID_MEDIA, __pCodecCtx, null, E_INVALID_STATE,
+ "[E_INVALID_STATE] Not Constructed");
+
+ // The following steps convert the decoder output to RGB565LE
+ // format, irrespective of decoder output format.
+ // Also required to eliminate the "padding" present in decoder
+ // output data.
+ //
+ outLength = avpicture_get_size(__pCodecCtx->pix_fmt, __pCodecCtx->width,
+ __pCodecCtx->height);
+ SysTryReturn(NID_MEDIA, 0 < outLength, null, E_OUT_OF_MEMORY, "FFMPEG returned buffer size as zero.");
+
+ pOutBuf.reset(new (std::nothrow) byte[outLength]);
+ SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Memory allocation of %d bytes for output buffer failed!", outLength);
+ __pixelFormat = _ImageUtil::ToMediaPixelFormatFromFfmpeg(__pCodecCtx->pix_fmt);
+
+ resFfmpeg = av_image_copy_to_buffer(pOutBuf.get(), outLength,
+ (const uint8_t * const*)__pVideoFrame->data, (const int*)__pVideoFrame->linesize,
+ __pCodecCtx->pix_fmt, __pCodecCtx->width, __pCodecCtx->height, 1);
+
+ SysTryReturn(NID_MEDIA, resFfmpeg >= 0, null, E_SYSTEM,
+ "[E_SYSTEM] Could not copy image data to buffer!!");
+
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+}
+
+result
+_BmpDecoder::SetDecodingRegion(int x, int y, int width, int height)
+{
+ // result r = E_SUCCESS;
+
+ // SysTryCatch(NID_MEDIA, __isConstructed, r = E_INVALID_STATE,
+ // E_INVALID_STATE, "[E_INVALID_STATE] Instance is not constructed.");
+ // TODO
+
+// CATCH:
+ return E_UNSUPPORTED_OPERATION;
+}
+
+result
+_BmpDecoder::GetDimension(int& width, int& height)
+{
+ result r = E_SUCCESS;
+
+ SysTryCatch(NID_MEDIA, __pCodecCtx, r = E_INVALID_STATE,
+ E_INVALID_STATE, "[E_INVALID_STATE] Not Constructed.");
+
+ 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;
+}
+
+MediaPixelFormat
+_BmpDecoder::GetPixelFormat(void)
+{
+ result r = E_SUCCESS;
+ MediaPixelFormat pixel_format = MEDIA_PIXEL_FORMAT_NONE;
+
+ SysTryReturn(NID_MEDIA, __pCodecCtx, pixel_format, E_INVALID_STATE,
+ "[E_INVALID_STATE] Not constructed");
+
+ return __pixelFormat;
+}
+
+result
+_BmpDecoder::SetScaleDown(int scaleDown)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturn(NID_MEDIA, __pCodecCtx, E_INVALID_STATE, E_INVALID_STATE,
+ "[E_INVALID_STATE] Not Constructed.");
+ // TODO
+ return r;
+}
+
+result
+_BmpDecoder::GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+}} // Tizen::Media
--- /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_BmpDecoder.h
+ * @brief This is header file for _BmpDecoder class.
+ *
+ */
+#ifndef _FMEDIA_INTERNAL_BMP_DECODER_H_
+#define _FMEDIA_INTERNAL_BMP_DECODER_H_
+
+#include <unique_ptr.h>
+#include "FMedia_IImageDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+class _BmpDecoder
+ : public _IImageDecoder
+ , public Tizen::Base::Object
+{
+public:
+ static const int MAX_SIZE = 15000000;
+ static const int MAX_WIDTH = 3000;
+ static const int MAX_HEIGHT = 3000;
+ static const int BYTES_PER_PIXEL_RGB565 = 2;
+
+ _BmpDecoder(void);
+
+ virtual ~_BmpDecoder(void);
+
+ /**
+ * Constructs this instancce with given buffer and length.
+ *
+ * @return An error code
+ * @param[in] buffer The buffer that contains compressed data.
+ * @param[in] length The length of buffer.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual result Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat);
+
+ /**
+ * Decodes current frame and returns decoded data.
+ *
+ * @return A buffer pointer of decoded data
+ * @param[out] outLength The length of outBuf.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_DATA The data is invalid.
+ */
+ virtual byte* DecodeN(int& outLength);
+
+ /**
+ * Sets the decoding region. @n
+ *
+ * @return An error code
+ * @param[in] rect The decoding region.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetDecodingRegion(int x, int y, int width, int height);
+
+ /**
+ * Gets current dimension of image.
+ *
+ * @return An error code
+ * @param[out] width The width of image.
+ * @param[out] height The height of image.
+ */
+ virtual result GetDimension(int& width, int& height);
+
+ /**
+ * Gets the output pixel format.
+ *
+ * @return The output pixel format.
+ */
+ virtual MediaPixelFormat GetPixelFormat(void);
+
+ /**
+ * Sets scale down degree.
+ *
+ * @return An error code
+ * @param[in] scaleDown The level of scale down.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetScaleDown(int scaleDown);
+
+ /**
+ * Gets the value of given key.
+ *
+ * @return An error code
+ * @param[in] key The key of the value.
+ * @param[out] value The output value.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+private:
+ /**
+ * Initializes the ffmpeg codec and codec context.
+ *
+ * @return An error code
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_SYSTEM Error occured when initializing FFMPEG resources.
+ */
+ result OpenCodec(void);
+
+ /**
+ * Uninitializes the ffmpeg codec and codec context.
+ */
+ void CloseCodec(void);
+
+ AVCodecContext* __pCodecCtx;
+ AVCodec* __pCodec;
+ AVFrame* __pVideoFrame;
+ std::unique_ptr<byte[]> __pSrcBuf;
+ int __srcLength;
+ MediaPixelFormat __pixelFormat;
+
+ _BmpDecoder(const _BmpDecoder& rhs);
+ _BmpDecoder& operator =(const _BmpDecoder& rhs);
+
+}; // class _BmpDecoder
+
+
+} } // Tizen::Media
+
+#endif
--- /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_BmpEncoder.c
+ * @brief This file contains the implementation of _BmpEncoder class.
+ *
+ */
+
+#include <unique_ptr.h>
+#include <FMediaImageTypes.h>
+#include <FBaseSysLog.h>
+#include "FMedia_Ffmpeg.h"
+#include "FMedia_BmpEncoder.h"
+#include "FMedia_ImageUtil.h"
+
+using namespace Tizen::Base;
+
+namespace Tizen { namespace Media
+{
+
+_BmpEncoder::_BmpEncoder(void)
+{
+ __pCodecCtx = null;
+ __pCodec = null;
+ __pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
+ __quality = 90;
+ __width = 0;
+ __height = 0;
+}
+
+_BmpEncoder::~_BmpEncoder(void)
+{
+ if (__pCodecCtx)
+ {
+ avcodec_flush_buffers(__pCodecCtx);
+ avcodec_close(__pCodecCtx);
+ av_free(__pCodecCtx);
+ __pCodecCtx = null;
+ __pCodec = null;
+ }
+}
+
+result
+_BmpEncoder::Construct(int width, int height,
+ MediaPixelFormat srcPixelFormat,
+ MediaPixelFormat& reqPixelFormat,
+ int quality)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturnResult(NID_MEDIA, width >= MIN_WIDTH, E_INVALID_ARG,
+ "Width (%d) < minimum bmp width (%d)", width, MIN_WIDTH);
+ SysTryReturnResult(NID_MEDIA, height >= MIN_HEIGHT, E_INVALID_ARG,
+ "Height (%d) < minimum bmp height (%d)", height, MIN_HEIGHT);
+ SysTryReturnResult(NID_MEDIA, quality > 0, E_INVALID_ARG,
+ "Quality should be greater than 0 (%d)", quality);
+ SysTryReturnResult(NID_MEDIA, quality <= 100, E_INVALID_ARG,
+ "Quality should be lesser than 100 (%d)", quality);
+
+ __width = width;
+ __height = height;
+ __quality = quality;
+ __pixelFormat = MEDIA_PIXEL_FORMAT_BGR888;
+ 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.");
+
+ // Context required for opening BMP encoder.
+ // Specifying output image format
+ __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;
+}
+
+void
+_BmpEncoder::CloseCodec(void)
+{
+ if (__pCodecCtx)
+ {
+ avcodec_close(__pCodecCtx);
+ av_free(__pCodecCtx);
+ __pCodecCtx = null;
+ __pCodec = null;
+ }
+}
+
+Tizen::Base::ByteBuffer*
+_BmpEncoder::EncodeN(const byte* srcBuf, 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;
+
+ // 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.");
+
+ 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.");
+
+ // 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[1] = 0;
+ pVideoFrame->data[2] = 0;
+ pVideoFrame->data[3] = 0;
+ pVideoFrame->linesize[0] = (__width) * BYTES_PER_PIXEL_RGB;
+ pVideoFrame->linesize[1] = 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;
+ }
+
+ tmpDstLength = BMP_HEADER_SIZE_
+ + (((__width * BYTES_PER_PIXEL_RGB) + widthPadding) * __height);
+
+ // 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;
+ }
+
+ 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);
+ pRetBuf->Flip();
+
+ av_free(pVideoFrame);
+
+ return pRetBuf.release();
+
+CATCH:
+ if (pVideoFrame != null)
+ {
+ av_free(pVideoFrame);
+ }
+ return null;
+}
+
+result
+_BmpEncoder::SetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+}} // Tizen::Media
--- /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_BmpEncoder.h
+ * @brief This is header file for _BmpEncoder class.
+ *
+ */
+
+#ifndef _FMEDIA_INTERNAL_BMP_ENCODER_H_
+#define _FMEDIA_INTERNAL_BMP_ENCODER_H_
+
+#include "FMedia_IImageEncoder.h"
+
+namespace Tizen { namespace Media
+{
+
+class _BmpEncoder
+ : public _IImageEncoder
+ , public Tizen::Base::Object
+{
+public:
+ // BMP header size for a 24byte image is 54 bytes.
+ static const int BMP_HEADER_SIZE_ = 54;
+ static const int BYTES_PER_PIXEL_RGB = 3;
+ static const int FF_PADDING_BYTES = 8;
+ static const int MIN_WIDTH = 1;
+ static const int MIN_HEIGHT = 1;
+
+ /**
+ * This is the default constructor for this class.
+ *
+ * @see Construct()
+ */
+ _BmpEncoder(void);
+
+ /**
+ * This is the destructor for this class.
+ *
+ * @see Construct()
+ */
+ virtual ~_BmpEncoder(void);
+
+ /**
+ * Initialize this instance.
+ * @param[in] dim Encode dimension
+ * @param[in] pixelFormat Encode pixel format
+ * @param[in] quality Encoding quality
+ */
+ virtual result Construct(int width, int height,
+ MediaPixelFormat srcPixelFormat,
+ MediaPixelFormat& reqPixelFormat,
+ int quality);
+
+ /**
+ * Encodes the image data
+ *
+ * @return An error code
+ * @param[in] srcBuf Source raw data
+ * @param[in] srcLength Source data length
+ * @param[out] dstBuf Encoded destination buffer
+ * @param[out] dstLength Destination buffer length
+ *
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual Tizen::Base::ByteBuffer* EncodeN(const byte* srcBuf, int srcLength);
+
+ /**
+ * Set specific key value to the encoder
+ * @return An error code
+ * @param[in] key The key to be set
+ * @param[in] value The value to be set.
+ */
+ virtual result SetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+protected:
+
+
+private:
+ result OpenCodec(int width, int height, MediaPixelFormat pixelFormat);
+ void CloseCodec(void);
+
+ int __width;
+ int __height;
+ int __quality;
+ MediaPixelFormat __pixelFormat;
+
+ AVCodecContext* __pCodecCtx;
+ AVCodec* __pCodec;
+}; // class _BmpEncoder
+
+
+};
+};
+
+#endif
--- /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_ColorConverterImpl.cpp
+ * @brief This is the implementation file for the FMedia::_ColorConverterImpl.
+ *
+ * This file contains the implementations of the FMedia::_ColorConverterImpl.
+ */
+
+#include <stdlib.h>
+#include <unique_ptr.h>
+#include <FGrpBitmapCommon.h>
+#include <FMediaImageTypes.h>
+#include <FBaseSysLog.h>
+#include "FMedia_Ffmpeg.h"
+#include "FMedia_ImageUtil.h"
+#include "FMedia_ColorConverter.h"
+
+using namespace Tizen::Base;
+
+namespace Tizen { namespace Media
+{
+
+_ColorConverter::_ColorConverter(void)
+ : __srcWidth(0)
+ , __srcHeight(0)
+ , __dstWidth(0)
+ , __dstHeight(0)
+ , __origSrcWidth(0)
+ , __origSrcHeight(0)
+ , __origDstWidth(0)
+ , __origDstHeight(0)
+ , __srcFormat(MEDIA_PIXEL_FORMAT_NONE)
+ , __dstFormat(MEDIA_PIXEL_FORMAT_NONE)
+ , __ffSrcFormat(PIX_FMT_NONE)
+ , __ffDstFormat(PIX_FMT_NONE)
+ , __pCvtCtxt(null)
+ , __toResizeIn(false)
+ , __toResizeOut(false)
+{
+}
+
+_ColorConverter::~_ColorConverter(void)
+{
+ if (__pCvtCtxt)
+ {
+ sws_freeContext(__pCvtCtxt);
+ }
+}
+
+result
+_ColorConverter::Construct(MediaPixelFormat srcFormat, int srcWidth, int srcHeight,
+ MediaPixelFormat dstFormat, int dstWidth, int dstHeight)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturn(NID_MEDIA, !__pCvtCtxt, r = E_INVALID_STATE, E_INVALID_STATE,
+ "[E_INVALID_STATE] Convert Context is not null.");
+
+ SysTryReturn(NID_MEDIA, srcWidth > 0 && srcHeight > 0,
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be greater than zero. Check source: (%d x %d).", srcWidth, srcHeight);
+
+ SysTryReturn(NID_MEDIA, dstWidth > 0 && dstHeight > 0,
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be greater than zero. Check destination: (%d x %d).", dstWidth, dstHeight);
+
+ __srcFormat = srcFormat;
+ __origSrcWidth = srcWidth;
+ __origSrcHeight = srcHeight;
+ __origDstWidth = dstWidth;
+ __origDstHeight = dstHeight;
+ __srcWidth = srcWidth;
+ __srcHeight = srcHeight;
+ __dstFormat = dstFormat;
+ __dstWidth = dstWidth;
+ __dstHeight = dstHeight;
+
+ // swscale does not accept srcWidth < 4 and dstWidth < 8.
+ if (srcWidth < 4)
+ {
+ __srcWidth = 4;
+ __toResizeIn = true;
+ __srcHeight = srcHeight * (__srcWidth / srcWidth);
+ }
+
+ if (dstWidth < 8)
+ {
+ __dstWidth = 8;
+ __toResizeOut = true;
+ __dstHeight = dstHeight * (__dstWidth / dstWidth);
+ }
+
+ // Get ffmpeg format type
+ __ffSrcFormat = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(__srcFormat);
+ SysTryReturn(NID_MEDIA, __ffSrcFormat != PIX_FMT_NONE,
+ r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "[E_UNSUPPORTED_FORMAT] Source pixel format (%d) is not supported.", __srcFormat);
+
+ __ffDstFormat = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(__dstFormat);
+ SysTryReturn(NID_MEDIA, __ffDstFormat != PIX_FMT_NONE,
+ 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);
+
+ 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,
+ __dstWidth, __dstHeight, __ffDstFormat);
+
+ return r;
+}
+
+Tizen::Base::ByteBuffer*
+_ColorConverter::ConvertN(const Tizen::Base::ByteBuffer& srcBuf)
+{
+ result r = E_SUCCESS;
+ int outLength = 0;
+ std::unique_ptr<byte[]> pOutBuf;
+
+ pOutBuf.reset(ConvertN(srcBuf.GetPointer(), srcBuf.GetCapacity(), outLength));
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+
+ std::unique_ptr<ByteBuffer> pDstBuf(new (std::nothrow) ByteBuffer());
+ SysTryReturn(NID_MEDIA, pDstBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
+
+ r = pDstBuf->Construct(outLength);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] Propagated. Could not construct ByteBuffer of %d bytes.",
+ GetErrorMessage(r), outLength);
+
+ r = pDstBuf->SetArray(pOutBuf.get(), 0, outLength);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] Propagated. ByteBuffer.SetArray failed for buffer size %d.",
+ GetErrorMessage(r), outLength);
+
+ r = pDstBuf->SetPosition(0);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] Propagated. ByteBuffer.SetPosition(0) failed.",
+ GetErrorMessage(r));
+
+ SetLastResult(E_SUCCESS);
+ return pDstBuf.release();
+}
+
+byte*
+_ColorConverter::ConvertN(const byte* pSrcBuf, int srcLength, int& dstLength)
+{
+ result r = E_SUCCESS;
+ int size = 0;
+ std::unique_ptr<byte[]> pDstBuf;
+ PixelFormat srcFormat = __ffSrcFormat;
+ PixelFormat dstFormat = __ffDstFormat;
+
+ SysTryReturn(NID_MEDIA, __pCvtCtxt, null, E_INVALID_STATE, "Convert Context is null");
+
+ size = avpicture_get_size(srcFormat, __origSrcWidth, __origSrcHeight);
+ SysTryReturn(NID_MEDIA, size <= srcLength, null, E_INVALID_ARG,
+ "[E_INVALID_ARG] underflow: size calculated (%d) < source size (%d), for (%d x %d), pixelformat (%d)",
+ size, srcLength, __origSrcWidth, __origSrcHeight, srcFormat);
+
+ // Allocate output buffer.
+ size = avpicture_get_size(dstFormat, __origDstWidth, __origDstHeight);
+ SysTryReturn(NID_MEDIA, size > 0, null, E_INVALID_ARG,
+ "[E_INVALID_ARG] Check arguments: size calculated = %d, for (%d x %d), pixelformat (%d)",
+ size, __origDstWidth, __origDstHeight, dstFormat);
+
+ pDstBuf.reset(new (std::nothrow) byte[size]);
+ SysTryReturn(NID_MEDIA, pDstBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes.", size);
+
+ dstLength = size;
+ memset(pDstBuf.get(), 0, dstLength);
+
+ r = Convert(pSrcBuf, srcLength, pDstBuf.get(), dstLength);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] Could not convert to dstBuf.", GetErrorMessage(r));
+
+ SetLastResult(E_SUCCESS);
+ return pDstBuf.release();
+}
+
+result
+_ColorConverter::Convert(const byte* srcBuf, int srcLength, byte* dstBuf, int dstLength)
+{
+ result r = E_SUCCESS;
+ AVPicture srcFrame;
+ AVPicture dstFrame;
+ int size = 0;
+ byte* pInputBuf = null;
+ std::unique_ptr<byte[]> pResizeBuf;
+ std::unique_ptr<byte[]> pOutputBuf;
+ PixelFormat srcFormat = __ffSrcFormat;
+ PixelFormat dstFormat = __ffDstFormat;
+
+ SysTryReturnResult(NID_MEDIA, __pCvtCtxt, E_INVALID_STATE, "Convert Context is null");
+
+ size = avpicture_get_size(srcFormat, __origSrcWidth, __origSrcHeight);
+ SysTryReturn(NID_MEDIA, size <= srcLength, E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] underflow: size calculated (%d) < source size (%d), for (%d x %d), pixelformat (%d)",
+ size, srcLength, __origSrcWidth, __origSrcHeight, srcFormat);
+
+ size = avpicture_get_size(dstFormat, __origDstWidth, __origDstHeight);
+ SysTryReturn(NID_MEDIA, dstBuf != null && (size <= dstLength) , E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Check arguments: size calculated (%d) < out Buffer length (%d), for (%d x %d), pixelformat (%d)",
+ size, dstLength, __origDstWidth, __origDstHeight, dstFormat);
+
+ if (__toResizeOut == true)
+ {
+ size = avpicture_get_size(dstFormat, __dstWidth, __dstHeight + 1);
+ SysTryReturn(NID_MEDIA, size > 0, E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Check arguments: size calculated = %d, for (%d x %d), pixelformat (%d)",
+ size, __dstWidth, __dstHeight + 1, dstFormat);
+
+ pOutputBuf.reset(new (std::nothrow) byte[size]);
+ SysTryReturn(NID_MEDIA, pOutputBuf.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes", size);
+ dstLength = size;
+ memset(pOutputBuf.get(), 0, dstLength);
+ }
+ else
+ {
+ size = avpicture_get_size(dstFormat, __origDstWidth, __origDstHeight + 1);
+ SysTryReturn(NID_MEDIA, size > 0, E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Check arguments: size calculated = %d, for (%d x %d), pixelformat (%d)",
+ size, __origDstWidth, __origDstHeight + 1, dstFormat);
+
+ pOutputBuf.reset(new (std::nothrow) byte[size]);
+ SysTryReturn(NID_MEDIA, pOutputBuf.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes", size);
+ }
+
+ if (__toResizeIn == true)
+ {
+ // Resize input from __origSrcWidth-Height to __srcWidth-Height
+ int bufferSize = _ImageUtil::GetBufferSize(__srcFormat, __srcWidth, __srcHeight);
+ SysTryReturn(NID_MEDIA, bufferSize > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] underflow: size calculated (%d) < source size (%d), for (%d x %d), pixelformat (%d)",
+ bufferSize, srcLength, srcFormat, __origSrcWidth, __origSrcHeight);
+
+ pResizeBuf.reset(new (std::nothrow) byte[bufferSize]);
+ SysTryReturn(NID_MEDIA, pResizeBuf.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes.", bufferSize);
+
+ pInputBuf = pResizeBuf.get();
+ r = _ImageUtil::ResizeBuffer(srcBuf, __srcFormat, __origSrcWidth, __origSrcHeight,
+ pInputBuf, __srcWidth, __srcHeight);
+
+ SysTryReturn(NID_MEDIA, pInputBuf != null, GetLastResult(), GetLastResult(),
+ "[%s] Could not resize input buffer for ffmpeg input.", GetErrorMessage(r));
+ }
+ else
+ {
+ pInputBuf = const_cast<byte*>(srcBuf);
+ }
+
+ // Clear all buffers.
+ memset(&srcFrame, 0, sizeof(srcFrame));
+ memset(&dstFrame, 0, sizeof(dstFrame));
+
+ // Fill source frame
+ avpicture_fill((AVPicture*)&srcFrame, (byte*)pInputBuf, srcFormat, __srcWidth, __srcHeight);
+
+ // Fill dest frame
+ avpicture_fill((AVPicture*)&dstFrame, (byte*)pOutputBuf.get(), dstFormat, __dstWidth, __dstHeight);
+
+ // Scaling
+ sws_scale(__pCvtCtxt, srcFrame.data, srcFrame.linesize, 0, __srcHeight,
+ dstFrame.data, dstFrame.linesize);
+
+ if (__toResizeOut != true)
+ {
+ // Copy resized data to output buffer.
+ memcpy(dstBuf, pOutputBuf.get(), dstLength);
+ }
+ else
+ {
+ // Resize output from __dstWidth-Height to __origDstWidth-Height
+ r = _ImageUtil::ResizeBuffer(pOutputBuf.get(), __dstFormat, __dstWidth, __dstHeight,
+ dstBuf, __origDstWidth, __origDstHeight);
+ SysTryReturn(NID_MEDIA, dstBuf != null, GetLastResult(), GetLastResult(),
+ "[%s] Could not resize output buffer.", GetErrorMessage(r));
+ }
+
+ return E_SUCCESS;
+}
+
+}} // Tizen::Media
--- /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_EvasDef.h
+ * @brief This is the header file for the evas related header inclusion.
+ *
+ * This header file contains the declarations of data structures for evas.
+ */
+#ifndef _FMEDIA_INTERNAL_EVAS_DEF_H_
+#define _FMEDIA_INTERNAL_EVAS_DEF_H_
+
+#endif
--- /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_GifDecoderImpl.cpp
+ * @brief This file contains the implementation of _GifDecoder class.
+ */
+
+#include <unique_ptr.h>
+#include <gif_lib.h>
+#include <FBaseLong.h>
+#include <FMediaImageTypes.h>
+#include <FBaseSysLog.h>
+#include "FMedia_GifDecoder.h"
+
+using namespace Tizen::Base;
+using namespace Tizen::Io;
+
+namespace Tizen { namespace Media
+{
+
+static int _INTERLACED_OFFSET[] = { 0, 4, 2, 1 }; // The way Interlaced image should.
+static int _INTERLACED_JUMPS[] = { 8, 8, 4, 2 }; // be read - offsets and jumps...
+
+#define RGBA8888(r, g, b, a) \
+ ((((a) & 0x0ff) << 24) | (((b) & 0x0ff) << 16) | (((g) & 0x0ff) << 8) | ((r) & 0x0ff))
+#define BGRA8888(r, g, b, a) \
+ ((((unsigned int) (a) & 0x0ff) << 24) | (((unsigned int) (r) & 0x0ff) << 16) \
+ | (((unsigned int) (g) & 0x0ff) << 8) | ((unsigned int) (b) & 0x0ff))
+#define RGB565LE(r, g, b) \
+ ((((unsigned short) (r) & 0x0f8) << 8) | \
+ (((unsigned short) (g) & 0x0fc) << 3) | (((unsigned short) (b) & 0x0f8) >> 3))
+
+_GifDecoder::_GifDecoder(void)
+{
+ __pDec = null;
+ __bpp = 2;
+ __transparent = false;
+ __transColor = 0;
+ __pixelFormat = MEDIA_PIXEL_FORMAT_RGB565LE;
+ __firstFramePos = 0;
+ __dstLength = 0;
+ __srcWidth = 0;
+ __srcHeight = 0;
+ __frameIndex = 0;
+ __duration = 0;
+ __totalFrames = 0;
+}
+
+_GifDecoder::~_GifDecoder(void)
+{
+ if (__pDec)
+ {
+ DGifCloseFile(__pDec);
+ }
+}
+
+int
+_GifDecoder::BufferReadFuncStatic(struct GifFileType* gifFile, unsigned char* buf, int count)
+{
+ _GifDecoder* pGifImg = (_GifDecoder*)gifFile->UserData;
+ if (pGifImg == null)
+ {
+ return -1;
+ }
+ return pGifImg->BufferReadFunc(buf, count);
+}
+
+int
+_GifDecoder::BufferReadFunc(unsigned char* buf, int count)
+{
+ result r = E_SUCCESS;
+ count = (__srcBuf.GetRemaining() > count) ? count : __srcBuf.GetRemaining();
+
+ r = __srcBuf.GetArray(buf, 0, count);
+
+ if (IsFailed(r))
+ {
+ return -1;
+ }
+
+ return count;
+}
+
+result
+_GifDecoder::ConstructBuffer(MediaPixelFormat pixelFormat)
+{
+ byte* pPalette = null;
+ result r = E_SUCCESS;
+ int loopIndex = 0;
+ int xpos = 0;
+ int ypos = 0;
+ int width = 0;
+ int height = 0;
+ const byte* pDataPtr = null;
+ int dataSize = 0;
+
+ __pixelFormat = pixelFormat;
+ __bpp = (__pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE) ? 2 : 4;
+
+ __pGlobalPalette.reset(GeneratePaletteN(pixelFormat, __pDec->SColorMap));
+
+ // Global Pattle might not exist in all the images, in those cases we
+ // should expect a Local palatte and continue here
+ // SysTryCatch(NID_MEDIA, __pGlobalPalette, r = GetLastResult(), GetLastResult(),
+ // "[%s] Propagated.", GetErrorMessage(GetLastResult()));
+
+ __dstLength = __pDec->SWidth * __pDec->SHeight * __bpp;
+ SysTryReturn(NID_MEDIA, __dstLength > 0, E_SYSTEM, E_SYSTEM, "invalid size:%d", __dstLength);
+ __pDstByte.reset(new (std::nothrow) byte[__dstLength]);
+ SysTryReturn(NID_MEDIA, __pDstByte.get(), E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "new byte:%d", __dstLength);
+
+ if (__pGlobalPalette.get())
+ {
+ pPalette = (byte*) __pGlobalPalette.get();
+
+ if (__bpp == 2)
+ {
+ unsigned short* pBuf = (unsigned short*) __pDstByte.get();
+ for (loopIndex = 0; loopIndex < __pDec->SWidth; loopIndex++) // Set its color to BackGround
+ {
+ pBuf[loopIndex] = ((unsigned short*) pPalette)[__pDec->SBackGroundColor];
+ }
+ for (loopIndex = 1; loopIndex < __pDec->SHeight; loopIndex++)
+ {
+ memcpy(pBuf + __pDec->SWidth * loopIndex, pBuf, __pDec->SWidth * __bpp);
+ }
+ }
+ else // if (__bpp == 4)
+ {
+ unsigned int* pBuf = (unsigned int*) __pDstByte.get();
+ for (loopIndex = 0; loopIndex < __pDec->SWidth; loopIndex++) // Set its color to BackGround
+ {
+ pBuf[loopIndex] = ((unsigned int*) pPalette)[__pDec->SBackGroundColor];
+ }
+ for (loopIndex = 1; loopIndex < __pDec->SHeight; loopIndex++)
+ {
+ memcpy(pBuf + __pDec->SWidth * loopIndex, pBuf, __pDec->SWidth * __bpp);
+ }
+ }
+ }
+ pDataPtr = __srcBuf.GetPointer();
+ dataSize = __srcBuf.GetCapacity();
+ __totalFrames = 0;
+
+ __srcWidth = pDataPtr[7] << 8 | pDataPtr[6];
+ __srcHeight = pDataPtr[9] << 8 | pDataPtr[8];
+ for (loopIndex = 10; loopIndex < dataSize; loopIndex++)
+ {
+ if (pDataPtr[loopIndex] == 0x2c)
+ {
+ loopIndex++;
+ xpos = pDataPtr[loopIndex + 1] << 8 | pDataPtr[loopIndex];
+ ypos = pDataPtr[loopIndex + 3] << 8 | pDataPtr[loopIndex + 2];
+ width = pDataPtr[loopIndex + 5] << 8 | pDataPtr[loopIndex + 4];
+ height = pDataPtr[loopIndex + 7] << 8 | pDataPtr[loopIndex + 6];
+
+ if ((xpos <= __srcWidth) && (ypos <= __srcHeight) &&
+ (width <= __srcWidth) && (height <= __srcHeight))
+ {
+ if (__totalFrames == 0)
+ {
+ __firstFramePos = loopIndex;
+ }
+ __totalFrames++;
+ }
+ }
+ }
+
+ __srcWidth = __pDec->SWidth;
+ __srcHeight = __pDec->SHeight;
+ r = E_SUCCESS;
+
+ return r;
+}
+
+
+byte*
+_GifDecoder::GeneratePaletteN(MediaPixelFormat fmt, struct ColorMapObject* pColorMap)
+{
+ byte* pPalette = null;
+ int bpp = 0;
+ int loopIndex = 0;
+ result r = E_SUCCESS;
+
+ SysTryReturn(NID_MEDIA, fmt == MEDIA_PIXEL_FORMAT_RGB565LE || fmt == MEDIA_PIXEL_FORMAT_BGRA8888,
+ null, E_INVALID_ARG,
+ "Unsupported Pixel format: %d. Supported formats are %d and %d", fmt,
+ MEDIA_PIXEL_FORMAT_RGB565LE, MEDIA_PIXEL_FORMAT_BGRA8888);
+ SysTryReturn(NID_MEDIA, pColorMap && pColorMap->ColorCount > 0, null, E_INVALID_ARG,
+ "colorMap is invalid: 0x%x => Color count = %d", pColorMap, pColorMap ? pColorMap->ColorCount : 0);
+
+ bpp = (fmt == MEDIA_PIXEL_FORMAT_RGB565LE) ? 2 : 4;
+
+ pPalette = new (std::nothrow) byte[pColorMap->ColorCount * bpp];
+ SysTryReturn(NID_MEDIA, pPalette != null, null, E_OUT_OF_MEMORY,
+ "palette alloc failed for (%d x %d) bytes.", pColorMap->ColorCount , bpp);
+
+ if (bpp == 4)
+ {
+ for (loopIndex = 0; loopIndex < pColorMap->ColorCount; loopIndex++)
+ {
+ unsigned int* pPal = (unsigned int*) pPalette;
+ GifColorType* pColor = &pColorMap->Colors[loopIndex];
+ pPal[loopIndex] = BGRA8888(pColor->Red, pColor->Green, pColor->Blue, 255);
+ }
+ }
+ else // if (bpp == 2)
+ {
+ for (loopIndex = 0; loopIndex < pColorMap->ColorCount; loopIndex++)
+ {
+ unsigned short* pPal = (unsigned short*) pPalette;
+ GifColorType* pColor = &pColorMap->Colors[loopIndex];
+ pPal[loopIndex] = RGB565LE(pColor->Red, pColor->Green, pColor->Blue);
+ }
+ }
+ r = E_SUCCESS;
+ SetLastResult(r);
+ return pPalette;
+}
+
+result
+_GifDecoder::DecodeOneFrame(unsigned char* pDstBuffer, unsigned int length)
+{
+ result r = E_SUCCESS;
+ int loopIndex = 0;
+ int j = 0;
+ int k = 0;
+ int row = 0;
+ int col = 0;
+ int width = 0;
+ int height = 0;
+ int count = 0;
+ std::unique_ptr<byte[]> pLine;
+ byte* pPalette = null;
+
+ r = DGifGetImageDesc(__pDec);
+ SysTryReturn(NID_MEDIA, r != GIF_ERROR, E_INVALID_DATA, E_INVALID_DATA,
+ "DGifGetImageDesc failed: %x", GifLastError());
+
+ row = __pDec->Image.Top; // Image Position relative to Screen.
+ col = __pDec->Image.Left;
+ width = __pDec->Image.Width;
+ height = __pDec->Image.Height;
+
+ pLine.reset(new (std::nothrow) byte[width]);
+ SysTryReturn(NID_MEDIA, pLine.get(), E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Failed to allocate %d bytes for new pLine", width);
+
+ SysTryReturn(NID_MEDIA, __pDec->Image.Left + __pDec->Image.Width <= __pDec->SWidth &&
+ __pDec->Image.Top + __pDec->Image.Height <= __pDec->SHeight,
+ E_INVALID_DATA, E_INVALID_DATA,
+ "Image area exceeds it's frame size : (%d + %d) x (%d + %d) should be within (%d x %d)",
+ __pDec->Image.Left, __pDec->Image.Width, __pDec->Image.Top, __pDec->Image.Height,
+ __pDec->SWidth, __pDec->SHeight);
+
+ // Update Color map
+ if (__pDec->Image.ColorMap != null)
+ {
+ __pLocalPalette.reset(GeneratePaletteN(__pixelFormat, __pDec->Image.ColorMap));
+ SysTryReturn(NID_MEDIA, __pLocalPalette.get(), GetLastResult(), GetLastResult(),
+ "[%s] GeneratePaletteN failed for pixelFormat %d.",
+ GetErrorMessage(GetLastResult()), __pixelFormat);
+
+ pPalette = (byte*) __pLocalPalette.get();
+ }
+ else
+ {
+ pPalette = (byte*) __pGlobalPalette.get();
+ }
+
+ SysTryReturn(NID_MEDIA, pPalette != null, E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] pPalette is NULL!! Global or local pallete is absent so this is an invalid image");
+
+ if (__pDec->Image.Interlace)
+ {
+ // Need to perform 4 passes on the images:
+ if (__bpp == 2)
+ {
+ for (count = 0, loopIndex = 0; loopIndex < 4; loopIndex++)
+ {
+ for (j = row + _INTERLACED_OFFSET[loopIndex]; j < row + height; j += _INTERLACED_JUMPS[loopIndex])
+ {
+ unsigned short* pBuf = (unsigned short*) pDstBuffer + __pDec->SWidth * (row + j) + col;
+ r = DGifGetLine(__pDec, pLine.get(), width);
+ SysTryReturn(NID_MEDIA, r != GIF_ERROR, E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] DGifGetLineByte failed with code %x", GifLastError());
+ if (__transparent)
+ {
+ for (k = 0; k < width; k++)
+ {
+ pBuf[k] = (pLine[k] == __transColor) ? pBuf[k] : ((unsigned short*) pPalette)[pLine[k]];
+ }
+ }
+ else
+ {
+ for (k = 0; k < width; k++)
+ {
+ pBuf[k] = ((unsigned short*) pPalette)[pLine[k]];
+ }
+ }
+ }
+ }
+ }
+ else if (__bpp == 4)
+ {
+ for (count = 0, loopIndex = 0; loopIndex < 4; loopIndex++)
+ {
+ for (j = row + _INTERLACED_OFFSET[loopIndex]; j < row + height; j += _INTERLACED_JUMPS[loopIndex])
+ {
+ unsigned int* pBuf = (unsigned int*) pDstBuffer + __pDec->SWidth * (row + j) + col;
+ r = DGifGetLine(__pDec, pLine.get(), width);
+ SysTryReturn(NID_MEDIA, r != GIF_ERROR, E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] DGifGetLineByte failed with code %x", GifLastError());
+ if (__transparent)
+ {
+ for (k = 0; k < width; k++)
+ {
+ pBuf[k] = (pLine[k] == __transColor) ? pBuf[k] : ((unsigned int*) pPalette)[pLine[k]];
+ }
+ }
+ else
+ {
+ for (k = 0; k < width; k++)
+ {
+ pBuf[k] = ((unsigned int*) pPalette)[pLine[k]];
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (__bpp == 2)
+ {
+ for (loopIndex = 0; loopIndex < height; loopIndex++)
+ {
+ unsigned short* pBuf = (unsigned short*) pDstBuffer + __pDec->SWidth * (row + loopIndex) + col;
+ r = DGifGetLine(__pDec, pLine.get(), width);
+ SysTryReturn(NID_MEDIA, r != GIF_ERROR, E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] DGifGetLineByte failed with code %x", GifLastError());
+ if (__transparent)
+ {
+ for (k = 0; k < width; k++)
+ {
+ pBuf[k] = (pLine[k] == __transColor) ? pBuf[k] : ((unsigned short*) pPalette)[pLine[k]];
+ }
+ }
+ else
+ {
+ for (k = 0; k < width; k++)
+ {
+ pBuf[k] = ((unsigned short*) pPalette)[pLine[k]];
+ }
+ }
+ }
+ }
+ else if (__bpp == 4)
+ {
+ for (loopIndex = 0; loopIndex < height; loopIndex++)
+ {
+ unsigned int* pBuf = (unsigned int*) pDstBuffer + __pDec->SWidth * (row + loopIndex) + col;
+ r = DGifGetLine(__pDec, pLine.get(), width);
+ SysTryReturn(NID_MEDIA, r != GIF_ERROR, E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] DGifGetLineByte failed with code %x", GifLastError());
+ if (__transparent)
+ {
+ for (k = 0; k < width; k++)
+ {
+ pBuf[k] = (pLine[k] == __transColor) ? pBuf[k] : ((unsigned int*) pPalette)[pLine[k]];
+ }
+ }
+ else
+ {
+ for (k = 0; k < width; k++)
+ {
+ pBuf[k] = ((unsigned int*) pPalette)[pLine[k]];
+ }
+ }
+ }
+ }
+ }
+ length = __dstLength;
+ r = E_SUCCESS;
+ return r;
+}
+
+result
+_GifDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
+{
+ result r = E_SUCCESS;
+
+ SysTryCatch(NID_MEDIA, __pDec == null, r = E_INVALID_STATE, E_INVALID_STATE, "Already constructed");
+ SysTryCatch(NID_MEDIA, (buffer && (length > 0)), r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Wrong Arguments buffer - %x length - %d", buffer, length);
+
+ //__pixelFormat = pixelFormat;
+ if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
+ {
+ __pixelFormat = MEDIA_PIXEL_FORMAT_RGB565LE;
+ }
+ else
+ {
+ __pixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888;
+ }
+
+ r = __srcBuf.Construct(length);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
+ "[%s] ByteBuffer.Construct failed for size %d", GetErrorMessage(r), length);
+
+ r = __srcBuf.SetArray(buffer, 0, length);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
+ "[%s] Propagated. ByteBuffer.SetArray failed for buffer size %d.",
+ GetErrorMessage(r), length);
+ __srcBuf.Flip();
+
+ __pDec = DGifOpen((void*) this, BufferReadFuncStatic);
+ SysTryCatch(NID_MEDIA, __pDec, r = E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] DGifOpen failed with code %x", GifLastError());
+
+ SysTryCatch(NID_MEDIA, __pDec->SWidth && __pDec->SHeight, r = E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] Dimensions should be non zero (%d x %d)", __pDec->SWidth, __pDec->SHeight);
+
+ r = ConstructBuffer(__pixelFormat);
+
+CATCH:
+ return r;
+}
+
+byte*
+_GifDecoder::DecodeN(int& outLength)
+{
+ int i = 0;
+ int extCode = 0;
+ GifRecordType recordType;
+ unsigned char* pExt = null;
+ result r = E_SUCCESS;
+ std::unique_ptr<byte[]> pOutBuf;
+
+ SysTryReturn(NID_MEDIA, __pDec, null, E_INVALID_STATE, "Not Constructed");
+
+ recordType = UNDEFINED_RECORD_TYPE;
+ // Scan the content of the GIF file and load the image(s) in:
+ while (recordType != TERMINATE_RECORD_TYPE && pOutBuf == null)
+ {
+ r = DGifGetRecordType(__pDec, &recordType);
+ SysTryReturn(NID_MEDIA, r != GIF_ERROR, null, E_INVALID_DATA,
+ "[E_INVALID_DATA] DGifGetRecordType failed with code %x", GifLastError());
+
+ switch (recordType)
+ {
+ case IMAGE_DESC_RECORD_TYPE:
+ r = DecodeOneFrame(__pDstByte.get(), __dstLength);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] Propagated", GetErrorMessage(r));
+ pOutBuf.reset(new (std::nothrow) byte[__dstLength]);
+ SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Failed to allocate %d bytes", __dstLength);
+ memcpy(pOutBuf.get(), __pDstByte.get(), __dstLength);
+ __frameIndex++;
+ break;
+
+ case EXTENSION_RECORD_TYPE:
+ // Skip any extension blocks in file:
+ i = 0;
+ r = DGifGetExtension(__pDec, &extCode, &pExt);
+ SysTryReturn(NID_MEDIA, r != GIF_ERROR, null, E_INVALID_DATA,
+ "[E_INVALID_DATA] DGifGetExtension failed with code %x", GifLastError());
+ //ext[i++] = extension ? *extension : 0;
+ if (extCode == GRAPHICS_EXT_FUNC_CODE)
+ {
+ if (pExt[1] == 0x05)
+ {
+ __transparent = true;
+ }
+ else
+ {
+ __transparent = false;
+ }
+ __duration = ((((unsigned short) pExt[3]) << 8) + ((unsigned short) pExt[2])) * 10;
+ __transColor = (unsigned int) pExt[4];
+ }
+ while (pExt != NULL)
+ {
+ r = DGifGetExtensionNext(__pDec, &pExt);
+ SysTryReturn(NID_MEDIA, r != GIF_ERROR, null, E_INVALID_DATA,
+ "[E_INVALID_DATA] DGifGetExtensionNext failed with code %x", GifLastError());
+ i++;
+ }
+ break;
+
+ case TERMINATE_RECORD_TYPE:
+ break;
+
+ default: // Should be traps by DGifGetRecordType.
+ break;
+ }
+ }
+
+ outLength = __dstLength;
+ SetLastResult(r);
+ return pOutBuf.release();
+}
+
+result
+_GifDecoder::SetDecodingRegion(int x, int y, int width, int height)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+result
+_GifDecoder::GetDimension(int& width, int& height)
+{
+ SysTryReturnResult(NID_MEDIA, __pDec, E_INVALID_STATE, "Not Constructed");
+ width = __srcWidth;
+ height = __srcHeight;
+
+ SetLastResult(E_SUCCESS);
+ return E_SUCCESS;
+}
+
+MediaPixelFormat
+_GifDecoder::GetPixelFormat(void)
+{
+ return __pixelFormat; // MEDIA_PIXEL_FORMAT_RGB565LE;
+}
+
+result
+_GifDecoder::SetScaleDown(int scaleDown)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+result
+_GifDecoder::GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ result r = E_SUCCESS;
+ if (key.Equals(L"duration", false))
+ {
+ Long *pLong = null;
+ pLong = dynamic_cast<Long*>(&value);
+
+ SysTryCatch(NID_MEDIA, pLong, r = E_INVALID_ARG, E_INVALID_ARG,
+ "value is not a Long");
+ pLong->value = __duration;
+ }
+ else
+ {
+ r = E_OBJ_NOT_FOUND;
+ }
+
+CATCH:
+ return r;
+}
+
+}} // Tizen::Media
--- /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_ImageDecoder.cpp
+ * @brief This is the implementation file for the _ImageDecoder.
+ */
+
+#include <unique_ptr.h>
+#include <FBaseColArrayListT.h>
+#include <FBaseSysLog.h>
+#include <FMediaImageTypes.h>
+#include <FBaseInteger.h>
+#include <FIoFile.h>
+#include <FMediaImageTypes.h>
+#include "FMedia_MediaUtil.h"
+#include "FMedia_Ffmpeg.h"
+#include "FMedia_ColorConverter.h"
+#include "FMedia_ImageDecoder.h"
+#include "FMedia_PngDecoder.h"
+#include "FMedia_JpegTurboDecoder.h"
+#include "FMedia_GifDecoder.h"
+#include "FMedia_BmpDecoder.h"
+#include "FMedia_TiffDecoder.h"
+#include "FMedia_WbmpDecoder.h"
+#include "FMedia_ImageUtil.h"
+
+using namespace Tizen::Base;
+using namespace Tizen::Io;
+
+namespace Tizen { namespace Media
+{
+
+#define IS_VALID_DEC_PIXEL(x) \
+ ((x == MEDIA_PIXEL_FORMAT_RGB565LE) || (x == MEDIA_PIXEL_FORMAT_BGRA8888) \
+ || (x == MEDIA_PIXEL_FORMAT_RGBA8888))
+
+Tizen::Base::ByteBuffer*
+_ImageDecoder::DecodeToBufferN(const Tizen::Base::String& filePath,
+ MediaPixelFormat pixelFormat, int &width, int &height)
+{
+ result r = E_SUCCESS;
+ std::unique_ptr<ByteBuffer> pBuf;
+ _ImageDecoder dec;
+
+ SysTryReturn(NID_MEDIA, filePath.GetLength() > 0 && filePath.GetLength() <= PATH_MAX, null, E_INVALID_ARG,
+ "[E_INVALID_ARG] Given filePath length is zero or exceeds system limitations Length = %d.",filePath.GetLength());
+ SysTryReturn(NID_MEDIA, File::IsFileExist(filePath), null, E_FILE_NOT_FOUND,
+ "[E_FILE_NOT_FOUND] filePath:%ls", filePath.GetPointer());
+
+ r = dec.Construct(filePath, pixelFormat);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] Decoder construct failed.", GetErrorMessage(r));
+
+ // Reset decoder output demension
+ pBuf.reset(dec.DecodeN());
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+
+ r = dec.GetDimension(width, height);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+
+ SetLastResult(E_SUCCESS);
+ return pBuf.release();
+}
+
+Tizen::Base::ByteBuffer*
+_ImageDecoder::DecodeRegionToBufferN(const Tizen::Base::String& filePath,
+ MediaPixelFormat pixelFormat, int x, int y, int width, int height)
+{
+ result r = E_SUCCESS;
+ _ImageDecoder dec;
+ int imgWidth = 0;
+ int imgHeight = 0;
+ std::unique_ptr<ByteBuffer> pBuf;
+
+ r = dec.Construct(filePath, pixelFormat);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] dec.Construct", GetErrorMessage(r));
+ r = dec.GetDimension(imgWidth, imgHeight);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] dec.GetDimension", GetErrorMessage(r));
+
+ SysTryReturn(NID_MEDIA, imgWidth >= (x + width) && imgHeight >= (y + height),
+ null, E_INVALID_ARG,
+ "[E_INVALID_ARG] Bottom left point of region (%d, %d) should lie within dimensions of image (%d x %d)",
+ x, y, width, height, imgWidth, imgHeight);
+
+ r = dec.SetDecodingRegion(x, y, width, height);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS || r == E_UNSUPPORTED_OPERATION, null, r,
+ "[%s] dec.SetDecodingRegion failed for region (%d, %d) (%d x %d)",
+ GetErrorMessage(r), x, y, width, height);
+
+ if (r == E_SUCCESS)
+ {
+ pBuf.reset(dec.DecodeN());
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+ }
+ else // E_UNSUPPORTED_OPERATION
+ {
+ // crop image
+ ByteBuffer *pTmpBuf = null;
+
+ pBuf.reset(dec.DecodeN());
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+ pTmpBuf = _ImageUtil::CropN(*pBuf.get(), pixelFormat, imgWidth, imgHeight, x, y, width, height);
+ SysTryReturn(NID_MEDIA, pTmpBuf != null, null, GetLastResult(),
+ "[%s] Crop failed for buffer(%x), pixelFormat(%d), image size(%dx%d), region(%d,%d), (%dx%d)",
+ GetErrorMessage(GetLastResult()), pBuf->GetPointer(), pixelFormat, imgWidth,
+ imgHeight, x, y, width, height);
+ pBuf.reset(pTmpBuf);
+ }
+
+ SetLastResult(E_SUCCESS);
+ return pBuf.release();
+}
+
+Tizen::Base::ByteBuffer*
+_ImageDecoder::DecodeRegionToBufferN(const Tizen::Base::ByteBuffer& srcBuf, MediaPixelFormat pixelFormat,
+ int x, int y, int width, int height)
+{
+ result r = E_SUCCESS;
+ _ImageDecoder dec;
+ int imgWidth = 0;
+ int imgHeight = 0;
+ std::unique_ptr<ByteBuffer> pBuf;
+
+ r = dec.Construct(srcBuf, pixelFormat);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] dec.Construct", GetErrorMessage(r));
+ r = dec.GetDimension(imgWidth, imgHeight);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] dec.GetDimension", GetErrorMessage(r));
+
+ SysTryReturn(NID_MEDIA, imgWidth >= (x + width) && imgHeight >= (y + height),
+ null, E_INVALID_ARG,
+ "[E_INVALID_ARG] Bottom left point of region (%d, %d) should lie within dimensions of image (%d x %d)",
+ x, y, width, height, imgWidth, imgHeight);
+
+ r = dec.SetDecodingRegion(x, y, width, height);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS || r == E_UNSUPPORTED_OPERATION, null, r,
+ "[%s] dec.SetDecodingRegion failed for region (%d, %d) (%d x %d)",
+ GetErrorMessage(r), x, y, width, height);
+
+ if (r == E_SUCCESS)
+ {
+ pBuf.reset(dec.DecodeN());
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+ }
+ else // E_UNSUPPORTED_OPERATION
+ {
+ // crop image
+ ByteBuffer *pTmpBuf = null;
+ pBuf.reset(dec.DecodeN());
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+ pTmpBuf = _ImageUtil::CropN(*pBuf.get(), pixelFormat, imgWidth, imgHeight, x, y, width, height);
+ SysTryReturn(NID_MEDIA, pTmpBuf != null, null, GetLastResult(),
+ "[%s] Crop failed for buffer(%x), pixelFormat(%d), image size(%dx%d), region(%d,%d), (%dx%d)",
+ GetErrorMessage(GetLastResult()), pBuf->GetPointer(), pixelFormat, imgWidth,
+ imgHeight, x, y, width, height);
+ pBuf.reset(pTmpBuf);
+ }
+
+ SetLastResult(E_SUCCESS);
+ return pBuf.release();
+}
+
+result
+_ImageDecoder::GetImageInfo(const Tizen::Base::String& filePath, ImageFormat &imgFormat,
+ int &width, int &height)
+{
+ result r = E_SUCCESS;
+ _ImageDecoder dec;
+
+ r = dec.Construct(filePath);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] dec.Construct", GetErrorMessage(r));
+ imgFormat = dec.GetImageFormat();
+ r = dec.GetDimension(width, height);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] dec.GetDimension", GetErrorMessage(r));
+
+CATCH:
+ return r;
+}
+
+_ImageDecoder::_ImageDecoder(void)
+{
+ __pDec = null;
+ __imgFormat = IMG_FORMAT_NONE;
+ __pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
+ __orgDim.width = 0;
+ __orgDim.height = 0;
+ __outDim.width = 0;
+ __outDim.height = 0;
+ __pSrcBuf = null;
+}
+
+_ImageDecoder::~_ImageDecoder(void)
+{
+}
+
+_IImageDecoder*
+_ImageDecoder::CreateDecoderN(ImageFormat srcFormat)
+{
+ result r = E_SUCCESS;
+ std::unique_ptr<_IImageDecoder> pDec;
+
+ switch (srcFormat)
+ {
+ case IMG_FORMAT_JPG:
+ pDec.reset( new (std::nothrow) _JpegTurboDecoder());
+ break;
+
+ case IMG_FORMAT_PNG:
+ pDec.reset( new (std::nothrow) _PngDecoder());
+ break;
+
+ case IMG_FORMAT_GIF:
+ pDec.reset( new (std::nothrow) _GifDecoder());
+ break;
+
+ case IMG_FORMAT_BMP:
+ pDec.reset( new (std::nothrow) _BmpDecoder());
+ break;
+
+ case IMG_FORMAT_TIFF:
+ pDec.reset( new (std::nothrow) _TiffDecoder());
+ break;
+
+ case IMG_FORMAT_WBMP:
+ pDec.reset( new (std::nothrow) _WbmpDecoder());
+ break;
+
+ default:
+ r = E_UNSUPPORTED_FORMAT;
+ break;
+ }
+
+ //__imageFormat = srcFormat;
+ if (pDec.get() == null && r == E_SUCCESS)
+ {
+ r = E_OUT_OF_MEMORY;
+ }
+ SetLastResult(r);
+ return pDec.release();
+}
+
+
+result
+_ImageDecoder::Construct(const Tizen::Base::String& srcPath,
+ MediaPixelFormat pixelFormat,
+ ImageFormat imgFormat)
+{
+ result r = E_SUCCESS;
+ std::unique_ptr<ByteBuffer> pBuf;
+
+ // File to Buffer
+ pBuf.reset(_MediaUtil::FileToBufferN(srcPath));
+ SysTryReturn(NID_MEDIA, pBuf.get() != null, GetLastResult(), GetLastResult(),
+ "[%s] Propagated.", GetErrorMessage(GetLastResult()));
+
+ r = Construct(*pBuf.get(), pixelFormat, imgFormat);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r));
+ return r;
+}
+
+result
+_ImageDecoder::Construct(const Tizen::Base::ByteBuffer& srcBuf,
+ MediaPixelFormat pixelFormat,
+ ImageFormat imgFormat)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturnResult(NID_MEDIA, __pDec.get() == null, E_INVALID_STATE, "Already constructed");
+ 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);
+
+ SysTryCatch(NID_MEDIA, &srcBuf != null && srcBuf.GetCapacity() > 0,
+ r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
+ "[E_OBJ_NOT_FOUND] buf:0x%x, %d", &srcBuf, &srcBuf ? srcBuf.GetCapacity() : 0);
+
+ __pixelFormat = pixelFormat;
+
+ __pSrcBuf.reset(new (std::nothrow) ByteBuffer());
+ SysTryCatch(NID_MEDIA, __pSrcBuf.get() != null, , r, "[%s] Propagated.", GetErrorMessage(r));
+ r = __pSrcBuf->Construct(srcBuf);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated.", GetErrorMessage(r));
+
+ __imgFormat = _ImageUtil::GetImageFormat(srcBuf);
+
+ SysTryCatch(NID_MEDIA,
+ (__imgFormat > IMG_FORMAT_NONE) && (__imgFormat <= IMG_FORMAT_WBMP),
+ r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT, "[%s] Propagated.",
+ GetErrorMessage(GetLastResult()));
+
+ // Create decoder
+ __pDec.reset(CreateDecoderN(__imgFormat));
+ SysTryCatch(NID_MEDIA, __pDec.get() != null, r = GetLastResult(), r,
+ "[%s] Could not create decoder for image format %d.",
+ GetErrorMessage(r), __imgFormat);
+
+ // Decoder construction
+ r = __pDec->Construct((byte*) __pSrcBuf->GetPointer(), __pSrcBuf->GetCapacity(), pixelFormat);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated.", GetErrorMessage(r));
+
+ // Get original dimension
+ r = __pDec->GetDimension(__orgDim.width, __orgDim.height);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated.", GetErrorMessage(r));
+ __outDim.width = __orgDim.width;
+ __outDim.height = __orgDim.height;
+
+CATCH:
+ return r;
+}
+
+byte*
+_ImageDecoder::DecodeN(int& outLength)
+{
+ result r = E_SUCCESS;
+ int rawLength = 0;
+ byte* outBuf = null;
+ std::unique_ptr<byte[]> pRawBuf;
+ 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.",
+ GetErrorMessage(GetLastResult()),pRawBuf.get(), rawLength);
+
+ // Get working dimension
+ if ((__outDim.width == 0) && (__outDim.height == 0))
+ {
+ __outDim.width = __orgDim.width;
+ __outDim.height = __orgDim.height;
+ }
+
+ // if no need to convert.
+ if ((__pDec->GetPixelFormat() == __pixelFormat)
+ && (__orgDim.width == __outDim.width)
+ && (__orgDim.height == __outDim.height))
+ {
+ outBuf = pRawBuf.release();
+ outLength = rawLength;
+ }
+ else
+ {
+ _ColorConverter cvt;
+
+ // Converter construction
+ r = cvt.Construct(__pDec->GetPixelFormat(), __orgDim.width, __orgDim.height,
+ __pixelFormat, __outDim.width, __outDim.height);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+
+ // Convert to output format
+ outBuf = cvt.ConvertN(pRawBuf.get(), rawLength, outLength);
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+ }
+ SetLastResult(E_SUCCESS);
+ return outBuf;
+}
+
+// TODO: Change return type to ByteBuffer*
+
+Tizen::Base::ByteBuffer*
+_ImageDecoder::DecodeN(void)
+{
+ result r = E_SUCCESS;
+ int outLength = 0;
+ std::unique_ptr<byte[]> pTmpBuf;
+ std::unique_ptr<ByteBuffer> pByteBuf(new (std::nothrow) ByteBuffer());
+
+ SysTryReturn(NID_MEDIA, __pDec.get() != null, null, E_INVALID_STATE, "Not yet constructed");
+
+ pTmpBuf.reset(DecodeN(outLength));
+ SysTryReturn(NID_MEDIA, pTmpBuf.get() != null, null, GetLastResult(), "[%s] Propagated.", GetErrorMessage(GetLastResult()));
+
+ r = pByteBuf->Construct(outLength);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] Propagated. Could not construct Bytebuffer of size %d",
+ GetErrorMessage(r), outLength);
+
+ r = pByteBuf->SetArray((byte*) pTmpBuf.get(), 0, outLength);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+ pByteBuf->Flip();
+
+ SetLastResult(E_SUCCESS);
+ return pByteBuf.release();
+}
+
+ImageFormat
+_ImageDecoder::GetImageFormat(void) const
+{
+ return __imgFormat;
+}
+
+result
+_ImageDecoder::SetDecodingRegion(int x, int y, int width, int height)
+{
+ SysTryReturnResult(NID_MEDIA, __pDec.get() != null, E_INVALID_STATE, "Not yet constructed");
+ result r = E_SUCCESS;
+
+ r = __pDec->SetDecodingRegion(x, y, width, height);
+ if (r == E_SUCCESS)
+ {
+ __outDim.width = width;
+ __outDim.height = height;
+ __orgDim.width = width;
+ __orgDim.height = height;
+ }
+ return r;
+}
+
+result
+_ImageDecoder::GetDimension(int &width, int &height) const
+{
+ SysTryReturnResult(NID_MEDIA, __pDec.get() != null, E_INVALID_STATE, "Not yet constructed");
+
+ width = __outDim.width;
+ height = __outDim.height;
+
+ return E_SUCCESS;
+}
+
+MediaPixelFormat
+_ImageDecoder::GetPixelFormat(void) const
+{
+ return __pixelFormat;
+}
+
+result
+_ImageDecoder::SetOutputDimension(int width, int height, bool keepAspectRatio)
+{
+ if (width == 0 || height == 0 || __orgDim.width == 0 ||
+ __orgDim.height == 0 || keepAspectRatio == false)
+ {
+ __outDim.width = width;
+ __outDim.height = height;
+ }
+ else // keep aspect ratio
+ {
+ double xRatio = Integer(width).ToDouble() / Integer(__orgDim.width).ToDouble();
+ double yRatio = Integer(height).ToDouble() / Integer(__orgDim.height).ToDouble();
+ if (xRatio >= 1.0 || yRatio >= 1.0)
+ {
+ __outDim.width = __orgDim.width;
+ __outDim.height = __orgDim.height;
+ }
+ else if (xRatio < yRatio)
+ {
+ __outDim.width = (int)(__orgDim.width * yRatio);
+ __outDim.height = height;
+ }
+ else
+ {
+ __outDim.width = width;
+ __outDim.height = (int)(__orgDim.height*xRatio);
+ }
+ }
+ return E_SUCCESS;
+}
+
+}} // Tizen::Media
--- /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_ImageEncoder.cpp
+ * @brief This file contains the implementation of _ImageEncoder class.
+ */
+
+#include <unique_ptr.h>
+#include <FBaseSysLog.h>
+#include <FGrpBitmapCommon.h>
+#include <FMediaImageTypes.h>
+#include "FMedia_Ffmpeg.h"
+#include "FMedia_ImageEncoder.h"
+#include "FMedia_ColorConverter.h"
+#include "FMedia_JpegTurboEncoder.h"
+#include "FMedia_PngEncoder.h"
+#include "FMedia_BmpEncoder.h"
+
+using namespace Tizen::Base;
+using namespace Tizen::Base::Collection;
+
+namespace Tizen { namespace Media
+{
+
+Tizen::Base::ByteBuffer*
+_ImageEncoder::EncodeToBufferN(const Tizen::Base::ByteBuffer &srcBuf,
+ int width, int height, MediaPixelFormat pixelFormat,
+ ImageFormat imgFormat, int quality)
+{
+#if 0
+ result r = E_SUCCESS;
+ byte* pDstBuf = null;
+ int dstLength = 0;
+ ByteBuffer *pBuf = null;
+
+ r = EncodeN(imgFormat, srcBuf.GetPointer(), srcBuf.GetCapacity(),
+ width, height, pixelFormat, pDstBuf, dstLength, quality);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
+ "[%s] EncodeToBufferN:%d %x %d %dx%d %d %d",
+ GetErrorMessage(r), imgFormat, srcBuf.GetPointer(), srcBuf.GetCapacity(),
+ width, height, pixelFormat, quality);
+ pBuf = new (std::nothrow) ByteBuffer();
+ SysTryCatch(NID_MEDIA, pBuf != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
+
+ r = pBuf->Construct(dstLength);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] buf.Construct:%d", GetErrorMessage(r), dstLength);
+ r = pBuf->SetArray(pDstBuf, 0, dstLength);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] buf.SetArray:%d", GetErrorMessage(r), dstLength);
+
+ if (pDstBuf)
+ {
+ delete[] pDstBuf;
+ }
+ return pBuf;
+
+CATCH:
+ if (pDstBuf)
+ {
+ delete pDstBuf;
+ }
+ if (pBuf)
+ {
+ delete pBuf;
+ }
+ return null;
+#else
+ _ImageEncoder enc;
+ result r = E_SUCCESS;
+ ByteBuffer* pBuf = null;
+
+ r = enc.Construct(imgFormat, width, height, pixelFormat, quality);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
+ "[%s] enc.Construct failed for image format (%d), size (%dx%d), pixelformat (%d), quality (%d)",
+ GetErrorMessage(r), imgFormat, width, height, pixelFormat, quality);
+
+ pBuf = enc.EncodeN(srcBuf.GetPointer(), srcBuf.GetCapacity());
+ SysTryCatch(NID_MEDIA, pBuf != null, r = GetLastResult(), GetLastResult(),
+ "[%s] Propagated.", GetErrorMessage(GetLastResult()));
+
+ return pBuf;
+
+CATCH:
+ return null;
+#endif
+}
+
+
+Tizen::Base::ByteBuffer*
+_ImageEncoder::EncodeN(ImageFormat imgFormat, const byte* srcBuf, int srcLength,
+ int width, int height,
+ MediaPixelFormat pixelFormat, int quality)
+{
+ _ImageEncoder enc;
+ result r = E_SUCCESS;
+ std::unique_ptr<ByteBuffer> pBuf;
+
+ r = enc.Construct(imgFormat, width, height, pixelFormat, quality);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] enc.Construct failed for image format (%d), size (%dx%d), pixelformat (%d), quality (%d)",
+ GetErrorMessage(r), imgFormat, width, height, pixelFormat, quality);
+
+ pBuf.reset(enc.EncodeN(srcBuf, srcLength));
+ SysTryReturn(NID_MEDIA, pBuf.get() != null, null, GetLastResult(),
+ "[%s] Propagated.", GetErrorMessage(GetLastResult()));
+
+ return pBuf.release();
+}
+
+
+_ImageEncoder::_ImageEncoder(void)
+{
+ __pEnc = null;
+ __format = IMG_FORMAT_NONE;
+ __reqPixelFormat = MEDIA_PIXEL_FORMAT_NONE;
+ __pCvt = null;
+}
+
+_ImageEncoder::~_ImageEncoder(void)
+{
+}
+
+_IImageEncoder*
+_ImageEncoder::CreateEncoderN(ImageFormat srcFormat)
+{
+ _IImageEncoder *pEnc = null;
+ result r = E_SUCCESS;
+
+ switch (srcFormat)
+ {
+ case IMG_FORMAT_JPG:
+ pEnc = new (std::nothrow) _JpegTurboEncoder();
+ break;
+
+ case IMG_FORMAT_PNG:
+ pEnc = new (std::nothrow) _PngEncoder();
+ break;
+
+ case IMG_FORMAT_BMP:
+ pEnc = new (std::nothrow) _BmpEncoder();
+ break;
+
+ default:
+ r = E_UNSUPPORTED_FORMAT;
+ break;
+ }
+
+ if (pEnc == null && r == E_SUCCESS)
+ {
+ r = GetLastResult();
+ }
+
+ SetLastResult(r);
+ return pEnc;
+}
+
+result
+_ImageEncoder::Construct(ImageFormat format, int width, int height,
+ MediaPixelFormat pixelFormat, int quality)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturnResult(NID_MEDIA, __pEnc == null, E_INVALID_STATE, "Already constructed");
+
+ __pEnc.reset(CreateEncoderN(format));
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, __pEnc != null, r, r, "[%s] Propagated. ", GetErrorMessage(r));
+ r = __pEnc->Construct(width, height, pixelFormat, __reqPixelFormat, quality);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
+ "[%s] Propagated. Encoder Construct failed for size (%dx%d), pixelformat (%d), req pixelformat (%d)",
+ GetErrorMessage(r), width, height, pixelFormat, __reqPixelFormat);
+
+ __format = format;
+
+ if (pixelFormat != __reqPixelFormat)
+ {
+ __pCvt.reset(new _ColorConverter());
+ SysTryReturn(NID_MEDIA, __pCvt.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not create new _ColorConverter.");
+ r = __pCvt->Construct(pixelFormat, width, height,
+ __reqPixelFormat, width, height);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
+ "[%s] Propagated. ColorConverter construct failed for srcPixel (%d), dstPixel (%d), size (%dx%d)",
+ GetErrorMessage(r), pixelFormat, __reqPixelFormat, width, height);
+ }
+ return r;
+}
+
+Tizen::Base::ByteBuffer*
+_ImageEncoder::EncodeN(const byte* srcBuf, int srcLength)
+{
+ result r = E_SUCCESS;
+ int cvtLength = 0;
+ std::unique_ptr<ByteBuffer> pBuf;
+ SysTryReturn(NID_MEDIA, __pEnc, null, E_INVALID_STATE, "[E_INVALID_STATE] Propagated.");
+
+ // TODO: add supported pixel format check routine
+ if (__pCvt.get())
+ {
+ std::unique_ptr<byte[]> pCvtBuf;
+ pCvtBuf.reset(__pCvt->ConvertN(srcBuf, srcLength, cvtLength));
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated.", GetErrorMessage(r));
+ SysTryReturn(NID_MEDIA, pCvtBuf.get() != null, null, E_SYSTEM,
+ "[E_SYSTEM] pCvtBuf is null");
+
+ pBuf.reset(__pEnc->EncodeN(pCvtBuf.get(), cvtLength));
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, pBuf.get() != null, null, r, "[%s] Propagated. ", GetErrorMessage(r));
+ }
+ else
+ {
+ pBuf.reset(__pEnc->EncodeN(srcBuf, srcLength));
+ r = GetLastResult();
+ SysTryReturn(NID_MEDIA, pBuf.get() != null, null, r, "[%s] Propagated. ", GetErrorMessage(r));
+ }
+
+ return pBuf.release();
+}
+
+}} // Tizen::Media
--- /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_ImageUtil.cpp
+ * @brief This is the implementation file for the _ImageUtil.
+ */
+
+#include <unique_ptr.h>
+#include <FBaseSysLog.h>
+#include <image_util.h>
+#include <mmf/mm_error.h>
+#include <mmf/mm_util_imgp.h>
+#include "FMedia_ImageUtil.h"
+#include "FMedia_Ffmpeg.h"
+#include <arpa/inet.h>
+#include "FMedia_MediaUtil.h"
+#include "FMedia_SlpUtil.h"
+
+using namespace Tizen::Base;
+using namespace Tizen::Io;
+
+#define USE_MM_UTIL
+#define USE_FFMPEG
+namespace Tizen { namespace Media
+{
+
+#define IS_VALID_PIXEL(x) \
+ ((x == MEDIA_PIXEL_FORMAT_YUV420P) || (x == MEDIA_PIXEL_FORMAT_NV12) \
+ || (x == MEDIA_PIXEL_FORMAT_YUYV422) || (x == MEDIA_PIXEL_FORMAT_RGB565LE) \
+ || (x == MEDIA_PIXEL_FORMAT_BGRA8888) || (x == MEDIA_PIXEL_FORMAT_RGBA8888) \
+ || (x == MEDIA_PIXEL_FORMAT_BGR888) || (x == MEDIA_PIXEL_FORMAT_RGB888) \
+ || (x == MEDIA_PIXEL_FORMAT_NV21) || ( x == MEDIA_PIXEL_FORMAT_YUV444P))
+
+#define IS_VALID_BUF(buf, format, w, h) \
+ (_ImageUtil::GetBufferSize(format, w, h) <= buf.GetCapacity())
+
+typedef struct
+{
+ MediaPixelFormat mediaPixelFmt;
+ PixelFormat pixelFmt;
+ float bpp;
+} _PixelFormatMap;
+
+static const _PixelFormatMap _PIXEL_FORMAT_MAP[] =
+{
+ { MEDIA_PIXEL_FORMAT_RGB565LE, PIX_FMT_RGB565LE, 2 },
+ { MEDIA_PIXEL_FORMAT_BGRA8888, PIX_FMT_BGRA, 4 },
+ { MEDIA_PIXEL_FORMAT_RGBA8888, PIX_FMT_RGBA, 4 },
+ { MEDIA_PIXEL_FORMAT_RGB565BE, PIX_FMT_RGB565BE, 2 },
+ { MEDIA_PIXEL_FORMAT_RGB888, PIX_FMT_RGB24, 3 },
+ { MEDIA_PIXEL_FORMAT_BGR888, PIX_FMT_BGR24, 3 },
+ { MEDIA_PIXEL_FORMAT_YUV420P, PIX_FMT_YUV420P, 1.5 },
+ { MEDIA_PIXEL_FORMAT_YUV444P, PIX_FMT_YUV444P, 3 },
+ { MEDIA_PIXEL_FORMAT_YUYV422, PIX_FMT_YUYV422, 2 },
+ { MEDIA_PIXEL_FORMAT_UYVY422, PIX_FMT_UYVY422, 2 },
+ { MEDIA_PIXEL_FORMAT_NV12, PIX_FMT_NV12, 1.5 },
+ { MEDIA_PIXEL_FORMAT_NV12_TILE, PIX_FMT_NV12, 1.5 },
+ { MEDIA_PIXEL_FORMAT_NV21, PIX_FMT_NV21, 1.5 }
+};
+
+static const int _BPP_RGB565 = 2;
+static const int _BPP_RGB888 = 3;
+static const int _BPP_ARGB8888 = 4;
+static const int _BPP_YUV444 = 3;
+static const float _BPP_YUV420 = 1.5;
+static const float _BPP_NV12 = 1.5;
+
+/*
+* Input is assumed to be 8888
+* pDataIn => Input ARGB/BGRA/RGBA 8888 Buffer
+* pDataOut => Output buffer, allocated by caller
+* inWidth => Input Width
+* inHeight => Input Height
+* outWidth => Output Width
+* outHeight => Output Height
+*/
+result
+_ImageUtil::Resize8888(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
+{
+ int scaleX = 0;
+ int scaleY = 0;
+ int i = 0;
+ int j = 0;
+
+ int iRow = 0;
+ int iIndex = 0;
+
+ byte* pOutput = pDataOut;
+ byte* pOut = pDataOut;
+ const byte* pIn = null;
+
+ std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
+ SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate memory.");
+
+ /* Calculate X Scale factor */
+ scaleX = inWidth * 256 / outWidth;
+
+ /* Calculate Y Scale factor, aspect ratio is not maintained */
+ scaleY = inHeight * 256 / outHeight;
+
+ for (j = 0; j < outWidth; j++)
+ {
+ /* Get input index based on column scale factor */
+
+ /* To get more optimization, this is calculated once and
+ * is placed in a LUT and used for indexing
+ */
+ pColLUT [j] = ((j * scaleX) >> 8) * _BPP_ARGB8888;
+ }
+
+ pOut = pOutput;
+
+ for (i = 0; i < outHeight; i++)
+ {
+ /* Get input routWidth index based on routWidth scale factor */
+ iRow = (i * scaleY >> 8) * inWidth * _BPP_ARGB8888;
+
+ /* Loop could be unrolled for more optimization */
+ for (j = 0; j < (outWidth); j++)
+ {
+ /* Get input index based on column scale factor */
+ iIndex = iRow + pColLUT [j];
+
+ pIn = pDataIn + iIndex;
+ *pOut++ = *pIn++;
+ *pOut++ = *pIn++;
+ *pOut++ = *pIn++;
+ *pOut++ = *pIn++;
+ }
+ }
+
+ return E_SUCCESS;
+}
+
+/*
+* Input is assumed to be RGB888
+* pDataIn => Input RGB888 Buffer
+* pDataOut => Output buffer, allocated by caller
+* inWidth => Input Width
+* inHeight => Input Height
+* outWidth => Output Width
+* outHeight => Output Height
+*/
+result
+_ImageUtil::ResizeRGB888(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
+{
+ int scaleX = 0;
+ int scaleY = 0;
+ int i = 0;
+ int j = 0;
+
+ int iRow = 0;
+ int iIndex = 0;
+
+ byte* pOutput = pDataOut;
+ byte* pOut = pDataOut;
+ const byte* pIn = null;
+
+ std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
+ SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate memory.");
+
+ /* Calculate X Scale factor */
+ scaleX = inWidth * 256 / outWidth;
+
+ /* Calculate Y Scale factor, aspect ratio is not maintained */
+ scaleY = inHeight * 256 / outHeight;
+
+ for (j = 0; j < outWidth; j++)
+ {
+ /* Get input index based on column scale factor */
+
+ /* To get more optimization, this is calculated once and
+ * is placed in a LUT and used for indexing
+ */
+ pColLUT[j] = ((j * scaleX) >> 8) * _BPP_RGB888;
+ }
+
+ pOut = pOutput;
+
+ for (i = 0; i < outHeight; i++)
+ {
+ /* Get input routWidth index based on routWidth scale factor */
+ iRow = (i * scaleY >> 8) * inWidth * _BPP_RGB888;
+
+ /* Loop could be unrolled for more optimization */
+ for (j = 0; j < (outWidth); j++)
+ {
+ /* Get input index based on column scale factor */
+ iIndex = iRow + pColLUT [j];
+ pIn = pDataIn + iIndex;
+
+ *pOut++ = *pIn++;
+ *pOut++ = *pIn++;
+ *pOut++ = *pIn++;
+ }
+ }
+
+ return E_SUCCESS;
+}
+
+/*
+* Input is assumed to be RGB565
+* pDataIn => Input RGB565 Buffer
+* pDataOut => Output RGB565 Buffer (memory is assumed to be already allocated)
+* inWidth => Input Width
+* inHeight => Input Height
+* outWidth => Output Width
+* outHeight => Output Height
+*/
+result
+_ImageUtil::ResizeRGB565(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
+{
+ int scaleX = 0;
+ int scaleY = 0;
+ int i = 0;
+ int j = 0;
+
+ int iRow = 0;
+ int iIndex = 0;
+
+ byte* pOutput = pDataOut;
+ byte* pOut = pDataOut;
+ const byte* pIn = null;
+
+ std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
+ SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate memory.");
+
+ /* Calculate X Scale factor */
+ scaleX = inWidth * 256 / outWidth;
+
+ /* Calculate Y Scale factor, aspect ratio is not maintained */
+ scaleY = inHeight * 256 / outHeight;
+
+ for (j = 0; j < outWidth; j++)
+ {
+ /* Get input index based on column scale factor */
+
+ /* To get more optimization, this is calculated once and
+ * is placed in a LUT and used for indexing
+ */
+ pColLUT [j] = ((j * scaleX) >> 8) * _BPP_RGB565;
+ }
+
+ pOut = pOutput;
+
+ for (i = 0; i < outHeight; i++)
+ {
+ /* Get input row index based on row scale factor */
+ iRow = (i * scaleY >> 8) * inWidth * _BPP_RGB565;
+
+ /* Loop could be unrolled for more optimization */
+ for (j = 0; j < (outWidth); j++)
+ {
+ /* Get input index based on column scale factor */
+ iIndex = iRow + pColLUT [j];
+
+ pIn = pDataIn + iIndex;
+ *pOut++ = *pIn++;
+ *pOut++ = *pIn++;
+ }
+ }
+
+ return E_SUCCESS;
+}
+
+/*
+* Input is assumed to be YUV444
+* pDataIn => Input YUV444 Buffer
+* pDataOut => Output buffer, allocated by caller
+* inWidth => Input Width
+* inHeight => Input Height
+* outWidth => Output Width
+* outHeight => Output Height
+*/
+result
+_ImageUtil::ResizeYUV444(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
+{
+ int scaleX = 0;
+ int scaleY = 0;
+ int i = 0;
+ int j = 0;
+
+ int iRow = 0;
+ int iIndex = 0;
+
+ int ipixelcount = inWidth * inHeight;
+ int opixelcount = outWidth * outHeight;
+ byte* pOutput = pDataOut;
+ byte* pOutY = null;
+ byte* pOutU = null;
+ byte* pOutV = null;
+ const byte* pInY = null;
+ const byte* pInU = null;
+ const byte* pInV = null;
+
+ std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
+ SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate memory.");
+
+ /* Calculate X Scale factor */
+ scaleX = inWidth * 256 / outWidth;
+
+ /* Calculate Y Scale factor, aspect ratio is not maintained */
+ scaleY = inHeight * 256 / outHeight;
+
+ for (j = 0; j < outWidth; j++)
+ {
+ /* Get input index based on column scale factor */
+
+ /* To get more optimization, this is calculated once and
+ * is placed in a LUT and used for indexing
+ */
+ pColLUT[j] = ((j * scaleX) >> 8);
+ }
+
+ pOutY = pOutput;
+ pOutU = pOutY + opixelcount;
+ pOutV = pOutU + opixelcount;
+
+ pInY = pDataIn;
+ pInU = pInY + ipixelcount;
+ pInV = pInU + ipixelcount;
+
+ for (i = 0; i < outHeight; i++)
+ {
+ /* Get input row index based on row scale factor */
+ iRow = (i * scaleY >> 8) * inWidth;
+
+ /* Loop could be unrolled for more optimization */
+ for (j = 0; j < outWidth; j++)
+ {
+ /* Get input index based on column scale factor */
+ iIndex = iRow + pColLUT [j];
+
+ *(pOutY++) = *(pInY + iIndex);
+ *(pOutU++) = *(pInU + iIndex);
+ *(pOutV++) = *(pInV + iIndex);
+ }
+ }
+
+ return E_SUCCESS;
+}
+
+/*
+* Input is assumed to be YUYV422
+* pDataIn => Input YUYV422 Buffer
+* pDataOut => Output buffer, allocated by caller
+* inWidth => Input Width
+* inHeight => Input Height
+* outWidth => Output Width
+* outHeight => Output Height
+*/
+result
+_ImageUtil::ResizeYUYV422(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
+{
+
+ return ResizeRGB565(pDataIn, pDataOut, inWidth, inHeight, outWidth, outHeight);
+}
+
+/*
+* Input is assumed to be YUV420P
+* pDataIn => Input YUV420P Buffer
+* pDataOut => Output buffer, allocated by caller
+* inWidth => Input Width
+* inHeight => Input Height
+* outWidth => Output Width
+* outHeight => Output Height
+*/
+result
+_ImageUtil::ResizeYUV420P(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
+{
+ int scaleX = 0;
+ int scaleY = 0;
+ int i = 0;
+ int j = 0;
+
+ int iRow = 0;
+ int iIndex = 0;
+
+ int ipixelcount = inWidth * inHeight;
+ int opixelcount = outWidth * outHeight;
+ byte* pOutput = pDataOut;
+ byte* pOutY = null;
+ byte* pOutU = null;
+ byte* pOutV = null;
+
+ std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
+ SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate memory.");
+
+ /* Calculate X Scale factor */
+ scaleX = inWidth * 256 / outWidth;
+
+ /* Calculate Y Scale factor, aspect ratio is not maintained */
+ scaleY = inHeight * 256 / outHeight;
+
+ for (j = 0; j < outWidth; j++)
+ {
+ /* Get input index based on column scale factor */
+
+ /* To get more optimization, this is calculated once and
+ * is placed in a LUT and used for indexing
+ */
+ pColLUT[j] = ((j * scaleX) >> 8);
+ }
+
+ pOutY = pOutput;
+
+ for (i = 0; i < outHeight; i++)
+ {
+ /* Get input row index based on row scale factor */
+ iRow = (i * scaleY >> 8) * inWidth;
+
+ /* Loop could be unrolled for more optimization */
+ for (j = 0; j < (outWidth); j++)
+ {
+ /* Get input index based on column scale factor */
+ iIndex = iRow + pColLUT[j];
+
+ *pOutY++ = pDataIn[iIndex];
+ }
+ }
+
+ pOutU = pOutput + opixelcount;
+ pOutV = pOutU + (opixelcount/4);
+
+ for (i = 0; i < (outHeight + 1) / 2; i++)
+ {
+ /* Get input row index based on row scale factor */
+ iRow = (i * scaleY >> 8) * inWidth/2;
+
+ /* Loop could be unrolled for more optimization */
+ for (j = 0; j < (outWidth)/2; j++)
+ {
+ /* Get input index based on column scale factor */
+ iIndex = iRow + pColLUT[j];
+
+ *pOutU++ = pDataIn[iIndex + ipixelcount];
+ *pOutV++ = pDataIn[iIndex + ipixelcount + (ipixelcount/4)];
+ }
+ }
+
+ return E_SUCCESS;
+}
+
+/*
+* Input is assumed to be NV12
+* pDataIn => Input NV12 Buffer
+* pDataOut => Output buffer, allocated by caller
+* inWidth => Input Width
+* inHeight => Input Height
+* outWidth => Output Width
+* outHeight => Output Height
+*/
+result
+_ImageUtil::ResizeNV12(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
+{
+ int scaleX = 0;
+ int scaleY = 0;
+ int i = 0;
+ int j = 0;
+
+ int iRow = 0;
+ int iIndex = 0;
+
+ int ipixelcount = inWidth * inHeight;
+ int opixelcount = outWidth * outHeight;
+ byte* pOutput = pDataOut;
+ byte* pOutY = null;
+ byte* pOutUV = null;
+
+ std::unique_ptr<int []> pColLUT (new (std::nothrow) int[sizeof(int) * outWidth]);
+ SysTryReturn(NID_MEDIA, pColLUT.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate memory.");
+
+ /* Calculate X Scale factor */
+ scaleX = inWidth * 256 / outWidth;
+
+ /* Calculate Y Scale factor, aspect ratio is not maintained */
+ scaleY = inHeight * 256 / outHeight;
+
+ for (j = 0; j < outWidth; j++)
+ {
+ /* Get input index based on column scale factor */
+
+ /* To get more optimization, this is calculated once and
+ * is placed in a LUT and used for indexing
+ */
+ pColLUT[j] = ((j * scaleX) >> 8);
+ }
+
+ pOutY = pOutput;
+
+ for (i = 0; i < outHeight; i++)
+ {
+ /* Get input row index based on row scale factor */
+ iRow = (i * scaleY >> 8) * inWidth;
+
+ /* Loop could be unrolled for more optimization */
+ for (j = 0; j < (outWidth); j++)
+ {
+ /* Get input index based on column scale factor */
+ iIndex = iRow + pColLUT[j];
+
+ *pOutY++ = pDataIn[iIndex];
+ }
+ }
+
+ pOutUV = pOutput + opixelcount;
+
+ for (i = 0; i < (outHeight + 1) / 2; i++)
+ {
+ /* Get input row index based on row scale factor */
+ iRow = (i * scaleY >> 8) * inWidth/2;
+
+ /* Loop could be unrolled for more optimization */
+ for (j = 0; j < (outWidth)/2; j++)
+ {
+ /* Get input index based on column scale factor */
+ iIndex = iRow + pColLUT[j];
+
+ *pOutUV++ = pDataIn[iIndex + ipixelcount];
+ *pOutUV++ = pDataIn[iIndex + ipixelcount + 1];
+ }
+ }
+
+ return E_SUCCESS;
+}
+
+result
+_ImageUtil::ResizeBuffer(const byte* pInBuf, MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight, byte* pOutBuf, int dstWidth, int dstHeight)
+{
+ result r = E_SUCCESS;
+
+ switch (pixelFormat)
+ {
+
+ case MEDIA_PIXEL_FORMAT_RGBA8888:
+ case MEDIA_PIXEL_FORMAT_BGRA8888:
+ {
+ r = Resize8888(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
+ }
+ break;
+
+ case MEDIA_PIXEL_FORMAT_RGB888:
+ {
+ r = ResizeRGB888(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
+ }
+ break;
+
+ case MEDIA_PIXEL_FORMAT_RGB565LE:
+ {
+ r = ResizeRGB565(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
+ }
+ break;
+
+ case MEDIA_PIXEL_FORMAT_YUV444P:
+ {
+ r = ResizeYUV444(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
+ }
+ break;
+
+ case MEDIA_PIXEL_FORMAT_YUYV422:
+ {
+ r = ResizeYUYV422(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
+ }
+ break;
+
+ case MEDIA_PIXEL_FORMAT_YUV420P:
+ {
+ r = ResizeYUV420P(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
+ }
+ break;
+
+ case MEDIA_PIXEL_FORMAT_NV12:
+ {
+ r = ResizeNV12(pInBuf, pOutBuf, srcWidth, srcHeight, dstWidth, dstHeight);
+ }
+ break;
+
+ default:
+ r = E_UNSUPPORTED_FORMAT;
+ }
+
+ return r;
+}
+
+result
+_ImageUtil::RotateBuffer(const byte* srcBuf, MediaPixelFormat pixelFormat,
+ int width, int height, byte* dstBuf, int& outWidth, int& outHeight,
+ ImageRotationType rotate)
+{
+ result r = E_SUCCESS;
+ int ret = 0;
+#ifdef USE_MM_UTIL
+ mm_util_img_format colorFormat = MM_UTIL_IMG_FMT_NUM;
+ mm_util_img_rotate_type rotation = MM_UTIL_ROTATE_NUM;
+#else
+ image_util_colorspace_e colorFormat = IMAGE_UTIL_COLORSPACE_RGB565;
+ image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
+#endif
+
+ SysTryCatch(NID_MEDIA, width > 0 && height > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid dimension: Should be greater than zero: (%d x %d)",
+ width, height);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, width, height),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", width, height);
+
+ if (rotate == IMAGE_ROTATION_0)
+ {
+ int length = GetBufferSize(pixelFormat, width, height);
+ memcpy(dstBuf, srcBuf, length);
+ return r;
+ }
+
+ // Set output dimensions;
+ if ((rotate == IMAGE_ROTATION_90) || (rotate == IMAGE_ROTATION_270))
+ {
+ outWidth = height;
+ outHeight = width;
+ }
+ else
+ {
+ outWidth = width;
+ outHeight = height;
+ }
+
+ if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
+ {
+ switch (rotate)
+ {
+ case IMAGE_ROTATION_90:
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ unsigned short* pSrcBuf = (unsigned short *)srcBuf;
+ unsigned short* pDstBuf = (unsigned short *)dstBuf;
+ unsigned short* pTmpOutCol = null;
+
+ // Copying from all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
+
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutCol = *pSrcBuf++;
+ pTmpOutCol += outWidth;
+ }
+ }
+ }
+ break;
+
+ case IMAGE_ROTATION_180:
+ {
+ int pixCount = 0;
+ unsigned short* pSrcBuf = (unsigned short *)srcBuf;
+ unsigned short* pDstBuf = (unsigned short *)dstBuf;
+
+ // pDstBuf points to the bottom right corner of the output image.
+ pDstBuf += (outWidth * outHeight) - 1;
+
+ for (pixCount = (width * height); pixCount > 0; pixCount--)
+ {
+ *pDstBuf = *pSrcBuf++;
+ pDstBuf--;
+ }
+ }
+ break;
+
+ case IMAGE_ROTATION_270:
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ unsigned short* pSrcBuf = (unsigned short *)srcBuf;
+ unsigned short* pDstBuf = (unsigned short *)dstBuf;
+ unsigned short* pTmpOutCol = null;
+
+ // Copying all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the bottom of the column being filled.
+ pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
+
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutCol = *pSrcBuf++;
+ pTmpOutCol -= outWidth;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (pixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888 || pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888)
+ {
+ switch (rotate)
+ {
+ case IMAGE_ROTATION_90:
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ unsigned int* pSrcBuf = (unsigned int *)srcBuf;
+ unsigned int* pDstBuf = (unsigned int *)dstBuf;
+ unsigned int* pTmpOutCol = null;
+
+ // Copying from all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
+
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutCol = *pSrcBuf++;
+ pTmpOutCol += outWidth;
+ }
+ }
+ }
+ break;
+
+ case IMAGE_ROTATION_180:
+ {
+ int pixCount = 0;
+ unsigned int* pSrcBuf = (unsigned int *)srcBuf;
+ unsigned int* pDstBuf = (unsigned int *)dstBuf;
+
+ // pDstBuf points to the bottom right corner of the output image.
+ pDstBuf += (outWidth * outHeight) - 1;
+
+ for (pixCount = (width * height); pixCount > 0; pixCount--)
+ {
+ *pDstBuf = *pSrcBuf++;
+ pDstBuf--;
+ }
+ }
+ break;
+
+ case IMAGE_ROTATION_270:
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ unsigned int* pSrcBuf = (unsigned int *)srcBuf;
+ unsigned int* pDstBuf = (unsigned int *)dstBuf;
+ unsigned int* pTmpOutCol = null;
+
+ // Copying all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the bottom of the column being filled.
+ pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
+
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutCol = *pSrcBuf++;
+ pTmpOutCol -= outWidth;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+#ifdef USE_MM_UTIL
+
+ colorFormat = _SlpUtil::ToMmUtilImgFormat(pixelFormat);
+ rotation = _SlpUtil::ToMmUtilRotateType(rotate);
+
+ ret = mm_util_rotate_image((unsigned char*)srcBuf, width, height, colorFormat,
+ (unsigned char*)dstBuf, (unsigned int *)&outWidth, (unsigned int *)&outHeight, rotation);
+
+ SysTryCatch(NID_MEDIA, ret == 0, r = E_SYSTEM, E_SYSTEM,
+ "mm_util_rotate_image: %0x", ret);
+
+#else
+
+ colorFormat = _SlpUtil::ToColorspace(pixelFormat);
+ rotation = _SlpUtil::ToRotation(rotate);
+
+ ret = image_util_transform(dstBuf, &outWidth, &outHeight, rotation,
+ srcBuf, width, height, colorFormat);
+
+ SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] util_transform failed: %0x", ret);
+#endif
+ }
+
+ return r;
+
+CATCH:
+ return r;
+}
+
+result
+_ImageUtil::FlipBuffer(const byte* srcBuf, MediaPixelFormat pixelFormat,
+ int width, int height,
+ byte* dstBuf, ImageFlipType flip)
+{
+ result r = E_SUCCESS;
+ int ret = 0;
+#ifdef USE_MM_UTIL
+ mm_util_img_format colorFormat = MM_UTIL_IMG_FMT_NUM;
+ mm_util_img_rotate_type rotation = MM_UTIL_ROTATE_NUM;
+
+ unsigned int outWidth = 0;
+ unsigned int outHeight = 0;
+#else
+ image_util_colorspace_e colorFormat = IMAGE_UTIL_COLORSPACE_RGB565;
+ image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
+ int outWidth = 0;
+ int outHeight = 0;
+#endif
+
+ SysTryCatch(NID_MEDIA, width > 0 && height > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid dimension: Should be greater than zero: (%d x %d)",
+ width, height);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, width, height),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", width, height);
+
+ if (flip == IMAGE_FLIP_NONE)
+ {
+ int length = GetBufferSize(pixelFormat, width, height);
+ memcpy(dstBuf, srcBuf, length);
+ return r;
+ }
+
+ // Set output dimensions;
+ outWidth = width;
+ outHeight = height;
+
+ if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
+ {
+ if (flip == IMAGE_FLIP_HORIZONTAL)
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ unsigned short* pSrcBuf = (unsigned short *)srcBuf;
+ unsigned short* pDstBuf = (unsigned short *)dstBuf;
+ // pTmpOutRow points to last column of first row of destination.
+ unsigned short* pTmpOutRow = pDstBuf + width - 1;
+
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutRow-- = *pSrcBuf++; // copy source row in reverse to destination.
+ }
+ pTmpOutRow += (2 * outWidth);
+ }
+ }
+ else
+ {
+ int rowCount = 0;
+ unsigned short* pSrcBuf = (unsigned short *)srcBuf;
+ unsigned short* pDstBuf = (unsigned short *)dstBuf;
+ // pTmpOutRow points to the start of last row in destination buffer.
+ unsigned short* pTmpOutRow = pDstBuf + (width * (height - 1));
+
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // copy one row worth of data.
+ memcpy(pTmpOutRow, pSrcBuf, sizeof(unsigned short) * width);
+ pTmpOutRow -= width; // go to one higher row.
+ pSrcBuf += width; // go to next row.
+ }
+ }
+ }
+ else
+ {
+#ifdef USE_MM_UTIL
+
+ colorFormat = _SlpUtil::ToMmUtilImgFormat(pixelFormat);
+ rotation = _SlpUtil::ToMmUtilRotateType(flip);
+
+ ret = mm_util_rotate_image((unsigned char*)srcBuf, width, height, colorFormat,
+ (unsigned char*)dstBuf, &outWidth, &outHeight, rotation);
+
+ SysTryCatch(NID_MEDIA, ret == 0, r = E_SYSTEM, E_SYSTEM,
+ "mm_util_rotate_image failed with error code: %0x", ret);
+#else
+ colorFormat = _SlpUtil::ToColorspace(pixelFormat);
+ rotation = _SlpUtil::ToRotation(flip);
+
+ ret = image_util_transform(dstBuf, &outWidth, &outHeight, rotation,
+ srcBuf, width, height, colorFormat);
+ SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
+ "util_transform failed with error code: %0x", ret);
+#endif
+ }
+
+CATCH:
+ return r;
+}
+
+result
+_ImageUtil::ConvertPixelFormat(const ByteBuffer& srcBuf,
+ MediaPixelFormat srcFormat, int srcWidth, int srcHeight,
+ ByteBuffer& dstBuf, MediaPixelFormat dstFormat)
+{
+ result r = E_SUCCESS;
+
+#ifndef USE_FFMPEG
+ int ret = 0;
+ image_util_colorspace_e srcColor = IMAGE_UTIL_COLORSPACE_RGB565;
+ image_util_colorspace_e dstColor = IMAGE_UTIL_COLORSPACE_RGB565;
+
+ SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid dimension: Should be greater than zero. (%d x %d)", srcWidth, srcHeight);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(srcFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "[E_UNSUPPORTED_FORMAT] Unsupported srcPixelFormat:%d", srcFormat);
+ SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(dstFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "[E_UNSUPPORTED_FORMAT] Unsupported dstPixelFormat:%d", dstFormat);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(srcFormat, srcWidth, srcHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, dstFormat, srcWidth, srcHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
+ dstBuf.GetLimit(), dstFormat, srcWidth, srcHeight);
+
+ srcColor = _SlpUtil::ToColorspace(srcFormat);
+ dstColor = _SlpUtil::ToColorspace(dstFormat);
+
+ ret = image_util_convert_colorspace((unsigned char*) dstBuf.GetPointer(), dstColor,
+ (byte*)srcBuf.GetPointer(), srcWidth, srcHeight, srcColor);
+ SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] convert_colorspace failed with error code %d", ret);
+ r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(dstFormat, srcWidth, srcHeight));
+ SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
+ "[%s] SetLimit to %d failed for buffer.", GetErrorMessage(r),
+ _ImageUtil::GetBufferSize(dstFormat, srcWidth, srcHeight));
+#else
+ AVFrame srcFrame;
+ AVFrame dstFrame;
+
+ int dstWidth = srcWidth;
+ int dstHeight = srcHeight;
+ int width = srcWidth;
+ int size = 0;
+ int srcLength = srcBuf.GetCapacity();
+ int dstLength = 0;
+ byte* pSrcBuf;
+ std::unique_ptr<byte []> pDstBuf;
+ struct SwsContext* pCvtCtxt = null;
+ // Get ffmpeg format type
+ PixelFormat ffSrcFormat = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(srcFormat);
+ PixelFormat ffDstFormat = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(dstFormat);
+
+ SysTryReturn(NID_MEDIA, srcWidth > 0 && srcHeight > 0, E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid dimension: Should be greater that zero (%d x %d)", srcWidth, srcHeight);
+
+ SysTryReturn(NID_MEDIA, ffSrcFormat != PIX_FMT_NONE, E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "[E_UNSUPPORTED_FORMAT] Unsupported srcPixelFormat: %d", srcFormat);
+ SysTryReturn(NID_MEDIA, ffDstFormat != PIX_FMT_NONE, E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "[E_UNSUPPORTED_FORMAT] Unsupported dstPixelFormat: %d", dstFormat);
+
+ SysTryReturn(NID_MEDIA, IsValidDimension(srcFormat, srcWidth, srcHeight),
+ E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
+
+ SysTryReturn(NID_MEDIA, IS_VALID_BUF(srcBuf, srcFormat, srcWidth, srcHeight),
+ E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
+ srcBuf.GetLimit(), srcFormat, srcWidth, srcHeight);
+
+ SysTryReturn(NID_MEDIA, IsValidDimension(dstFormat, srcWidth, srcHeight),
+ E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
+
+ SysTryReturn(NID_MEDIA, IS_VALID_BUF(dstBuf, dstFormat, srcWidth, srcHeight),
+ E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid dst buffer size (%d) for pixelformat (%d) and size (%d x %d)",
+ dstBuf.GetLimit(), dstFormat, srcWidth, srcHeight);
+
+ avcodec_register_all();
+
+ if (srcWidth < 8)
+ {
+ int row = 0;
+ std::unique_ptr<byte []> pSrcBufUPtr;
+ const byte* pSrcData = null;
+ byte* pDstData = null;
+
+ width = srcWidth;
+ srcWidth = 8;
+ dstWidth = 8;
+
+ size = GetBufferSize(srcFormat, srcWidth, srcHeight);
+
+ pSrcBufUPtr.reset(new (std::nothrow) byte[size]);
+ pSrcBuf = pSrcBufUPtr.get();
+ SysTryReturn(NID_MEDIA, pSrcBuf != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Couldn't allocate buffer");
+ memset(pSrcBuf, 0, size);
+
+ pSrcData = srcBuf.GetPointer();
+ SysTryReturn(NID_MEDIA, pSrcData != null, GetLastResult(), GetLastResult(),
+ "[%s] ByteBuffer::GetPointer() returned null", GetErrorMessage(GetLastResult()));
+
+ pDstData = pSrcBuf;
+
+ // Create a new buffer with input buffer, padded to increase width to be 8 pixels wide.
+ for (row = 0; row < srcHeight; row++)
+ {
+ memcpy(pDstData, pSrcData, srcWidth);
+ pDstData += 8;
+ pSrcData += srcWidth;
+ }
+ }
+ else
+ {
+ width = srcWidth;
+ pSrcBuf = (const_cast<byte *>(srcBuf.GetPointer()));
+ SysTryReturn(NID_MEDIA, pSrcBuf != null, GetLastResult(), GetLastResult(),
+ "[%s] srcBuf.GetPointer failed", GetErrorMessage(GetLastResult()));
+
+ }
+ dstWidth = width;
+
+ // Create scale context
+ pCvtCtxt = sws_getContext(srcWidth, srcHeight, ffSrcFormat,
+ dstWidth, dstHeight, ffDstFormat,
+ SWS_BICUBIC, NULL, NULL, NULL);
+
+ SysTryReturn(NID_MEDIA, pCvtCtxt != null, E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] sws_getContext failed for src size (%d x %d), pix (%d), and dst size (%d x %d), pix (%d)",
+ srcWidth, srcHeight, ffSrcFormat,
+ dstWidth, dstHeight, ffDstFormat);
+
+ // Calculate src/dest size
+ size = avpicture_get_size(ffSrcFormat, srcWidth, srcHeight);
+ SysTryReturn(NID_MEDIA, size <= srcLength, E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] underflow: Required buffer size (%d) < given buffer size (%d), for pix (%d), (%d x %d)",
+ size, srcLength, srcFormat, srcWidth, srcHeight);
+
+ size = avpicture_get_size(ffDstFormat, dstWidth, dstHeight);
+ SysTryReturn(NID_MEDIA, size >= 0, E_FAILURE, E_FAILURE,
+ "[E_FAILURE] Not able find size of dest frame for pix (%d), size (%d x %d)");
+
+ pDstBuf.reset(new (std::nothrow) byte[size]);
+ SysTryReturn(NID_MEDIA, pDstBuf.get() != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", size);
+ dstLength = size;
+
+ memset(&srcFrame, 0, sizeof(srcFrame));
+ memset(&dstFrame, 0, sizeof(dstFrame));
+
+ // Fill source frame
+ avpicture_fill((AVPicture*)&srcFrame, (byte*)pSrcBuf, ffSrcFormat, srcWidth, srcHeight);
+
+ // Fill dest frame
+ avpicture_fill((AVPicture*)&dstFrame, (byte*)pDstBuf.get(), ffDstFormat, dstWidth, dstHeight);
+
+ // Scaling
+ sws_scale(pCvtCtxt, srcFrame.data, srcFrame.linesize, 0, srcHeight,
+ dstFrame.data, dstFrame.linesize);
+
+ if (width == srcWidth)
+ {
+ r = dstBuf.SetArray(pDstBuf.get(), 0, dstLength);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r,
+ "[%s] Propagated.", GetErrorMessage(r));
+ dstBuf.Flip();
+ }
+ else
+ {
+ // The padding must be removed from output buffer.
+ int row = 0;
+ std::unique_ptr<byte []> pUnpadded;
+ byte *pSrcData = null;
+ byte *pDstData = null;
+
+ srcWidth = width;
+ size = GetBufferSize(srcFormat, srcWidth, srcHeight);
+
+ pUnpadded.reset(new (std::nothrow) byte[size]);
+ SysTryReturn(NID_MEDIA, pUnpadded.get() != null, E_OUT_OF_MEMORY,
+ E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Couldn't allocate buffer");
+ memset(pUnpadded.get(), 0, size);
+
+ pSrcData = pDstBuf.get();
+
+ pDstData = pUnpadded.get();
+
+ // Create a new buffer with input buffer, padded to increase width to be 8 pixels wide.
+ for (row = 0; row < srcHeight; row++)
+ {
+ memcpy(pDstData, pSrcData, srcWidth);
+ pDstData += srcWidth;
+ pSrcData += 8;
+ }
+
+ r = dstBuf.SetArray(pUnpadded.get(), 0, size);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, r,
+ r, "[%s] Propagated.", GetErrorMessage(r));
+ dstBuf.Flip();
+ }
+
+ if (pCvtCtxt != NULL)
+ {
+ sws_freeContext(pCvtCtxt);
+ }
+
+#endif
+
+#ifndef USE_FFMPEG
+CATCH:
+#endif
+ return r;
+}
+
+
+result
+_ImageUtil::Resize(const ByteBuffer& srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ ByteBuffer& dstBuf,
+ int dstWidth, int dstHeight)
+{
+ result r = E_SUCCESS;
+ unsigned int outWidth = dstWidth;
+ unsigned int outHeight = dstHeight;
+ byte* pDataOut = null;
+
+ SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid src dimension: Should be greater than zero: (%d x %d)", srcWidth, srcHeight);
+ SysTryCatch(NID_MEDIA, dstWidth > 0 && dstHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid dst dimension: Should be greater than zero: (%d x %d)", dstWidth, dstHeight);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "Unsupported pixelFormat: %d", pixelFormat);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, srcWidth, srcHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, srcWidth, srcHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
+ srcBuf.GetLimit(), pixelFormat, srcWidth, srcHeight);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, dstWidth, dstHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", dstWidth, dstHeight);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, dstWidth, dstHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
+ dstBuf.GetLimit(), pixelFormat, dstWidth, dstHeight);
+
+ pDataOut = const_cast<byte*>(dstBuf.GetPointer());
+
+ r = ResizeBuffer(const_cast<byte*>(srcBuf.GetPointer()), pixelFormat,
+ srcWidth, srcHeight, pDataOut, dstWidth, dstHeight);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Resize failed.", GetErrorMessage(r));
+
+ r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
+ SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
+ "[%s] dstBuf.SetLimit to %d failed.", GetErrorMessage(r),
+ _ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
+
+CATCH:
+ return r;
+}
+
+result
+_ImageUtil::Rotate(const ByteBuffer& srcBuf,
+ MediaPixelFormat pixelFormat,
+ int width, int height,
+ ByteBuffer& dstBuf,
+ ImageRotationType rotate)
+{
+ result r = E_SUCCESS;
+ int ret = 0;
+#ifdef USE_MM_UTIL
+ mm_util_img_format colorFormat = MM_UTIL_IMG_FMT_NUM;
+ mm_util_img_rotate_type rotation = MM_UTIL_ROTATE_NUM;
+
+ unsigned int outWidth = 0;
+ unsigned int outHeight = 0;
+#else
+ image_util_colorspace_e colorFormat = IMAGE_UTIL_COLORSPACE_RGB565;
+ image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
+ int outWidth = 0;
+ int outHeight = 0;
+#endif
+
+
+ SysTryCatch(NID_MEDIA, width > 0 && height > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid dimension: Should be greater than zero: (%d x %d)",
+ width, height);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, width, height),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", width, height);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, width, height),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
+ srcBuf.GetLimit(), pixelFormat, width, height);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, width, height),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
+ dstBuf.GetLimit(), pixelFormat, width, height);
+
+ if (rotate == IMAGE_ROTATION_0)
+ {
+ r = dstBuf.SetArray(srcBuf.GetPointer(), 0, srcBuf.GetLimit());
+ SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
+ "[%s] dstBuf.SetArray failed. SrcBuffer = %d, SrcBuffer.Limit = %d, dstBuffer.Position = %d, dstBuffer.Capacity = %d.",
+ GetErrorMessage(r), srcBuf.GetPointer(), srcBuf.GetLimit(), dstBuf.GetPosition(), dstBuf.GetCapacity());
+ dstBuf.Flip();
+ return r;
+ }
+
+ // Set output dimensions;
+ if ((rotate == IMAGE_ROTATION_90) || (rotate == IMAGE_ROTATION_270))
+ {
+ outWidth = height;
+ outHeight = width;
+ }
+ else
+ {
+ outWidth = width;
+ outHeight = height;
+ }
+
+ if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB888)
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ byte* pSrcBuf = (byte *)srcBuf.GetPointer();
+ byte* pDstBuf = (byte *)dstBuf.GetPointer();
+ byte* pTmpOutCol = null;
+
+ switch (rotate)
+ {
+ case IMAGE_ROTATION_90:
+ {
+ // Copying from all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutCol = pDstBuf + outWidth * 3 - 1 - rowCount * 3;
+
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ pTmpOutCol = pTmpOutCol - 2;
+ *pTmpOutCol++ = *pSrcBuf++; // copied R byte
+ *pTmpOutCol++ = *pSrcBuf++; // copied G byte
+ *pTmpOutCol = *pSrcBuf++; // copied B byte
+ pTmpOutCol += outWidth * 3;
+
+ pTmpOutCol = pTmpOutCol - 2;
+ *pTmpOutCol++ = *pSrcBuf++; // copied R byte
+ *pTmpOutCol++ = *pSrcBuf++; // copied G byte
+ *pTmpOutCol = *pSrcBuf++; // copied B byte
+ pTmpOutCol += outWidth * 3;
+ }
+ }
+ }
+ break;
+ case IMAGE_ROTATION_180:
+ {
+ // Copying all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the bottom of the column being filled.
+ pTmpOutCol = pDstBuf + ((outWidth * outHeight * 3) - 1) - (rowCount * outWidth * 3);
+
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ pTmpOutCol -= 2; // move to R bye of pixel
+ *pTmpOutCol++ = *pSrcBuf++; // copied R
+ *pTmpOutCol++ = *pSrcBuf++; // copied G
+ *pTmpOutCol = *pSrcBuf++; // copied B
+ pTmpOutCol -= 3; // move to next pixel to get copied
+
+ pTmpOutCol -= 2; // move to R bye of pixel
+ *pTmpOutCol++ = *pSrcBuf++; // copied R
+ *pTmpOutCol++ = *pSrcBuf++; // copied G
+ *pTmpOutCol = *pSrcBuf++; // copied B
+ pTmpOutCol -= 3; // move to next pixel to get copied
+ }
+ }
+ }
+ break;
+ case IMAGE_ROTATION_270:
+ {
+ // Copying all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the bottom of the column being filled.
+ pTmpOutCol = pDstBuf + (outWidth * 3 * (outHeight - 1)) + rowCount * 3;
+
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ *pTmpOutCol++ = *pSrcBuf++; // copied R
+ *pTmpOutCol++ = *pSrcBuf++; // copied G
+ *pTmpOutCol = *pSrcBuf++; // copied B
+ pTmpOutCol -= 2; // take pointer back to R
+ pTmpOutCol -= outWidth * 3;
+
+ *pTmpOutCol++ = *pSrcBuf++; // copied R
+ *pTmpOutCol++ = *pSrcBuf++; // copied G
+ *pTmpOutCol = *pSrcBuf++; // copied B
+ pTmpOutCol -= 2; // take pointer back to R
+ pTmpOutCol -= outWidth * 3;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ else if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
+ {
+ switch (rotate)
+ {
+ case IMAGE_ROTATION_90:
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ unsigned short* pSrcBuf = (unsigned short *)srcBuf.GetPointer();
+ unsigned short* pDstBuf = (unsigned short *)dstBuf.GetPointer();
+ unsigned short* pTmpOutCol = null;
+
+ // Copying from all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
+
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutCol = *pSrcBuf++;
+ pTmpOutCol += outWidth;
+ }
+ }
+ }
+ break;
+
+ case IMAGE_ROTATION_180:
+ {
+ int pixCount = 0;
+ unsigned short* pSrcBuf = (unsigned short *)srcBuf.GetPointer();
+ unsigned short* pDstBuf = (unsigned short *)dstBuf.GetPointer();
+
+ // pDstBuf points to the bottom right corner of the output image.
+ pDstBuf += (outWidth * outHeight) - 1;
+
+ for (pixCount = (width * height); pixCount > 0; pixCount--)
+ {
+ *pDstBuf = *pSrcBuf++;
+ pDstBuf--;
+ }
+ }
+ break;
+
+ case IMAGE_ROTATION_270:
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ unsigned short* pSrcBuf = (unsigned short *)srcBuf.GetPointer();
+ unsigned short* pDstBuf = (unsigned short *)dstBuf.GetPointer();
+ unsigned short* pTmpOutCol = null;
+
+ // Copying all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the bottom of the column being filled.
+ pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
+
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutCol = *pSrcBuf++;
+ pTmpOutCol -= outWidth;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (pixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888 || pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888)
+ {
+ switch (rotate)
+ {
+ case IMAGE_ROTATION_90:
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ unsigned int* pSrcBuf = (unsigned int *)srcBuf.GetPointer();
+ unsigned int* pDstBuf = (unsigned int *)dstBuf.GetPointer();
+ unsigned int* pTmpOutCol = null;
+
+ // Copying from all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
+
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutCol = *pSrcBuf++;
+ pTmpOutCol += outWidth;
+ }
+ }
+ }
+ break;
+
+ case IMAGE_ROTATION_180:
+ {
+ int pixCount = 0;
+ unsigned int* pSrcBuf = (unsigned int *)srcBuf.GetPointer();
+ unsigned int* pDstBuf = (unsigned int *)dstBuf.GetPointer();
+
+ // pDstBuf points to the bottom right corner of the output image.
+ pDstBuf += (outWidth * outHeight) - 1;
+
+ for (pixCount = (width * height); pixCount > 0; pixCount--)
+ {
+ *pDstBuf = *pSrcBuf++;
+ pDstBuf--;
+ }
+ }
+ break;
+
+ case IMAGE_ROTATION_270:
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ unsigned int* pSrcBuf = (unsigned int *)srcBuf.GetPointer();
+ unsigned int* pDstBuf = (unsigned int *)dstBuf.GetPointer();
+ unsigned int* pTmpOutCol = null;
+
+ // Copying all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the bottom of the column being filled.
+ pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
+
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutCol = *pSrcBuf++;
+ pTmpOutCol -= outWidth;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (pixelFormat == MEDIA_PIXEL_FORMAT_YUV420P)
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ byte* pDstY = (byte *)dstBuf.GetPointer();
+ byte* pDstU = pDstY + outWidth * outHeight;
+ byte* pDstV = pDstU + (outWidth / 2) * (outHeight / 2);
+
+ byte* pSrcY = (byte *) srcBuf.GetPointer();
+ byte* pSrcU = pSrcY + width * height;
+ byte* pSrcV = pSrcU + (width /2) * ( height / 2);
+ byte* pTmpOutColY = null;
+ byte* pTmpOutColU = null;
+ byte* pTmpOutColV = null;
+ switch (rotate)
+ {
+ case IMAGE_ROTATION_90:
+ {
+ // Copying from all source rows to destination columns of Y plane.
+ for (rowCount = 0; rowCount < height / 2; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutColU = pDstU + (outWidth / 2) - 1 - rowCount;
+ pTmpOutColV = pDstV + (outWidth / 2) - 1 - rowCount;
+ pTmpOutColY = pDstY + outWidth - 1 - rowCount;
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ *pTmpOutColU = *pSrcU++;
+ pTmpOutColU += outWidth / 2;
+ *pTmpOutColV = *pSrcV++;
+ pTmpOutColV += outWidth / 2;
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY += outWidth;
+ }
+ for (colCount = width / 2; colCount < width; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY += outWidth;
+ }
+ }
+ for (rowCount = height / 2; rowCount < height; rowCount++)
+ {
+ pTmpOutColY = pDstY + outWidth - 1 - rowCount;
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY += outWidth;
+ }
+ }
+ }
+ break;
+ case IMAGE_ROTATION_180:
+ {
+ // Copying from all source rows to destination columns of Y plane.
+ pTmpOutColY = pDstY + outWidth * outHeight - 1;
+ pTmpOutColU = pDstU + (outWidth / 2) * (outHeight / 2) - 1;
+ pTmpOutColV = pDstV + (outWidth / 2) * (outHeight / 2) - 1;
+ for (colCount = 0; colCount < (outWidth / 2 * outHeight / 2); colCount++)
+ {
+ *pTmpOutColY-- = *pSrcY++;
+ *pTmpOutColU-- = *pSrcU++;
+ *pTmpOutColV-- = *pSrcV++;
+ }
+ for (colCount = (outWidth / 2 * outHeight / 2); colCount < (outWidth * outHeight); colCount++)
+ {
+ *pTmpOutColY-- = *pSrcY++;
+ }
+ }
+ break;
+ case IMAGE_ROTATION_270:
+ {
+
+ // Copying from all source rows to destination columns of Y plane.
+ for (rowCount = 0; rowCount < height / 2; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
+ pTmpOutColU = pDstU + (outWidth / 2) * (outHeight / 2 - 1) + rowCount;
+ pTmpOutColV = pDstV + (outWidth / 2) * (outHeight / 2 - 1) + rowCount;
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY -= outWidth;
+ *pTmpOutColU = *pSrcU++;
+ pTmpOutColU -= outWidth / 2;
+ *pTmpOutColV = *pSrcV++;
+ pTmpOutColV -= outWidth / 2;
+ }
+ for (colCount = width / 2; colCount < width; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY -= outWidth;
+ }
+ }
+ for (rowCount = height / 2; rowCount < height; rowCount++)
+ {
+ pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
+ // pTmpOutCol points to the top of the output column being filled.
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY -= outWidth;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else if (pixelFormat == MEDIA_PIXEL_FORMAT_NV12
+ || pixelFormat == MEDIA_PIXEL_FORMAT_NV21)
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ byte* pDstY = (byte *)dstBuf.GetPointer();
+ short* pDstUV = (short* )(pDstY + outWidth * outHeight);
+
+ byte* pSrcY = (byte* ) srcBuf.GetPointer();
+ short* pSrcUV = (short* )(pSrcY + width * height);
+ byte* pTmpOutColY = null;
+ short* pTmpOutColUV = null;
+
+ switch (rotate)
+ {
+ case IMAGE_ROTATION_90:
+ {
+ // Copying from all source rows to destination columns of Y plane.
+ for (rowCount = 0; rowCount < height / 2; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutColUV = pDstUV + (outWidth / 2) - 1 - rowCount;
+ pTmpOutColY = pDstY + outWidth - 1 - rowCount;
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ *pTmpOutColUV = *pSrcUV++;
+ pTmpOutColUV += outWidth / 2 ;
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY += outWidth;
+ }
+ for (colCount = width / 2; colCount < width; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY += outWidth;
+ }
+ }
+ for (rowCount = height / 2; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutColY = pDstY + outWidth - 1 - rowCount;
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY += outWidth;
+ }
+ }
+ }
+ break;
+ case IMAGE_ROTATION_180:
+ {
+ // Copying from all source rows to destination columns of Y plane.
+ pTmpOutColY = pDstY + outWidth * outHeight - 1;
+ pTmpOutColUV = pDstUV + (outWidth / 2) * (outHeight / 2) - 1;
+ for (colCount = 0; colCount < (outWidth / 2 * outHeight / 2); colCount++)
+ {
+ *pTmpOutColY-- = *pSrcY++;
+ *pTmpOutColUV-- = *pSrcUV++;
+ }
+ for (colCount = (outWidth / 2 * outHeight / 2); colCount < outWidth * outHeight; colCount++)
+ {
+ *pTmpOutColY-- = *pSrcY++;
+ }
+ }
+ break;
+ case IMAGE_ROTATION_270:
+ {
+ // Copying from all source rows to destination columns of Y plane.
+ for (rowCount = 0; rowCount < height / 2; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
+ pTmpOutColUV = pDstUV + (outWidth / 2) * (outHeight / 2 - 1) + rowCount;
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY -= outWidth;
+ *pTmpOutColUV = *pSrcUV++;
+ pTmpOutColUV -= outWidth / 2;
+ }
+ for (colCount = width / 2; colCount < width; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY -= outWidth;
+ }
+ }
+ for (rowCount = height / 2; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY -= outWidth;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ else if (pixelFormat == MEDIA_PIXEL_FORMAT_YUV444P)
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ byte* pDstY = (byte *)dstBuf.GetPointer();
+ byte* pDstU = pDstY + outWidth * outHeight;
+ byte* pDstV = pDstU + outWidth * outHeight;
+
+ byte* pSrcY = (byte *) srcBuf.GetPointer();
+ byte* pSrcU = pSrcY + width * height;
+ byte* pSrcV = pSrcU + width * height;
+ byte* pTmpOutColY = null;
+ byte* pTmpOutColU = null;
+ byte* pTmpOutColV = null;
+
+ switch (rotate)
+ {
+ case IMAGE_ROTATION_90:
+ {
+ // Copying from all source rows to destination columns of Y plane.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutColU = pDstU + outWidth - 1 - rowCount;
+ pTmpOutColV = pDstV + outWidth - 1 - rowCount;
+ pTmpOutColY = pDstY + outWidth - 1 - rowCount;
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ *pTmpOutColU = *pSrcU++;
+ pTmpOutColU += outWidth;
+ *pTmpOutColV = *pSrcV++;
+ pTmpOutColV += outWidth;
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY += outWidth;
+
+ *pTmpOutColU = *pSrcU++;
+ pTmpOutColU += outWidth;
+ *pTmpOutColV = *pSrcV++;
+ pTmpOutColV += outWidth;
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY += outWidth;
+ }
+ }
+ }
+ break;
+ case IMAGE_ROTATION_180:
+ {
+ // Copying from all source rows to destination columns of Y plane.
+ pTmpOutColY = pDstY + outWidth * outHeight - 1;
+ pTmpOutColU = pDstU + outWidth * outHeight - 1;
+ pTmpOutColV = pDstV + outWidth * outHeight - 1;
+ for (colCount = (outWidth * outHeight); colCount > 0; colCount--)
+ {
+ *pTmpOutColY-- = *pSrcY++;
+ *pTmpOutColU-- = *pSrcU++;
+ *pTmpOutColV-- = *pSrcV++;
+ }
+ }
+ break;
+ case IMAGE_ROTATION_270:
+ {
+ // Copying from all source rows to destination columns of Y plane.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutColY = pDstY + (outWidth * (outHeight - 1)) + rowCount;
+ pTmpOutColU = pDstU + (outWidth * (outHeight - 1)) + rowCount;
+ pTmpOutColV = pDstV + (outWidth * (outHeight - 1)) + rowCount;
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY -= outWidth;
+ *pTmpOutColU = *pSrcU++;
+ pTmpOutColU -= outWidth;
+ *pTmpOutColV = *pSrcV++;
+ pTmpOutColV -= outWidth;
+
+ *pTmpOutColY = *pSrcY++;
+ pTmpOutColY -= outWidth;
+ *pTmpOutColU = *pSrcU++;
+ pTmpOutColU -= outWidth;
+ *pTmpOutColV = *pSrcV++;
+ pTmpOutColV -= outWidth;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else if (pixelFormat == MEDIA_PIXEL_FORMAT_YUYV422)
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ short* pSrcBuf = (short*)srcBuf.GetPointer();
+ short* pDstBuf = (short*)dstBuf.GetPointer();
+ short* pTmpOutCol = null;
+
+ switch (rotate)
+ {
+ case IMAGE_ROTATION_90:
+ {
+ // Copying from all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the top of the output column being filled.
+ pTmpOutCol = pDstBuf + outWidth - 1 - rowCount;
+ for (colCount = 0; colCount < width / 2 ; colCount++)
+ {
+ *pTmpOutCol = *pSrcBuf++; // copied Y0 U0
+ pTmpOutCol += outWidth;
+
+ *pTmpOutCol = *pSrcBuf++; // copied Y1 V0
+ pTmpOutCol += outWidth;
+ }
+ }
+ }
+ break;
+ case IMAGE_ROTATION_180:
+ {
+ // Copying all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the bottom of the column being filled.
+ pTmpOutCol = pDstBuf + ((outWidth * outHeight ) - 1) - (rowCount * outWidth);
+
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ *pTmpOutCol-- = *pSrcBuf++; // copied Y0 U0
+ *pTmpOutCol-- = *pSrcBuf++; // copied Y1 V0
+ }
+ }
+ }
+ break;
+ case IMAGE_ROTATION_270:
+ {
+ // Copying all source rows to destination columns.
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // pTmpOutCol points to the bottom of the column being filled.
+ pTmpOutCol = pDstBuf + (outWidth * (outHeight - 1)) + rowCount;
+ for (colCount = 0; colCount < width / 2; colCount++)
+ {
+ *pTmpOutCol = *pSrcBuf++; // copied B
+ pTmpOutCol -= outWidth;
+
+ *pTmpOutCol = *pSrcBuf++; // copied B
+ pTmpOutCol -= outWidth;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+#ifdef USE_MM_UTIL
+
+ colorFormat = _SlpUtil::ToMmUtilImgFormat(pixelFormat);
+ rotation = _SlpUtil::ToMmUtilRotateType(rotate);
+
+ ret = mm_util_rotate_image((unsigned char*)srcBuf.GetPointer(), width, height, colorFormat,
+ (unsigned char*)dstBuf.GetPointer(), &outWidth, &outHeight, rotation);
+
+ SysTryCatch(NID_MEDIA, ret == 0, r = E_SYSTEM, E_SYSTEM,
+ "mm_util_rotate_image: %0x", ret);
+
+#else
+
+ colorFormat = _SlpUtil::ToColorspace(pixelFormat);
+ rotation = _SlpUtil::ToRotation(rotate);
+
+ ret = image_util_transform((byte*)dstBuf.GetPointer(), &outWidth, &outHeight, rotation,
+ (byte*)srcBuf.GetPointer(), width, height, colorFormat);
+
+ SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] util_transform failed: %0x", ret);
+#endif
+ }
+
+
+ r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
+ SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
+ "[%s] dstBuf.SetLimit failed for (%d x %d) pixel format: %d",
+ GetErrorMessage(r), outWidth, outHeight, pixelFormat);
+
+ return r;
+
+CATCH:
+ return r;
+}
+
+result
+_ImageUtil::Flip(const ByteBuffer& srcBuf, MediaPixelFormat pixelFormat,
+ int width, int height,
+ ByteBuffer& dstBuf, ImageFlipType flip)
+{
+ result r = E_SUCCESS;
+ int ret = 0;
+#ifdef USE_MM_UTIL
+ mm_util_img_format colorFormat = MM_UTIL_IMG_FMT_NUM;
+ mm_util_img_rotate_type rotation = MM_UTIL_ROTATE_NUM;
+
+ unsigned int outWidth = 0;
+ unsigned int outHeight = 0;
+#else
+ image_util_colorspace_e colorFormat = IMAGE_UTIL_COLORSPACE_RGB565;
+ image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
+ int outWidth = 0;
+ int outHeight = 0;
+#endif
+
+ SysTryCatch(NID_MEDIA, width > 0 && height > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid dimension: Should be greater than zero: (%d x %d)",
+ width, height);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_PIXEL(pixelFormat), r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "[E_UNSUPPORTED_FORMAT] Unsupported pixelFormat: %d", pixelFormat);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, width, height),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", width, height);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, width, height),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
+ srcBuf.GetLimit(), pixelFormat, width, height);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, width, height),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
+ dstBuf.GetLimit(), pixelFormat, width, height);
+
+ if (flip == IMAGE_FLIP_NONE)
+ {
+ r = dstBuf.SetArray(srcBuf.GetPointer(), 0, srcBuf.GetLimit());
+ SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
+ "[%s] dstBuf.SetArray failed: source (%x %d), dst (%d %d)",
+ srcBuf.GetPointer(), srcBuf.GetLimit(),
+ dstBuf.GetPosition(), dstBuf.GetCapacity());
+ dstBuf.Flip();
+ return r;
+ }
+
+ // Set output dimensions;
+ outWidth = width;
+ outHeight = height;
+
+ if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
+ {
+ if (flip == IMAGE_FLIP_HORIZONTAL)
+ {
+ int rowCount = 0;
+ int colCount = 0;
+ unsigned short* pSrcBuf = (unsigned short *)srcBuf.GetPointer();
+ unsigned short* pDstBuf = (unsigned short *)dstBuf.GetPointer();
+ // pTmpOutRow points to last column of first row of destination.
+ unsigned short* pTmpOutRow = pDstBuf + width - 1;
+
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ for (colCount = 0; colCount < width; colCount++)
+ {
+ *pTmpOutRow-- = *pSrcBuf++; // copy source row in reverse to destination.
+ }
+ pTmpOutRow += (2 * outWidth);
+ }
+ }
+ else
+ {
+ int rowCount = 0;
+ unsigned short* pSrcBuf = (unsigned short *)srcBuf.GetPointer();
+ unsigned short* pDstBuf = (unsigned short *)dstBuf.GetPointer();
+ // pTmpOutRow points to the start of last row in destination buffer.
+ unsigned short* pTmpOutRow = pDstBuf + (width * (height - 1));
+
+ for (rowCount = 0; rowCount < height; rowCount++)
+ {
+ // copy one row worth of data.
+ memcpy(pTmpOutRow, pSrcBuf, sizeof(unsigned short) * width);
+ pTmpOutRow -= width; // go to one higher row.
+ pSrcBuf += width; // go to next row.
+ }
+ }
+ }
+ else
+ {
+#ifdef USE_MM_UTIL
+
+ colorFormat = _SlpUtil::ToMmUtilImgFormat(pixelFormat);
+ rotation = _SlpUtil::ToMmUtilRotateType(flip);
+
+ ret = mm_util_rotate_image((unsigned char*)srcBuf.GetPointer(), width, height, colorFormat,
+ (unsigned char*)dstBuf.GetPointer(), &outWidth, &outHeight, rotation);
+
+ SysTryCatch(NID_MEDIA, ret == 0, r = E_SYSTEM, E_SYSTEM,
+ "mm_util_rotate_image failed with error code: %0x", ret);
+#else
+ colorFormat = _SlpUtil::ToColorspace(pixelFormat);
+ rotation = _SlpUtil::ToRotation(flip);
+
+ ret = image_util_transform((byte*)dstBuf.GetPointer(), &outWidth, &outHeight, rotation,
+ (byte*)srcBuf.GetPointer(), width, height, colorFormat);
+ SysTryCatch(NID_MEDIA, ret == IMAGE_UTIL_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
+ "util_transform failed with error code: %0x", ret);
+#endif
+ }
+
+ r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
+ SysTryCatch(NID_MEDIA, r==E_SUCCESS, , r,
+ "[%s] SetLimit to %d failed for buffer.", GetErrorMessage(r),
+ _ImageUtil::GetBufferSize(pixelFormat, outWidth, outHeight));
+
+ return r;
+
+CATCH:
+ return r;
+}
+
+Tizen::Media::ImageFormat
+_ImageUtil::GetImageFormat(const Tizen::Base::String& srcImageFile)
+{
+ ImageFormat imgFormat;
+ ByteBuffer* pBuf = null;
+
+ pBuf = _MediaUtil::FileToBufferN(srcImageFile, _ImageUtil::MinImageFormatLength());
+ SysTryCatch(NID_MEDIA, pBuf != null, , GetLastResult(),
+ "[%s] _MediaUtil::FileToBufferN failed for %ls.",
+ GetErrorMessage(GetLastResult()), srcImageFile.GetPointer());
+
+ imgFormat = GetImageFormat(*pBuf);
+
+ if (pBuf != null)
+ {
+ delete pBuf;
+ }
+ return imgFormat;
+
+CATCH:
+
+ return IMG_FORMAT_NONE;
+}
+
+
+bool
+_ImageUtil::HasAlphaChannel(const Tizen::Base::String& srcImageFile)
+{
+ bool hasAlpha = false;
+ ByteBuffer* pBuf = null;
+
+ pBuf = _MediaUtil::FileToBufferN(srcImageFile);
+ SysTryCatch(NID_MEDIA, pBuf != null, , GetLastResult(),
+ "[%s] _MediaUtil::FileToBufferN failed for %ls.",
+ GetErrorMessage(GetLastResult()), srcImageFile.GetPointer());
+ hasAlpha = HasAlphaChannel(*pBuf);
+
+ // fall through
+CATCH :
+ if (pBuf != null)
+ {
+ delete pBuf;
+ }
+ return hasAlpha;
+}
+
+// For check image format
+static byte _PNG_HEADER[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
+static byte _JPEG_HEADER[] = { 0xFF, 0xD8 }; // support only JFIF.
+static byte _GIF_HEADER[] = { 'G', 'I', 'F' };
+static byte _TIFF_HEADER[][4] = { { 0x49, 0x49, 0x2A, 0x00 }, { 0x4D, 0x4D, 0x00, 0x2A } };
+static byte _BMP_HEADER[] = { 'B', 'M' };
+static byte _WBMP_HEADER[] = { 0x00, 0x00 };
+
+static const int MIN_IMAGE_FORMAT_LENGTH = sizeof(_PNG_HEADER);
+
+int
+_ImageUtil::MinImageFormatLength(void)
+{
+ return MIN_IMAGE_FORMAT_LENGTH;
+}
+
+ImageFormat
+_ImageUtil::GetImageFormat(const Tizen::Base::ByteBuffer& srcBuf)
+{
+ const byte* pBuf = null;
+ static struct
+ {
+ byte* pHeader;
+ int size;
+ ImageFormat format;
+ } map[] = {
+ { _PNG_HEADER, sizeof(_PNG_HEADER), IMG_FORMAT_PNG },
+ { _JPEG_HEADER, sizeof(_JPEG_HEADER), IMG_FORMAT_JPG },
+ { _BMP_HEADER, sizeof(_BMP_HEADER), IMG_FORMAT_BMP },
+ { _GIF_HEADER, sizeof(_GIF_HEADER), IMG_FORMAT_GIF },
+ { _TIFF_HEADER[0], sizeof(_TIFF_HEADER[0]), IMG_FORMAT_TIFF },
+ { _TIFF_HEADER[1], sizeof(_TIFF_HEADER[1]), IMG_FORMAT_TIFF },
+ { _WBMP_HEADER, sizeof(_WBMP_HEADER), IMG_FORMAT_WBMP },
+ };
+ ImageFormat fmt = IMG_FORMAT_NONE;
+ SysTryCatch(NID_MEDIA, &srcBuf != null, , E_INVALID_ARG,
+ "[E_INVALID_ARG] srcBuf is null");
+ SysTryCatch(NID_MEDIA, srcBuf.GetLimit() >= MIN_IMAGE_FORMAT_LENGTH, , E_INVALID_DATA,
+ "[E_INVALID_DATA] data is too small:%d < %d", srcBuf.GetLimit(), MIN_IMAGE_FORMAT_LENGTH);
+
+ pBuf = (const byte*) (srcBuf.GetPointer());
+ SysTryCatch(NID_MEDIA, pBuf != null, , E_INVALID_ARG,
+ "[E_INVALID_ARG] Could not get file header.");
+ for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
+ {
+ if (memcmp(pBuf, map[i].pHeader, map[i].size) == 0)
+ {
+ fmt = map[i].format;
+ break;
+ }
+ }
+ if ((fmt == IMG_FORMAT_WBMP) && (pBuf[2] == 1 || pBuf[2] == 2) && pBuf[3] == 0 )
+ {
+ fmt = IMG_FORMAT_NONE;
+ }
+ return fmt;
+
+
+CATCH:
+ return IMG_FORMAT_NONE;
+}
+
+bool
+_ImageUtil::HasAlphaChannel(const Tizen::Base::ByteBuffer& srcBuf)
+{
+ ImageFormat imgFormat = IMG_FORMAT_NONE;
+ const byte* pBuf = null;
+ bool idatFlag = false;
+ bool hasAlpha = false;
+ unsigned int cnkLength = 0;
+ int curPosition = 0;
+ int value = 0;
+ int bufSize = 0;
+
+ SysTryReturn(NID_MEDIA, &srcBuf != null, hasAlpha, E_INVALID_ARG,
+ "[E_INVALID_ARG] srcBuf is null");
+
+ imgFormat = GetImageFormat(srcBuf);
+
+ SysTryReturn(NID_MEDIA, imgFormat == IMG_FORMAT_PNG, hasAlpha, E_UNSUPPORTED_FORMAT,
+ "[E_UNSUPPORTED_FORMAT] The file is not of PNG format.");
+
+ pBuf = (const byte*)srcBuf.GetPointer();
+ bufSize = srcBuf.GetCapacity();
+
+ curPosition = 25;
+ // 25 means, Png ID(8byte) + IHDR length(4byte) + IHDR(4byte) +
+ // Width(4byte) + Height(4byte) + Bitdepth(1byte) and next 1byte is
+ // color type.
+ // If color type is between 4 and 7, it uses alpha channel.
+ SysTryReturn(NID_MEDIA, bufSize > (curPosition + 4), hasAlpha, E_UNSUPPORTED_FORMAT,
+ "[E_INVALID_DATA] data size is too small: %d < %d", bufSize, curPosition + 4);
+
+ value = pBuf[curPosition];
+ if ((4 <= value) && (value <= 7))
+ {
+ hasAlpha = true;
+ }
+ else if (value == 3)
+ {
+ // check tRNS chunck existance if color type is 3(indexed palette).
+ // 25byte + remained IHDR 3byte(filter mode etc.) = 28byte
+ // 28byte + ?(4byte)
+ curPosition = 33;
+ // Chunk length(4byte)+ chunk name(4byte) + length(value of chunk length) + CRC(4byte)
+ // chunk can be pHYs, sBIT, gAMA, cHRM, tRNS, etc (before IDAT)
+ SysTryReturn(NID_MEDIA, bufSize > (curPosition + 4), hasAlpha, E_INVALID_DATA,
+ "[E_INVALID_DATA] data size is too small: %d < %d", bufSize, curPosition + 4);
+
+ // Structure of chunk:
+ // |<----------------- A single chunk ---------------------->|
+ // |_________________________________________________________|
+ // | 4 bytes || 4 bytes || chunk length bytes || 4 bytes |
+ // |____________||__________||____________________||_________|
+ // | || || || |
+ // |Chunk length||Chunk name|| chunk data || CRC sum |
+ //
+ // data is stored in network byte order; ie big endian.
+ // To get the value, convert to little endian.
+
+ memcpy(&cnkLength, pBuf + curPosition, 4);
+ cnkLength = ntohl(cnkLength);
+
+ // Increment position to point to chunk name, which follows the length.
+ curPosition = curPosition + 4;
+
+ // Loop with starting chunk length.
+ while (curPosition < bufSize - 4)
+ {
+ if (!memcmp((void *)(pBuf + curPosition), (void *)"tRNS", 4))
+ {
+ hasAlpha = true;
+ }
+ else if (!memcmp((void *)(pBuf + curPosition), (void *)"IDAT", 4))
+ {
+ idatFlag = true;
+ }
+ else
+ {
+ curPosition += 4; // chunk name
+ curPosition += cnkLength;
+ curPosition += 4; // CRC
+ }
+
+ // tRNS chunk must be before IDAT chunk.
+ if (idatFlag || hasAlpha)
+ {
+ break;
+ }
+
+ if (curPosition >= bufSize - 4)
+ {
+ break;
+ }
+
+ // read next chunk length
+ memcpy(&cnkLength, pBuf + curPosition, 4);
+ cnkLength = ntohl(cnkLength);
+ curPosition = curPosition + 4;
+ }
+ }
+
+ return hasAlpha;
+}
+
+Tizen::Base::ByteBuffer*
+_ImageUtil::ResizeN(const Tizen::Base::ByteBuffer &srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ int dstWidth, int dstHeight)
+{
+ int bufSize = 0;
+ std::unique_ptr <ByteBuffer> pOutBuf;
+ result r = E_SUCCESS;
+
+ bufSize = GetBufferSize(pixelFormat, dstWidth, dstHeight);
+ SysTryReturn(NID_MEDIA, bufSize > 0, null, GetLastResult(),
+ "[%s] Check dimensions (%d x %d) and pixelformat %d", GetErrorMessage(GetLastResult()),
+ dstWidth, dstHeight, pixelFormat);
+
+ pOutBuf.reset(new (std::nothrow) ByteBuffer());
+ SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[%s] Failed to create new ByteBuffer", GetErrorMessage(GetLastResult()));
+
+ r = pOutBuf->Construct(bufSize);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] ByteBuffer.Construct failed", GetErrorMessage(r));
+
+ r = Resize(srcBuf, pixelFormat, srcWidth, srcHeight, *pOutBuf.get(), dstWidth, dstHeight);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] ImageUtil.Resize", GetErrorMessage(r));
+
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+}
+
+result
+_ImageUtil::Crop(const Tizen::Base::ByteBuffer &srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ Tizen::Base::ByteBuffer &dstBuf,
+ int dstX, int dstY, int dstWidth, int dstHeight)
+{
+ result r = E_SUCCESS;
+ byte* pInBuffer = null;
+ byte* pOutBuffer = null;
+ int copyRowWidth = 0;
+ int srcRowWidth = 0;
+ int bpp = 0;
+
+ SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid src dimension: Should be greater than zero (%d x %d)", srcWidth, srcHeight);
+ SysTryCatch(NID_MEDIA, dstWidth > 0 && dstHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid dst dimension: Should be greater than zero (%d x %d)", dstWidth, dstHeight);
+ SysTryCatch(NID_MEDIA, dstX >= 0 && dstY >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid offset dimension: Should be greater than zero (%d x %d)", dstX, dstY);
+
+ SysTryCatch(NID_MEDIA, (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE) ||
+ (pixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888) ||
+ (pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888),
+ r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "Unsupported pixelFormat: %d", pixelFormat);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, srcWidth, srcHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_BUF(srcBuf, pixelFormat, srcWidth, srcHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
+ srcBuf.GetLimit(), pixelFormat, srcWidth, srcHeight);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, dstWidth, dstHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", dstWidth, dstHeight);
+
+ SysTryCatch(NID_MEDIA, IS_VALID_BUF(dstBuf, pixelFormat, dstWidth, dstHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid buffer size (%d) for format (%d), width (%d), height (%d)",
+ dstBuf.GetLimit(), pixelFormat, dstWidth, dstHeight);
+
+ SysTryCatch(NID_MEDIA, dstWidth + dstX <= srcWidth , r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid Clip Area : destination \"x\" (%d) exceeds image width (%d).",
+ dstWidth + dstX, srcWidth);
+
+ SysTryCatch(NID_MEDIA, dstHeight + dstY <= srcHeight , r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid Clip Area : destination \"y\" (%d) exceeds image height (%d).",
+ dstHeight + dstY, srcHeight);
+
+ pOutBuffer = (byte *)dstBuf.GetPointer();
+
+ if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
+ {
+ bpp = 2;
+ // pInBuffer points to the start of the region to be copied to destination.
+ pInBuffer = (byte *)srcBuf.GetPointer() + (dstY * srcWidth * bpp) + (dstX * bpp);
+ copyRowWidth = dstWidth * bpp;
+ srcRowWidth = srcWidth * bpp;
+ }
+ else
+ {
+ bpp = 4;
+ // pInBuffer points to the start of the region to be copied to destination.
+ pInBuffer = (byte *)srcBuf.GetPointer() + (dstY * srcWidth * bpp) + (dstX * bpp);
+ copyRowWidth = dstWidth * bpp; // BGRA and RGBA are 4 bytes each.
+ srcRowWidth = srcWidth * bpp;
+ }
+
+ for (int i = dstY; i < dstY + dstHeight; i++)
+ {
+ memcpy(pOutBuffer, pInBuffer, copyRowWidth);
+ pOutBuffer += copyRowWidth;
+ pInBuffer += srcRowWidth;
+ }
+
+ r = dstBuf.SetLimit(_ImageUtil::GetBufferSize(pixelFormat, dstWidth, dstHeight));
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] ByteBuffer.SetLimit to %d failed.",
+ GetErrorMessage(r), _ImageUtil::GetBufferSize(pixelFormat, dstWidth, dstHeight));
+ return r;
+
+CATCH:
+ return r;
+}
+
+result
+_ImageUtil::CropBuffer(const byte* srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ byte* dstBuf,
+ int dstX, int dstY, int dstWidth, int dstHeight)
+{
+ result r = E_SUCCESS;
+ int copyRowWidth = 0;
+ int srcRowWidth = 0;
+ int bpp = 0;
+ byte* pInBuffer = null;
+ byte* pOutBuffer = null;
+
+ SysTryCatch(NID_MEDIA, srcWidth > 0 && srcHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid src dimension: Should be greater than zero (%d x %d)", srcWidth, srcHeight);
+ SysTryCatch(NID_MEDIA, dstWidth > 0 && dstHeight > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid dst dimension: Should be greater than zero (%d x %d)", dstWidth, dstHeight);
+ SysTryCatch(NID_MEDIA, dstX >= 0 && dstY >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Invalid offset dimension: Should be greater than zero (%d x %d)", dstX, dstY);
+
+ SysTryCatch(NID_MEDIA, (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE) ||
+ (pixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888) ||
+ (pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888),
+ r = E_UNSUPPORTED_FORMAT, E_UNSUPPORTED_FORMAT,
+ "Unsupported pixelFormat: %d", pixelFormat);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, srcWidth, srcHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", srcWidth, srcHeight);
+
+ SysTryCatch(NID_MEDIA, IsValidDimension(pixelFormat, dstWidth, dstHeight),
+ r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be even (%d x %d).", dstWidth, dstHeight);
+
+ SysTryCatch(NID_MEDIA, dstWidth + dstX <= srcWidth , r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid Clip Area : destination \"x\" (%d) exceeds image width (%d).",
+ dstWidth + dstX, srcWidth);
+
+ SysTryCatch(NID_MEDIA, dstHeight + dstY <= srcHeight , r = E_INVALID_ARG, E_INVALID_ARG,
+ "Invalid Clip Area : destination \"y\" (%d) exceeds image height (%d).",
+ dstHeight + dstY, srcHeight);
+
+ pOutBuffer = dstBuf;
+
+ if (pixelFormat == MEDIA_PIXEL_FORMAT_RGB565LE)
+ {
+ bpp = 2;
+ // pInBuffer points to the start of the region to be copied to destination.
+ pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
+ copyRowWidth = dstWidth * bpp;
+ srcRowWidth = srcWidth * bpp;
+ }
+ else
+ {
+ bpp = 4;
+ // pInBuffer points to the start of the region to be copied to destination.
+ pInBuffer = const_cast<byte*>(srcBuf) + (dstY * srcWidth * bpp) + (dstX * bpp);
+ copyRowWidth = dstWidth * bpp; // BGRA and RGBA are 4 bytes each.
+ srcRowWidth = srcWidth * bpp;
+ }
+
+ for (int i = dstY; i < dstY + dstHeight; i++)
+ {
+ memcpy(pOutBuffer, pInBuffer, copyRowWidth);
+ pOutBuffer += copyRowWidth;
+ pInBuffer += srcRowWidth;
+ }
+
+CATCH:
+ return r;
+}
+
+Tizen::Base::ByteBuffer*
+_ImageUtil::CropN(const Tizen::Base::ByteBuffer &srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ int dstX, int dstY,
+ int dstWidth, int dstHeight)
+{
+ int bufSize = 0;
+ std::unique_ptr <ByteBuffer> 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) ByteBuffer());
+ SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not create new ByteBuffer.");
+
+ r = pOutBuf->Construct(bufSize);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] buf.Construct failed.", GetErrorMessage(r));
+
+ r = Crop(srcBuf, pixelFormat, srcWidth, srcHeight, *pOutBuf.get(), dstX, dstY, dstWidth, dstHeight);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] ImageUtil.Crop failed.", GetErrorMessage(r));
+
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+}
+
+int
+_ImageUtil::GetBufferSize(MediaPixelFormat pixelFormat, int width, int height)
+{
+ typedef struct _Rational
+ {
+ int num;
+ int den;
+ } rational;
+
+ static struct
+ {
+ MediaPixelFormat key;
+ rational value;
+ } map[] = {
+ { MEDIA_PIXEL_FORMAT_RGB565LE, {2, 1}},
+ { MEDIA_PIXEL_FORMAT_RGBA8888, {4, 1}},
+ { MEDIA_PIXEL_FORMAT_BGRA8888, {4, 1}},
+ { MEDIA_PIXEL_FORMAT_YUV420P, {3, 2}},
+ { MEDIA_PIXEL_FORMAT_NV12, {3, 2}},
+ { MEDIA_PIXEL_FORMAT_YUYV422, {2, 1}},
+ { MEDIA_PIXEL_FORMAT_BGR888, {3,1}},
+ { MEDIA_PIXEL_FORMAT_RGB888, {3,1}},
+ };
+ rational ret = {0, 0};
+
+ SysTryCatch(NID_MEDIA, width > 0 && height > 0, , E_INVALID_ARG,
+ "[E_INVALID_ARG] Dimensions should be greater than zero (%d x %d)", width, height);
+
+ for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
+ {
+ if (map[i].key == pixelFormat)
+ {
+ ret = map[i].value;
+ break;
+ }
+ }
+
+ SysTryCatch(NID_MEDIA, ret.den != 0, , E_UNSUPPORTED_FORMAT,
+ "Could not find details for pixelformat %d.", pixelFormat);
+
+ SetLastResult(E_SUCCESS);
+ return width * height * ret.num / ret.den;
+
+CATCH:
+ return 0;
+}
+
+bool
+_ImageUtil::IsValidDimension(MediaPixelFormat pixelFormat, int width, int height)
+{
+ MediaPixelFormat fmt[] = {
+ MEDIA_PIXEL_FORMAT_YUV420P,
+ MEDIA_PIXEL_FORMAT_NV12,
+ MEDIA_PIXEL_FORMAT_YUYV422,
+ };
+
+ for (unsigned int i = 0; i < sizeof(fmt)/sizeof(fmt[0]); i++)
+ {
+ if (fmt[i] == pixelFormat)
+ {
+ if ((width & 0x01) || (height & 0x01))
+ {
+ return false;
+ }
+ return true;
+ }
+ }
+ // return true for other pixel formats
+ return true;
+}
+
+int
+_ImageUtil::ToFfmpegPixelFormat(MediaPixelFormat pixelFmt)
+{
+ for (unsigned int i = 0; i < sizeof(_PIXEL_FORMAT_MAP)/sizeof(_PIXEL_FORMAT_MAP[0]); i++)
+ {
+ if (pixelFmt == _PIXEL_FORMAT_MAP[i].mediaPixelFmt)
+ {
+ return _PIXEL_FORMAT_MAP[i].pixelFmt;
+ }
+ }
+ return PIX_FMT_NONE;
+}
+
+MediaPixelFormat
+_ImageUtil::ToMediaPixelFormatFromFfmpeg(int pixelFormat)
+{
+ for (unsigned int i = 0; i < sizeof(_PIXEL_FORMAT_MAP)/sizeof(_PIXEL_FORMAT_MAP[0]); i++)
+ {
+ if (pixelFormat == _PIXEL_FORMAT_MAP[i].pixelFmt)
+ {
+ return _PIXEL_FORMAT_MAP[i].mediaPixelFmt;
+ }
+ }
+ return MEDIA_PIXEL_FORMAT_NONE;
+}
+
+}} // Tizen::Media
--- /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_JpegDecoder.cpp
+ * @brief This file contains the implementation of _JpegDecoder class.
+ */
+#include <stdio.h>
+#include <setjmp.h>
+#include <jpeglib.h>
+#include <stdlib.h>
+#include <FMediaTypes.h>
+#include <FBaseSysLog.h>
+#include "FMedia_JpegDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+_JpegDecoder::_JpegDecoder(void)
+{
+ __pSrcBuf = null;
+ __srcBufSize = 0;
+ __srcWidth = 0;
+ __srcHeight = 0;
+ __decodingRectX = 0;
+ __decodingRectY = 0;
+ __decodingRectWidth = 0;
+ __decodingRectHeight = 0;
+ __isDecodeRegionEnabled = false;
+ __scale = 0;
+ __pDec = null;
+ __pErr = null;
+ __pJmp = null;
+}
+
+_JpegDecoder::~_JpegDecoder(void)
+{
+ // SAFE_DELETE_ARRAY(__pSrcBuf);
+ if (__pDec != null)
+ {
+ jpeg_destroy_decompress(__pDec);
+ }
+
+ if (__pDec)
+ {
+ delete __pDec;
+ }
+ if (__pErr)
+ {
+ delete __pErr;
+ }
+ if (__pJmp)
+ {
+ delete __pJmp;
+ }
+}
+
+void
+_JpegDecoder::JpegErrorExitStatic(struct jpeg_common_struct * pDecInfo)
+{
+ if (pDecInfo != null)
+ {
+ _JpegDecoder *pDec = (_JpegDecoder*)pDecInfo->client_data;
+ if (pDec)
+ {
+ pDec->JpegErrorExit();
+ }
+ }
+}
+
+void
+_JpegDecoder::JpegErrorExit(void)
+{
+ longjmp(__pJmp, 1);
+}
+
+result
+_JpegDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturnResult(NID_MEDIA, __pDec == null, E_INVALID_STATE, "Already constructed");
+
+ // TODO: do not copy the source data
+ //__pSrcBuf = new (std::nothrow) byte[length];
+ //SysTryCatch(NID_MEDIA, __pSrcBuf != null, r = E_SYSTEM, E_SYSTEM,
+ // "[E_SYSTEM] new byte:%d", length);
+ // memcpy(__pSrcBuf, buffer, length);
+ __pSrcBuf = (byte*)buffer;
+ __srcBufSize = length;
+
+ __pDec = new (std::nothrow) jpeg_decompress_struct;
+ SysTryCatch(NID_MEDIA, __pDec != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] new ", sizeof(jpeg_decompress_struct));
+ __pErr = new (std::nothrow) jpeg_error_mgr;
+ SysTryCatch(NID_MEDIA, __pErr != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] new ", sizeof(jpeg_error_mgr));
+ __pJmp = new (std::nothrow) __jmp_buf_tag;
+ SysTryCatch(NID_MEDIA, __pJmp != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] new ", sizeof(__jmp_buf_tag));
+
+ memset(__pDec, 0, sizeof(jpeg_decompress_struct));
+ memset(__pErr, 0, sizeof(jpeg_error_mgr));
+ memset(__pJmp, 0, sizeof(__jmp_buf_tag));
+
+ // Initialize
+ __pDec->err = jpeg_std_error(__pErr);
+ __pErr->error_exit = JpegErrorExitStatic;
+ __pDec->client_data = this;
+
+ SysTryCatch(NID_MEDIA, !setjmp(__pJmp), r = E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] error jump");
+
+ jpeg_create_decompress(__pDec);
+
+ // Specify data source for decompression
+ jpeg_mem_src(__pDec, (JOCTET*) __pSrcBuf, __srcBufSize);
+
+ // Read file header, set default decompression parameters
+ jpeg_read_header(__pDec, TRUE);
+
+ __srcWidth = __pDec->image_width;
+ __srcHeight = __pDec->image_height;
+
+ return E_SUCCESS;
+
+CATCH:
+ //SAFE_DELETE_ARRAY(__pSrcBuf);
+ if (__pDec)
+ {
+ jpeg_destroy_decompress(__pDec);
+ }
+ return r;
+}
+
+result
+_JpegDecoder::DecodeN(byte*& outBuf, int& length)
+{
+ int buffSize = 0;
+ int planarSize = 0;
+ int h = 0;
+ byte* pReturnBuf = null;
+ int outY = 0;
+ int outX = 0;
+
+ result r = E_SUCCESS;
+
+ // Set decoding option
+ if (__pDec->jpeg_color_space == JCS_GRAYSCALE)
+ {
+ __pDec->out_color_space = JCS_GRAYSCALE;
+ }
+ else // YUV444
+ {
+ __pDec->out_color_space = JCS_YCbCr;
+ }
+
+ // Start decompressor
+ jpeg_start_decompress(__pDec);
+
+ // Write output buffer
+ __srcWidth = __pDec->output_width;
+ __srcHeight = __pDec->output_height;
+
+ if (__pDec->output_components == 1) // for grayscale
+ {
+ if (__isDecodeRegionEnabled == true)
+ {
+ int row_stride = __pDec->output_width;
+ buffSize = __decodingRectWidth * __decodingRectHeight * 3;
+ length = buffSize;
+ JSAMPARRAY buffer = (*__pDec->mem->alloc_sarray)((struct jpeg_common_struct *) __pDec, JPOOL_IMAGE, row_stride, 1);
+
+ pReturnBuf = new (std::nothrow) byte[buffSize];
+ SysTryCatch(NID_MEDIA, pReturnBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", buffSize);
+
+ // Initialize cb and cr to 128, since they need not be considered for gray scale image.
+ memset(pReturnBuf, 128, buffSize);
+ outBuf = pReturnBuf;
+
+ while (__pDec->output_scanline < (__decodingRectY + __decodingRectHeight))
+ {
+ jpeg_read_scanlines(__pDec, buffer, 1);
+ if (h >= __decodingRectY)
+ {
+ outX = 0;
+ for (int x = __decodingRectX; x < __decodingRectX + __decodingRectWidth; x++)
+ {
+ JSAMPLE* p = buffer[0] + x;
+
+ // YUV444 -> YUV444p
+ pReturnBuf[(__decodingRectWidth * outY) + outX] = p[0]; // Y
+ outX++;
+ }
+ outY++;
+ }
+ }
+ }
+ else // if not decoding a region
+ {
+ int row_stride = __pDec->output_width;
+ buffSize = __pDec->output_width * __pDec->output_height * 3;
+ length = buffSize;
+ JSAMPARRAY buffer = (*__pDec->mem->alloc_sarray)((struct jpeg_common_struct *) __pDec, JPOOL_IMAGE, row_stride, 1);
+
+ pReturnBuf = new (std::nothrow) byte[buffSize];
+ SysTryCatch(NID_MEDIA, pReturnBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", buffSize);
+
+ // Initialize cb and cr to 128, since they need not be considered for gray scale image.
+ memset(pReturnBuf, 128, buffSize);
+ outBuf = pReturnBuf;
+
+ while (__pDec->output_scanline < __pDec->output_height)
+ {
+ jpeg_read_scanlines(__pDec, buffer, 1);
+
+ for (unsigned int x = 0; x < __pDec->output_width; x++)
+ {
+ JSAMPLE* p = buffer[0] + x;
+ // YUV444 -> YUV444p
+ pReturnBuf[(__pDec->output_width * h) + x] = p[0]; // Y
+ }
+ h++;
+ }
+ }
+ }
+ else
+ {
+ if (__isDecodeRegionEnabled == true)
+ {
+ buffSize = __decodingRectWidth * __decodingRectHeight * __pDec->output_components;
+ planarSize = (__decodingRectWidth * __decodingRectHeight);
+ length = buffSize;
+ int row_stride = __pDec->output_width * __pDec->output_components;
+ JSAMPARRAY buffer = (*__pDec->mem->alloc_sarray)((struct jpeg_common_struct *) __pDec, JPOOL_IMAGE, row_stride, 1);
+
+ pReturnBuf = new (std::nothrow) byte[buffSize];
+ SysTryCatch(NID_MEDIA, pReturnBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", buffSize);
+
+ memset(pReturnBuf, 0, buffSize);
+ outBuf = pReturnBuf;
+
+ while (__pDec->output_scanline < (__decodingRectY + __decodingRectHeight))
+ {
+ jpeg_read_scanlines(__pDec, buffer, 1);
+ if (h >= __decodingRectY)
+ {
+ outX = 0;
+ for (int x = __decodingRectX; x < __decodingRectX + __decodingRectWidth; x++)
+ {
+ JSAMPLE* p = buffer[0] + 3 * x;
+
+ // YUV444 -> YUV444p
+ pReturnBuf[(__decodingRectWidth * outY) + outX] = p[0]; // Y
+ pReturnBuf[(__decodingRectWidth * outY) + planarSize + outX] = p[1]; // Cb
+ pReturnBuf[(__decodingRectWidth * outY) + (planarSize * 2) + outX] = p[2]; // Cr
+ outX++;
+ }
+ outY++;
+ }
+ h++;
+ }
+ }
+ else
+ {
+ buffSize = __pDec->output_width * __pDec->output_height * __pDec->output_components;
+ planarSize = __pDec->output_width * __pDec->output_height;
+ length = buffSize;
+ int row_stride = __pDec->output_width * __pDec->output_components;
+ JSAMPARRAY buffer = (*__pDec->mem->alloc_sarray)((struct jpeg_common_struct *) __pDec, JPOOL_IMAGE, row_stride, 1);
+
+ pReturnBuf = new (std::nothrow) byte[buffSize];
+ SysTryCatch(NID_MEDIA, pReturnBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes for output.", buffSize);
+
+ memset(pReturnBuf, 0, buffSize);
+ outBuf = pReturnBuf;
+
+ while (__pDec->output_scanline < __pDec->output_height)
+ {
+ jpeg_read_scanlines(__pDec, buffer, 1);
+
+ for (unsigned int x = 0; x < __pDec->output_width; x++)
+ {
+ JSAMPLE* p = buffer[0] + 3 * x;
+
+ // YUV444 -> YUV444p
+ pReturnBuf[(__pDec->output_width * h) + x] = p[0]; // Y
+ pReturnBuf[(__pDec->output_width * h) + planarSize + x] = p[1]; // Cb
+ pReturnBuf[(__pDec->output_width * h) + (planarSize * 2) + x] = p[2]; // Cr
+ }
+ h++;
+ }
+ }
+ }
+
+ pReturnBuf = null;
+
+CATCH:
+ return r;
+}
+
+result
+_JpegDecoder::SetDecodingRegion(int x, int y, int width, int height)
+{
+ SysTryReturnResult(NID_MEDIA, ((x >= 0) && (y >= 0) && ((x + width) <= __srcWidth) && ((y + height) <= __srcHeight)), E_INVALID_ARG,
+ "Invalid Input - %d %d %d %d src_width - %d src_height - %d", x, y, width, height, __srcWidth, __srcHeight);
+ __decodingRectX = x;
+ __decodingRectY = y;
+ __decodingRectWidth = width;
+ __decodingRectHeight = height;
+ __isDecodeRegionEnabled = true;
+ return E_SUCCESS;
+}
+
+result
+_JpegDecoder::GetDimension(int& width, int& height)
+{
+ width = __srcWidth;
+ height = __srcHeight;
+
+ return E_SUCCESS;
+}
+
+MediaPixelFormat
+_JpegDecoder::GetPixelFormat(void)
+{
+ return MEDIA_PIXEL_FORMAT_YUV444P;
+}
+
+result
+_JpegDecoder::SetScaleDown(int scaleDown)
+{
+ __scale = scaleDown;
+ return E_SUCCESS;
+}
+
+result
+_JpegDecoder::GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+}} // Tizen::Media
--- /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_JpegDecoder.h
+ * @brief This is header file for _JpegDecoder.
+ */
+#ifndef _FMEDIA_INTERNAL_JPEG_DECODER_H_
+#define _FMEDIA_INTERNAL_JPEG_DECODER_H_
+
+#include "FMedia_IImageDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+class _JpegDecoder
+ : public _IImageDecoder
+ , public Tizen::Base::Object
+{
+public:
+ static const int MAX_WIDTH = 5000;
+ static const int MAX_HEIGHT = 5000;
+ static const int MAX_SIZE = 4096000; // 4Mbyte
+
+ /**
+ * This is the default constructor for this class.
+ *
+ * @see Construct()
+ */
+ _JpegDecoder(void);
+
+ /**
+ * This is the destructor for this class.
+ *
+ * @see Construct()
+ */
+ virtual ~_JpegDecoder(void);
+
+ /**
+ * Constructs this instancce with given buffer and length.
+ *
+ * @return An error code
+ * @param[in] buffer The buffer that contains compressed data.
+ * @param[in] length The length of buffer.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual result Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat);
+
+ /**
+ * Decodes current frame and returns decoded data.
+ *
+ * @return An error code
+ * @param[out] outBuf The decoded frame buffer.
+ * @param[out] length The length of outBuf.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_DATA The data is invalid.
+ */
+ virtual result DecodeN(byte*& outBuf, int& length);
+
+ /**
+ * Sets the decoding region. @n
+ *
+ * @return An error code
+ * @param[in] rect The decoding region.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetDecodingRegion(int x, int y, int width, int height);
+
+ /**
+ * Gets current dimension of image.
+ *
+ * @return An error code
+ * @param[out] width The width of image.
+ * @param[out] height The height of image.
+ * @param[out] pitch The pitch of image in bytes.
+ */
+ virtual result GetDimension(int& width, int& height);
+
+ /**
+ * Gets the output pixel format.
+ *
+ * @return The output pixel format.
+ */
+ virtual MediaPixelFormat GetPixelFormat(void);
+
+ /**
+ * Sets scale down degree.
+ *
+ * @return An error code
+ * @param[in] scaleDown The level of scale down.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetScaleDown(int scaleDown);
+
+ /**
+ * Gets the value of given key.
+ *
+ * @return An error code
+ * @param[in] key The key of the value.
+ * @param[out] value The output value.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+private:
+ _JpegDecoder(const _JpegDecoder&);
+ _JpegDecoder& operator =(const _JpegDecoder & __jpegDecoder);
+
+private:
+ static void JpegErrorExitStatic(struct jpeg_common_struct * decInfo);
+ void JpegErrorExit(void);
+
+ byte* __pSrcBuf;
+ int __srcBufSize;
+ int __srcWidth;
+ int __srcHeight;
+ int __scale;
+ int __decodingRectX;
+ int __decodingRectY;
+ int __decodingRectWidth;
+ int __decodingRectHeight;
+ bool __isDecodeRegionEnabled;
+ struct jpeg_decompress_struct* __pDec;
+ struct jpeg_error_mgr* __pErr;
+ struct __jmp_buf_tag* __pJmp;
+}; // class _JpegDecoder
+
+
+};
+};
+
+#endif
--- /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_JpegEncoder.cpp
+ * @brief This file contains the implementation of _JpegEncoder class.
+ */
+
+#include <stdio.h>
+#include <jpeglib.h>
+#include <setjmp.h>
+#include <FMediaImageTypes.h>
+#include <FBaseSysLog.h>
+#include "FMedia_JpegEncoder.h"
+
+using namespace Tizen::Base;
+
+namespace Tizen { namespace Media
+{
+
+static const int MIN_JPEG_ENC_WIDTH = 16;
+static const int MIN_JPEG_ENC_HEIGHT = 16;
+static const int MAX_JPEG_ENC_WIDTH = 5000;
+static const int MAX_JPEG_ENC_HEIGHT = 5000;
+
+static void JpegErrorExitStatic(struct jpeg_common_struct * pJpegInfo);
+
+_JpegEncoder::_JpegEncoder(void)
+{
+ __pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
+ __quality = 90;
+ __width = 0;
+ __height = 0;
+}
+
+_JpegEncoder::~_JpegEncoder(void)
+{
+
+}
+
+result
+_JpegEncoder::Construct(int width, int height,
+ MediaPixelFormat srcPixelFormat,
+ MediaPixelFormat& reqPixelFormat,
+ int quality)
+{
+ SysTryReturnResult(NID_MEDIA, width >= MIN_JPEG_ENC_WIDTH, E_INVALID_ARG,
+ "Width (%d) should be greater than (%d)", width, MIN_JPEG_ENC_WIDTH);
+ SysTryReturnResult(NID_MEDIA, width <= MAX_JPEG_ENC_WIDTH, E_OVERFLOW,
+ "width (%d) should be lesser than (%d)", width, MAX_JPEG_ENC_WIDTH);
+ SysTryReturnResult(NID_MEDIA, height >= MIN_JPEG_ENC_HEIGHT, E_INVALID_ARG,
+ "Height (%d) should be greater than (%d)", height, MIN_JPEG_ENC_HEIGHT);
+ SysTryReturnResult(NID_MEDIA, height <= MAX_JPEG_ENC_HEIGHT, E_OVERFLOW,
+ "Height (%d) should be lesser than (%d)", height, MAX_JPEG_ENC_HEIGHT);
+ SysTryReturnResult(NID_MEDIA, quality > 0, E_INVALID_ARG,
+ "Quality (%d) should be greater than zero.", quality);
+ SysTryReturnResult(NID_MEDIA, quality <= 100, E_INVALID_ARG,
+ "Quality (%d) quality should be lesser than 100.", quality);
+
+ // TODO: add handling of srcPixelFormat
+ __width = width;
+ __height = height;
+ __pixelFormat = MEDIA_PIXEL_FORMAT_RGB888;
+ reqPixelFormat = MEDIA_PIXEL_FORMAT_RGB888;
+ __quality = quality;
+
+ return E_SUCCESS;
+}
+
+
+Tizen::Base::ByteBuffer*
+_JpegEncoder::EncodeN(const byte* srcBuf, int srcLength)
+{
+ result r = E_SUCCESS;
+
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ JSAMPROW ppRows[2] = {0,0}; // pointer to a single row
+ int rowStride = 0;
+ unsigned long outSize = 0;
+ //byte* pPos = null;
+ byte* pOutBuf = null;
+ jmp_buf errJump;
+ ByteBuffer* pRetBuf = null;
+
+ //SysTryReturn(NID_MEDIA, srcLength <= JPG_MAX_SIZE, E_OVERFLOW, E_OVERFLOW,
+ // "Buffer size is overflowed : size %d byte", srcLength);
+ //SysTryReturn(NID_MEDIA, ((dim.width <= JPG_MAX_WIDTH) &&
+ // (dim.height <= JPG_MAX_HEIGTH)), E_OVERFLOW, E_OVERFLOW,
+ // "Dimensions too large : width %d / height :%d", dim.width, dim.height);
+
+ // Initialize
+ cinfo.err = jpeg_std_error(&jerr);
+ jerr.error_exit = JpegErrorExitStatic;
+ cinfo.client_data = &errJump;
+
+ SysTryCatch(NID_MEDIA, !setjmp(errJump), r = E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] error jump");
+
+ jpeg_create_compress(&cinfo);
+
+ // Set output to dest buf
+ jpeg_mem_dest(&cinfo, &pOutBuf, &outSize);
+
+ cinfo.image_width = __width;
+ cinfo.image_height = __height;
+ cinfo.input_components = 3; // TODO: GetBytesPerPixel(pixelFormat);
+ cinfo.in_color_space = JCS_RGB; // colorspace of input image // or JCS_YCbCr
+
+ jpeg_set_defaults(&cinfo);
+ // Make optional parameter settings here
+ jpeg_set_quality(&cinfo, __quality, false);
+
+ jpeg_start_compress(&cinfo, TRUE);
+
+ rowStride = __width * 3; // JSAMPLEs per row in image_buffer // 4, if use JCS_YCbCr
+
+ // position = (byte*) srcBuf;
+ while (cinfo.next_scanline < cinfo.image_height)
+ {
+ ppRows[0] = (byte*)srcBuf + cinfo.next_scanline * rowStride;
+ jpeg_write_scanlines(&cinfo, ppRows, 1);
+ }
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ SysTryCatch(NID_MEDIA, outSize > 0, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] jpeg lib returned outSize (%d)", outSize);
+
+ SysTryCatch(NID_MEDIA, pOutBuf != null, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] outbuf is null.");
+
+ //dstLength = (int) outSize;
+ //dstBuf = new (std::nothrow) byte[outSize];
+ pRetBuf = new (std::nothrow) ByteBuffer();
+ SysTryCatch(NID_MEDIA, pRetBuf != 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. Failed to construct ByteBuffer of size %d",
+ GetErrorMessage(r), outSize);
+ r = pRetBuf->SetArray(pOutBuf, 0, outSize);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated. Failed to SetArray for buffer %x, size %d",
+ GetErrorMessage(r), pOutBuf, outSize);
+ pRetBuf->Flip();
+
+ free(pOutBuf);
+
+ return pRetBuf;
+
+CATCH:
+ if (pOutBuf)
+ {
+ free(pOutBuf);
+ }
+ if (pRetBuf)
+ {
+ delete pRetBuf;
+ }
+ return null;
+}
+
+static void
+JpegErrorExitStatic(struct jpeg_common_struct * pJpegInfo)
+{
+ if (pJpegInfo)
+ {
+ jmp_buf *pBuf = (jmp_buf*)pJpegInfo->client_data;
+ if (*pBuf)
+ {
+ longjmp(*pBuf, 1);
+ }
+ }
+}
+
+result
+_JpegEncoder::SetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+}} // Tizen::Media
--- /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_JpegEncoder.h
+ * @brief This is header file for _JpegEnecoder.
+ */
+
+#ifndef _FMEDIA_INTERNAL_JPEG_ENCODER_H_
+#define _FMEDIA_INTERNAL_JPEG_ENCODER_H_
+
+#include "FMedia_IImageEncoder.h"
+
+namespace Tizen { namespace Media
+{
+
+class _JpegEncoder
+ : public _IImageEncoder
+ , public Tizen::Base::Object
+{
+public:
+ /**
+ * This is the default constructor for this class.
+ *
+ * @see Construct()
+ */
+ _JpegEncoder(void);
+
+ /**
+ * This is the destructor for this class.
+ *
+ * @see Construct()
+ */
+ virtual ~_JpegEncoder(void);
+
+ /**
+ * Initialize this instance.
+ * @param[in] dim Encode dimension
+ * @param[in] pixelFormat Encode pixel format
+ * @param[in] quality Encoding quality
+ */
+ virtual result Construct(int width, int height,
+ MediaPixelFormat srcPixelFormat,
+ MediaPixelFormat& reqPixelFormat,
+ int quality);
+
+ /**
+ * Encodes the image data
+ *
+ * @return An error code
+ * @param[in] srcBuf Source raw data
+ * @param[in] srcLength Source data length
+ * @param[out] dstBuf Encoded destination buffer
+ * @param[out] dstLength Destination buffer length
+ *
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual Tizen::Base::ByteBuffer* EncodeN(const byte* srcBuf, int srcLength);
+
+ /**
+ * Set specific key value to the encoder
+ * @return An error code
+ * @param[in] key The key to be set
+ * @param[in] value The value to be set.
+ */
+ virtual result SetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+protected:
+
+
+private:
+ int __width;
+ int __height;
+ int __quality;
+ MediaPixelFormat __pixelFormat;
+}; // class _JpegEncoder
+
+
+};
+};
+
+#endif
--- /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_JpegTurboDecoder.cpp
+* @brief This file contains the implementation of _JpegTurboDecoder class.
+*/
+#include <unique_ptr.h>
+#include <turbojpeg.h>
+#include <FMediaImageTypes.h>
+#include <FBaseSysLog.h>
+#include "FMedia_JpegTurboDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+_JpegTurboDecoder::_JpegTurboDecoder(void)
+{
+ __pSrcBuf = null;
+ __srcBufSize = 0;
+ __srcWidth = 0;
+ __srcHeight = 0;
+ __decodingRectX = 0;
+ __decodingRectY = 0;
+ __decodingRectWidth = 0;
+ __decodingRectHeight = 0;
+ __isDecodeRegionEnabled = false;
+ __tjDecodingHandle = null;
+ __tjTransformHandle = null;
+ __scale = 0;
+ __subSamp = TJSAMP_444;
+ __requestPixelFormat = MEDIA_PIXEL_FORMAT_NONE;
+}
+
+_JpegTurboDecoder::~_JpegTurboDecoder(void)
+{
+ if(__tjDecodingHandle)
+ {
+ tjDestroy(__tjDecodingHandle);
+ }
+ if(__tjTransformHandle)
+ {
+ tjDestroy(__tjTransformHandle);
+ }
+}
+
+result
+_JpegTurboDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
+{
+ result r = E_SUCCESS;
+ int ret;
+
+ __pSrcBuf = const_cast<byte*>(buffer);
+ __srcBufSize = length;
+
+ __requestPixelFormat = pixelFormat;
+
+ __tjDecodingHandle = tjInitDecompress();
+ SysTryCatch(NID_MEDIA, __tjDecodingHandle != null, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] Turbo JPEG InitDecompress failed : %s", tjGetErrorStr());
+
+ ret = tjDecompressHeader2(__tjDecodingHandle, __pSrcBuf, __srcBufSize, &__srcWidth, &__srcHeight, &__subSamp);
+ SysTryCatch(NID_MEDIA, ret == 0 , r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] Turbo JPEG DecompressHeader2 failed : %s", tjGetErrorStr());
+
+ __tjTransformHandle = tjInitTransform();
+ SysTryCatch(NID_MEDIA, __tjDecodingHandle != null, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] Turbo JPEG InitTransform failed : %s", tjGetErrorStr());
+
+ return E_SUCCESS;
+
+CATCH:
+ if ( __tjDecodingHandle )
+ tjDestroy(__tjDecodingHandle);
+ if ( __tjTransformHandle )
+ tjDestroy(__tjTransformHandle);
+ return r;
+}
+
+byte*
+_JpegTurboDecoder::DecodeN(int& outLength)
+{
+ int buffSize = 0;
+ int ret = 0;
+ int tjPixelFormat = 0;
+ byte* pTransBuf = null;
+ tjtransform cropInfo = {};
+ unsigned long dstSize;
+ std::unique_ptr<byte[]> pOutBuf;
+
+ buffSize = tjBufSize(__srcWidth, __srcHeight, TJSAMP_444);
+ SysTryReturn(NID_MEDIA, buffSize > 0, null, E_INVALID_DATA,
+ "[E_INVALID_DATA] Decoder returned buffer size (%d).", buffSize);
+
+ pOutBuf.reset(new (std::nothrow) byte[buffSize]);
+ SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes.", buffSize);
+
+ if ( __requestPixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888)
+ {
+ tjPixelFormat = TJPF_RGBA;
+ }
+ else
+ {
+ tjPixelFormat = TJPF_BGRA;
+ }
+ if (__isDecodeRegionEnabled == true)
+ {
+ cropInfo.r.x = __decodingRectX;
+ cropInfo.r.y = __decodingRectY;
+ cropInfo.r.w = __decodingRectWidth;
+ cropInfo.r.h = __decodingRectHeight;
+ cropInfo.op = TJXOP_NONE;
+ cropInfo.options = TJXOPT_CROP;
+
+ ret = tjTransform(__tjTransformHandle, __pSrcBuf,__srcBufSize, 1, &pTransBuf, &dstSize, &cropInfo, 0);
+ SysTryReturn(NID_MEDIA, ret == 0, null, E_INVALID_DATA,
+ "[E_INVALID_DATA] Turbo JPEG Crop Failed : %s", tjGetErrorStr());
+
+ ret = tjDecompress2(__tjDecodingHandle, pTransBuf, __srcBufSize, pOutBuf.get(), __decodingRectWidth, __decodingRectWidth* tjPixelSize[tjPixelFormat], __decodingRectHeight, tjPixelFormat, 0);
+ SysTryReturn(NID_MEDIA, ret == 0, null, E_INVALID_DATA,
+ "[E_INVALID_DATA] Turbo JPEG Decompress Failed : %s", tjGetErrorStr());
+
+ outLength = __decodingRectWidth * __decodingRectHeight * tjPixelSize[tjPixelFormat];
+ }
+ else
+ {
+ ret = tjDecompress2(__tjDecodingHandle, __pSrcBuf, __srcBufSize, pOutBuf.get(), __srcWidth, __srcWidth* tjPixelSize[tjPixelFormat], __srcHeight, tjPixelFormat, 0);
+ SysTryReturn(NID_MEDIA, ret == 0, null, E_INVALID_DATA,
+ "[E_INVALID_DATA] Turbo JPEG Decompress Failed : %s", tjGetErrorStr());
+ outLength = __srcWidth * __srcHeight * tjPixelSize[tjPixelFormat];
+ }
+
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+}
+
+result
+_JpegTurboDecoder::SetDecodingRegion(int x, int y, int width, int height)
+{
+ SysTryReturnResult(NID_MEDIA, ((x >= 0) && (y >= 0) && ((x + width) <= __srcWidth) && ((y + height) <= __srcHeight)),
+ E_INVALID_ARG,
+ "Invalid Input - Check dimensions and coordinates (x, y) = (%d, %d), width (%d), height (%d), Image dimensions (%d x %d)",
+ x, y, width, height, __srcWidth, __srcHeight);
+ SysTryReturnResult(NID_MEDIA, (!(x%tjMCUWidth[__subSamp]) && !(y%tjMCUHeight[__subSamp])), E_UNSUPPORTED_OPERATION,
+ "To crop this JPEG image using JpegTurbo decoder, x must be a multiple of %d and y must be a multiple of %d",
+ tjMCUWidth[__subSamp], tjMCUHeight[__subSamp]);
+ __decodingRectX = x;
+ __decodingRectY = y;
+ __decodingRectWidth = width;
+ __decodingRectHeight = height;
+ __isDecodeRegionEnabled = true;
+ return E_SUCCESS;
+}
+
+result
+_JpegTurboDecoder::GetDimension(int& width, int& height)
+{
+ width = __srcWidth;
+ height = __srcHeight;
+
+ return E_SUCCESS;
+}
+
+MediaPixelFormat
+_JpegTurboDecoder::GetPixelFormat(void)
+{
+ if ( __requestPixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888)
+ {
+ return MEDIA_PIXEL_FORMAT_RGBA8888;
+ }
+ else
+ {
+ return MEDIA_PIXEL_FORMAT_BGRA8888;
+ }
+}
+
+result
+_JpegTurboDecoder::SetScaleDown(int scaleDown)
+{
+ __scale = scaleDown;
+ return E_SUCCESS;
+}
+
+result
+_JpegTurboDecoder::GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+}} // Tizen::Media
+
--- /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_JpegTurboDecoder.h
+ * @brief This is header file for _JpegTurboDecoder.
+ */
+#ifndef _FMEDIA_INTERNAL_JPEG_TURBO_DECODER_H_
+#define _FMEDIA_INTERNAL_JPEG_TURBO_DECODER_H_
+
+#include "FMedia_IImageDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+class _JpegTurboDecoder
+ : public _IImageDecoder
+ , public Tizen::Base::Object
+{
+public:
+ static const int MAX_WIDTH = 5000;
+ static const int MAX_HEIGHT = 5000;
+ static const int MAX_SIZE = 4096000; // 4Mbyte
+
+ /**
+ * This is the default constructor for this class.
+ *
+ * @see Construct()
+ */
+ _JpegTurboDecoder(void);
+
+ /**
+ * This is the destructor for this class.
+ *
+ * @see Construct()
+ */
+ virtual ~_JpegTurboDecoder(void);
+
+ /**
+ * Constructs this instancce with given buffer and length.
+ *
+ * @return An error code
+ * @param[in] buffer The buffer that contains compressed data.
+ * @param[in] length The length of buffer.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual result Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat);
+
+ /**
+ * Decodes current frame and returns decoded data.
+ *
+ * @return A buffer pointer of decoded data
+ * @param[out] outLength The length of outBuf.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_DATA The data is invalid.
+ */
+ virtual byte* DecodeN(int& outLength);
+
+ /**
+ * Sets the decoding region. @n
+ *
+ * @return An error code
+ * @param[in] rect The decoding region.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetDecodingRegion(int x, int y, int width, int height);
+
+ /**
+ * Gets current dimension of image.
+ *
+ * @return An error code
+ * @param[out] width The width of image.
+ * @param[out] height The height of image.
+ * @param[out] pitch The pitch of image in bytes.
+ */
+ virtual result GetDimension(int& width, int& height);
+
+ /**
+ * Gets the output pixel format.
+ *
+ * @return The output pixel format.
+ */
+ virtual MediaPixelFormat GetPixelFormat(void);
+
+ /**
+ * Sets scale down degree.
+ *
+ * @return An error code
+ * @param[in] scaleDown The level of scale down.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetScaleDown(int scaleDown);
+
+ /**
+ * Gets the value of given key.
+ *
+ * @return An error code
+ * @param[in] key The key of the value.
+ * @param[out] value The output value.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+private:
+ _JpegTurboDecoder(const _JpegTurboDecoder&);
+ _JpegTurboDecoder& operator =(const _JpegTurboDecoder & __JpegTurboDecoder);
+
+ byte* __pSrcBuf;
+ int __srcBufSize;
+ int __srcWidth;
+ int __srcHeight;
+ int __scale;
+ int __subSamp;
+ int __decodingRectX;
+ int __decodingRectY;
+ int __decodingRectWidth;
+ int __decodingRectHeight;
+ bool __isDecodeRegionEnabled;
+ MediaPixelFormat __requestPixelFormat;
+ void* __tjDecodingHandle;
+ void* __tjTransformHandle;
+}; // class _JpegTurboDecoder
+
+
+};
+};
+
+#endif
--- /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_JpegTurboEncoder.cpp
+ * @brief This file contains the implementation of _JpegTurboEncoder class.
+ */
+
+#include <FBaseSysLog.h>
+#include <FMediaImageTypes.h>
+#include <unique_ptr.h>
+#include "FMedia_JpegTurboEncoder.h"
+
+using namespace Tizen::Base;
+
+namespace Tizen { namespace Media
+{
+
+typedef struct
+{
+ MediaPixelFormat mediaPixelFmt;
+ TJPF turboJpegFmt;
+}_TjpfFormatMap;
+
+static const _TjpfFormatMap _TJPF_MAP[]={
+ {MEDIA_PIXEL_FORMAT_RGB888, TJPF_RGB },
+ {MEDIA_PIXEL_FORMAT_BGR888, TJPF_BGR },
+ {MEDIA_PIXEL_FORMAT_RGBA8888, TJPF_RGBA},
+ {MEDIA_PIXEL_FORMAT_BGRA8888, TJPF_BGRA}
+};
+
+TJPF
+_JpegTurboEncoder::ToTurboJpegPixelFormat(MediaPixelFormat mediaPixelFmt)
+{
+ for (unsigned int i = 0; i < sizeof(_TJPF_MAP)/sizeof(_TJPF_MAP[0]); i++)
+ {
+ if (mediaPixelFmt == _TJPF_MAP[i].mediaPixelFmt)
+ {
+ return _TJPF_MAP[i].turboJpegFmt;
+ }
+ }
+ return TJPF_RGB;
+}
+
+_JpegTurboEncoder::_JpegTurboEncoder(void)
+{
+ __width = 0;
+ __height = 0;
+ __quality = 90;
+ __pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
+ __tjEncodingHandle = null;
+ __tjPixelFormat = TJPF_RGB;
+}
+
+_JpegTurboEncoder::~_JpegTurboEncoder(void)
+{
+ tjDestroy(__tjEncodingHandle);
+ __tjEncodingHandle = null;
+}
+
+result
+_JpegTurboEncoder::Construct(int width, int height,
+ MediaPixelFormat srcPixelFormat,
+ MediaPixelFormat& reqPixelFormat,
+ int quality)
+{
+ SysTryReturnResult(NID_MEDIA, width >= MIN_WIDTH, E_INVALID_ARG,
+ "Width (%d) should be greater than (%d)", width, MIN_WIDTH);
+ SysTryReturnResult(NID_MEDIA, height >= MIN_HEIGHT, E_INVALID_ARG,
+ "Height (%d) should be greater than (%d)", height, MIN_HEIGHT);
+ SysTryReturnResult(NID_MEDIA, quality > 0, E_INVALID_ARG,
+ "Quality (%d) should be greater than zero.", quality);
+ SysTryReturnResult(NID_MEDIA, quality <= 100, E_INVALID_ARG,
+ "Quality (%d) quality should be lesser than 100.", quality);
+
+ __width = width;
+ __height = height;
+ __quality = quality;
+
+ switch (srcPixelFormat)
+ {
+ case MEDIA_PIXEL_FORMAT_RGB888:
+ __pixelFormat = MEDIA_PIXEL_FORMAT_RGB888;
+ reqPixelFormat = MEDIA_PIXEL_FORMAT_RGB888;
+ break;
+
+ case MEDIA_PIXEL_FORMAT_BGR888:
+ __pixelFormat = MEDIA_PIXEL_FORMAT_BGR888;
+ reqPixelFormat = MEDIA_PIXEL_FORMAT_BGR888;
+ break;
+
+ case MEDIA_PIXEL_FORMAT_RGBA8888:
+ __pixelFormat = MEDIA_PIXEL_FORMAT_RGBA8888;
+ reqPixelFormat = MEDIA_PIXEL_FORMAT_RGBA8888;
+ break;
+
+ case MEDIA_PIXEL_FORMAT_BGRA8888:
+ __pixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888;
+ reqPixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888;
+ break;
+
+ default:
+ __pixelFormat = MEDIA_PIXEL_FORMAT_RGB888;
+ reqPixelFormat = MEDIA_PIXEL_FORMAT_RGB888;
+ break;
+ }
+ __tjEncodingHandle = tjInitCompress();
+ SysTryReturnResult(NID_MEDIA, __tjEncodingHandle != null, E_OUT_OF_MEMORY, "Turbo JPEG Initcompress faild : %s", tjGetErrorStr());
+
+ return E_SUCCESS;
+}
+
+
+Tizen::Base::ByteBuffer*
+_JpegTurboEncoder::EncodeN(const byte* srcBuf, int srcLength)
+{
+ result r = E_SUCCESS;
+ int ret = 0;
+ unsigned long outSize = 0;
+
+ byte* pOutBuf = null;
+ std::unique_ptr<ByteBuffer> pRetBuf (new (std::nothrow) ByteBuffer);
+ SysTryCatch(NID_MEDIA, pRetBuf.get() != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] size=%d", outSize);
+
+ outSize=tjBufSize(__width, __height, TJSAMP_420);
+ SysTryCatch(NID_MEDIA, (long)outSize > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Get buffer size failed.");
+
+ pOutBuf = tjAlloc(outSize);
+ __tjPixelFormat = ToTurboJpegPixelFormat(__pixelFormat);
+ ret = tjCompress2(__tjEncodingHandle, (byte*)srcBuf, __width, __width*tjPixelSize[__tjPixelFormat],
+ __height, __tjPixelFormat, &pOutBuf, &outSize, TJSAMP_420, __quality, 0);
+ SysTryCatch(NID_MEDIA, ret == 0, r = E_OPERATION_FAILED, E_OPERATION_FAILED, "Turbo JPEG Compress Failed : %s", tjGetErrorStr());
+
+ r = pRetBuf->Construct(outSize);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated. size=%d", GetErrorMessage(r), outSize);
+
+ r = pRetBuf->SetArray(pOutBuf, 0, outSize);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated.", GetErrorMessage(r));
+
+ pRetBuf->Flip();
+ tjFree(pOutBuf);
+
+ return pRetBuf.release();
+
+CATCH:
+ if (pOutBuf)
+ {
+ tjFree(pOutBuf);
+ }
+ return null;
+}
+
+result
+_JpegTurboEncoder::SetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+}} // Tizen::Media
--- /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_JpegTurboEncoder.h
+ * @brief This is header file for _JpegTurboEnecoder.
+ */
+
+#ifndef _FMEDIA_INTERNAL_JPEG_TURBO_ENCODER_H_
+#define _FMEDIA_INTERNAL_JPEG_TURBO_ENCODER_H_
+
+#include <turbojpeg.h>
+#include "FMedia_IImageEncoder.h"
+namespace Tizen { namespace Media
+{
+
+class _JpegTurboEncoder
+ : public _IImageEncoder
+ , public Tizen::Base::Object
+{
+public:
+ static const int MIN_WIDTH = 16;
+ static const int MIN_HEIGHT = 16;
+ static const int MAX_WIDTH = 5000;
+ static const int MAX_HEIGHT = 5000;
+
+ /**
+ * This is the default constructor for this class.
+ *
+ * @see Construct()
+ */
+ _JpegTurboEncoder(void);
+
+ /**
+ * This is the destructor for this class.
+ *
+ * @see Construct()
+ */
+ virtual ~_JpegTurboEncoder(void);
+
+ /**
+ * Initialize this instance.
+ * @param[in] dim Encode dimension
+ * @param[in] pixelFormat Encode pixel format
+ * @param[in] quality Encoding quality
+ */
+ virtual result Construct(int width, int height,
+ MediaPixelFormat srcPixelFormat,
+ MediaPixelFormat& reqPixelFormat,
+ int quality);
+
+ /**
+ * Encodes the image data
+ *
+ * @return An error code
+ * @param[in] srcBuf Source raw data
+ * @param[in] srcLength Source data length
+ * @param[out] dstBuf Encoded destination buffer
+ * @param[out] dstLength Destination buffer length
+ *
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual Tizen::Base::ByteBuffer* EncodeN(const byte* srcBuf, int srcLength);
+
+ /**
+ * Set specific key value to the encoder
+ * @return An error code
+ * @param[in] key The key to be set
+ * @param[in] value The value to be set.
+ */
+ virtual result SetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+ TJPF ToTurboJpegPixelFormat(MediaPixelFormat mediaPixelFmt);
+protected:
+
+
+private:
+ int __width;
+ int __height;
+ int __quality;
+ MediaPixelFormat __pixelFormat;
+ tjhandle __tjEncodingHandle;
+ TJPF __tjPixelFormat;
+}; // class _JpegTurboEncoder
+
+
+};
+};
+
+#endif
--- /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_Util.cpp
+ * @brief This file contains the utility APIs of Media namespace.
+ */
+
+#include <limits.h>
+#include <unique_ptr.h>
+#include <FBaseSysLog.h>
+#include <FIoFile.h>
+#include "FMedia_MediaUtil.h"
+
+using namespace Tizen::Base;
+using namespace Tizen::Io;
+
+namespace Tizen { namespace Media {
+
+Tizen::Base::ByteBuffer*
+_MediaUtil::FileToBufferN(const Tizen::Base::String &path, int maxSize)
+{
+ File file;
+ std::unique_ptr<ByteBuffer> pBuf;
+ result r = E_SUCCESS;
+ int size = 0;
+
+ SysTryReturn(NID_MEDIA, !path.IsEmpty(), null, E_FILE_NOT_FOUND,
+ "[E_FILE_NOT_FOUND] path is empty");
+ SysTryReturn(NID_MEDIA, path.GetLength() > 0 && path.GetLength() <= PATH_MAX, null, E_INVALID_ARG,
+ "[E_INVALID_ARG] Given filePath length is zero or exceeds system limitations.");
+ SysTryReturn(NID_MEDIA, File::IsFileExist(path), null, E_FILE_NOT_FOUND,
+ "[E_FILE_NOT_FOUND] filePath:%ls", path.GetPointer());
+
+ r = file.Construct(path, L"rb");
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r,
+ "[%s] file.Construct failed. File name (%ls)", GetErrorMessage(r), path.GetPointer());
+
+ file.Seek(FILESEEKPOSITION_END, 0);
+ size = file.Tell();
+ file.Seek(FILESEEKPOSITION_BEGIN, 0);
+
+ SysTryReturn(NID_MEDIA, size > 0, null, E_DATA_NOT_FOUND,
+ "[E_DATA_NOT_FOUND] File size is 0: %ls", path.GetPointer());
+
+ pBuf.reset(new (std::nothrow) ByteBuffer());
+ SysTryReturn(NID_MEDIA, pBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Failed to create new ByteBuffer.");
+
+ if (maxSize == 0 || size <= maxSize) // read whole data
+ {
+ r = pBuf->Construct(size);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ByteBuffer Construct failed for %d bytes.",
+ GetErrorMessage(r), size);
+
+ r = file.Read(*pBuf.get());
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. File.Read failed: %ls",
+ GetErrorMessage(r), path.GetPointer());
+ }
+ else
+ {
+ r = pBuf->Construct(maxSize);
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ByteBuffer Construct failed for %d bytes.",
+ GetErrorMessage(r), maxSize);
+
+ r = file.Read(*pBuf.get());
+ SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. File.Read failed: %ls",
+ GetErrorMessage(r), path.GetPointer());
+ }
+
+ pBuf->Flip();
+
+ SetLastResult(E_SUCCESS);
+ return pBuf.release();
+}
+
+result
+_MediaUtil::BufferToFile(const Tizen::Base::ByteBuffer &srcBuf,
+ const Tizen::Base::String &dstPath, bool overwrite)
+{
+ File file;
+ result r = E_SUCCESS;
+
+ // Check file exist
+ if (File::IsFileExist(dstPath))
+ {
+ if (overwrite)
+ {
+ File::Remove(dstPath);
+ }
+ else
+ {
+ return E_FILE_ALREADY_EXIST;
+ }
+ }
+
+ r = file.Construct(dstPath, "wb", true);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated. File.Construct failed for %ls",
+ GetErrorMessage(r), dstPath.GetPointer());
+ r = file.Write(srcBuf);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated. File.Write failed for %ls",
+ GetErrorMessage(r), dstPath.GetPointer());
+
+CATCH:
+ return r;
+}
+
+}} // Tizen::Media
--- /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_PngDecoder.cpp
+ * @brief This file contains the implementation of _PngDecoder class.
+ */
+
+#include <unique_ptr.h>
+#include <FBaseSysLog.h>
+#include <FMediaImageTypes.h>
+#include "FMedia_PngDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+void
+_PngDecoder::PngReadDataStatic(struct png_struct_def* pngPtr, png_bytep data, png_size_t length)
+{
+ _PngDecoder *pDec = (_PngDecoder*) (pngPtr->io_ptr);
+ if (pDec)
+ {
+ pDec->PngReadData(pngPtr, data, length);
+ }
+}
+
+
+_PngDecoder::_PngDecoder(void)
+{
+ __pBuf = null;
+ __curPos = 0;
+ __bufSize = 0;
+ __srcWidth = 0;
+ __srcHeight = 0;
+ //__decodingRect.SetBounds(0, 0, 0, 0);
+ __scale = 0;
+ __decodingRectX = 0;
+ __decodingRectY = 0;
+ __decodingRectWidth = 0;
+ __decodingRectHeight = 0;
+ __isDecodeRegionEnabled = false;
+ __format = MEDIA_PIXEL_FORMAT_NONE;
+ __pPng = NULL;
+ __pInfo = NULL;
+}
+
+_PngDecoder::~_PngDecoder(void)
+{
+ if (__pPng)
+ {
+ if (setjmp(png_jmpbuf(__pPng)))
+ {
+ return;
+ }
+
+ if (__pInfo)
+ {
+ png_destroy_read_struct(&__pPng, &__pInfo, (png_infopp) NULL);
+ }
+ else
+ {
+ png_destroy_read_struct(&__pPng, (png_infopp) NULL, (png_infopp) NULL);
+ }
+ }
+}
+
+result
+_PngDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturnResult(NID_MEDIA, __pPng == null, E_INVALID_STATE, "Already constructed");
+
+ __pBuf = (byte*)buffer;
+ SysTryCatch(NID_MEDIA, __pBuf != null && length > 0, r = E_INVALID_ARG, E_INVALID_ARG,
+ "[E_INVALID_ARG] buffer = 0x%x, length = %d", buffer, length);
+
+ __curPos = 0;
+ __bufSize = length;
+
+ // Check png file
+ __pPng = png_create_read_struct(PNG_LIBPNG_VER_STRING, null, null, null);
+ SysTryCatch(NID_MEDIA, __pPng != null, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] png_create failed.");
+
+ SysTryCatch(NID_MEDIA, !setjmp(png_jmpbuf(__pPng)), r = E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] setjmp failed.");
+
+ // Initialize info struct
+ __pInfo = png_create_info_struct(__pPng);
+ SysTryCatch(NID_MEDIA, __pInfo != null, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] png_create_info failed");
+ // Set buffer read function
+ png_set_read_fn(__pPng, (png_voidp)this, PngReadDataStatic);
+
+ // __pInfo filled out.
+ png_read_info(__pPng, __pInfo);
+
+ __srcWidth = png_get_image_width(__pPng, __pInfo);
+ __srcHeight = png_get_image_height(__pPng, __pInfo);
+
+ return E_SUCCESS;
+
+CATCH:
+ if (__pPng)
+ {
+ if (__pInfo)
+ {
+ png_destroy_read_struct(&__pPng, &__pInfo, (png_infopp)null);
+ __pInfo = null;
+ }
+ else
+ {
+ png_destroy_read_struct(&__pPng, (png_infopp)null, (png_infopp)null);
+ }
+ __pPng = null;
+ }
+ return r;
+}
+
+byte*
+_PngDecoder::DecodeN(int& outLength)
+{
+ result r = E_SUCCESS;
+ png_uint_32 bitDepth = 0;
+ png_uint_32 colorType = 0;
+ png_uint_32 channels = 0;
+ png_uint_32 rowBytes = 0;
+ png_uint_32 bytesPerPixel = 0;
+ int interlaceCount = 0 ;
+
+ double gamma = 0.0;
+ std::unique_ptr<byte[]> pOutBuf;
+ std::unique_ptr<png_bytep []> ppRows;
+
+
+ SysTryReturn(NID_MEDIA, !setjmp(png_jmpbuf(__pPng)), null, E_INVALID_DATA,
+ "[E_INVALID_DATA] setjmp");
+
+ bitDepth = png_get_bit_depth(__pPng, __pInfo);
+ colorType = png_get_color_type(__pPng, __pInfo);
+
+ if (bitDepth == 16)
+ {
+ png_set_strip_16(__pPng);
+ }
+ if (colorType == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_set_expand(__pPng);
+ }
+ if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)
+ {
+ png_set_expand(__pPng);
+ }
+ if (png_get_valid(__pPng, __pInfo, PNG_INFO_tRNS))
+ {
+ png_set_expand(__pPng);
+ }
+ if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ png_set_gray_to_rgb(__pPng);
+ }
+ if (png_get_gAMA(__pPng, __pInfo, &gamma))
+ {
+ png_set_gamma(__pPng, (double) 2.2, gamma);
+ }
+ /*
+ if (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_GRAY)
+ {
+ // png_set_filler(__pPng, 0xff, PNG_FILLER_AFTER);
+ }
+ */
+ png_set_add_alpha(__pPng, 0xff, PNG_FILLER_AFTER);
+ // Update __pInfo
+ png_read_update_info(__pPng, __pInfo);
+
+ rowBytes = png_get_rowbytes(__pPng, __pInfo);
+ channels = png_get_channels(__pPng, __pInfo);
+ // If has alpha, out pixel format change RGB(or RGBA) -> BGR(or BGRA)
+ if (channels >= 4)
+ {
+ png_set_bgr(__pPng);
+ }
+
+ // Create row pointers.
+ ppRows = std::unique_ptr<png_bytep []> (new (std::nothrow) png_bytep[__srcHeight]);
+ SysTryReturn(NID_MEDIA, ppRows.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate new png_bytep[%d]", __srcHeight);
+ memset(ppRows.get(), 0, __srcHeight * sizeof(png_bytep));
+
+ bytesPerPixel = bitDepth * channels; // total bit per pixel
+ bytesPerPixel = bytesPerPixel >> 3;
+
+ // this is needed only in case of Image Region Decoding
+ interlaceCount = png_set_interlace_handling(__pPng);
+ if (__isDecodeRegionEnabled && interlaceCount == 1)
+ {
+ outLength = rowBytes * __decodingRectHeight;
+ }
+ else
+ {
+ outLength = rowBytes * __srcHeight;
+ }
+ pOutBuf.reset(new (std::nothrow) byte[outLength]);
+ SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate new byte[%d]", outLength);
+ // Set output pointer
+ if (__isDecodeRegionEnabled)
+ {
+ unsigned char *pRegionBuffer = null;
+ // reuse the buffer, change only the size after the media format conversion the whole memory will be deleted
+ // so there will be no memory leak
+ outLength = __decodingRectHeight * __decodingRectWidth * bytesPerPixel;
+ pRegionBuffer = pOutBuf.get();
+ if (interlaceCount > 1)
+ {
+ //if interlaceCount is greater than 1 then 7 passes are involved so its best
+ //to decode the whole image and pick the decoded region
+ for (int row = 0; row < __srcHeight; row++)
+ {
+ ppRows[row] = (png_bytep) pOutBuf.get() + (rowBytes * row);
+ }
+ png_read_image(__pPng, ppRows.get());
+ png_read_end(__pPng, __pInfo);
+ for (int row = __decodingRectY; row < __decodingRectY + __decodingRectHeight; row++)
+ {
+ memcpy(pRegionBuffer, ppRows[row] + (__decodingRectX * bytesPerPixel), __decodingRectWidth * bytesPerPixel);
+ pRegionBuffer = pRegionBuffer + (__decodingRectWidth * bytesPerPixel);
+ }
+ }
+ else
+ {
+ for (int row = 0; row < __decodingRectY + __decodingRectHeight; row++)
+ {
+ if (row < __decodingRectY)
+ {
+ ppRows[row] = (png_bytep) pOutBuf.get();
+ }
+ else
+ {
+ ppRows[row] = (png_bytep) pOutBuf.get() + (rowBytes * (row - __decodingRectY));
+ }
+ png_read_rows(__pPng, &ppRows[row], NULL, 1);
+ }
+ for (int row = __decodingRectY; row < __decodingRectY + __decodingRectHeight; row++)
+ {
+ memcpy(pRegionBuffer, ppRows[row] + (__decodingRectX * bytesPerPixel), __decodingRectWidth * bytesPerPixel);
+ pRegionBuffer = pRegionBuffer + (__decodingRectWidth * bytesPerPixel);
+ }
+ }
+ //png_read_end(__pPng, null);
+ }
+ else
+ {
+ for (int row = 0; row < __srcHeight; row++)
+ {
+ ppRows[row] = (png_bytep) pOutBuf.get() + (rowBytes * row);
+ }
+ // read image
+ png_read_image(__pPng, ppRows.get());
+ png_read_end(__pPng, __pInfo);
+ }
+
+ if (channels >= 4)
+ {
+ __format = MEDIA_PIXEL_FORMAT_BGRA8888;
+ }
+ else
+ {
+ __format = MEDIA_PIXEL_FORMAT_RGB888;
+ }
+
+ SetLastResult(r);
+ return pOutBuf.release();
+}
+
+
+void
+_PngDecoder::PngReadData(void* pPng, byte* data, int length)
+{
+ result r = E_SUCCESS;
+
+ SysTryCatch(NID_MEDIA, __curPos + length <= __bufSize, r = E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] Underflow: Requested data is beyond buffer size (%d + %d) > %d",
+ __curPos, length, __bufSize);
+
+ memcpy(data, __pBuf + __curPos, length);
+ __curPos += length;
+
+ return;
+
+CATCH:
+ png_error((struct png_struct_def*)pPng, "read error");
+ return;
+}
+
+result
+_PngDecoder::SetDecodingRegion(int x, int y, int width, int height)
+{
+ SysTryReturnResult(NID_MEDIA, ((x >= 0) && (y >= 0) && ((x + width) <= __srcWidth) && ((y + height) <= __srcHeight)), E_INVALID_ARG,
+ "Check coordinates (%d, %d) and dimensions (%d x %d), wrto image size (%d x %d)",
+ x, y, width, height, __srcWidth, __srcHeight);
+ __decodingRectX = x;
+ __decodingRectY = y;
+ __decodingRectWidth = width;
+ __decodingRectHeight = height;
+ __isDecodeRegionEnabled = true;
+ return E_SUCCESS;
+}
+
+result
+_PngDecoder::GetDimension(int& width, int& height)
+{
+ width = __srcWidth;
+ height = __srcHeight;
+
+ return E_SUCCESS;
+}
+
+MediaPixelFormat
+_PngDecoder::GetPixelFormat(void)
+{
+ return __format;
+}
+
+result
+_PngDecoder::SetScaleDown(int scaleDown)
+{
+ __scale = scaleDown;
+ return E_SUCCESS;
+}
+
+result
+_PngDecoder::GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+}}
--- /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_PngDecoder.h
+ * @brief This is header file for _PngDecoder.
+ */
+#ifndef _FMEDIA_INTERNAL_PNG_DECODER_H_
+#define _FMEDIA_INTERNAL_PNG_DECODER_H_
+
+#include <png.h>
+#include "FMedia_IImageDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+class _PngDecoder
+ : public _IImageDecoder
+ , public Tizen::Base::Object
+{
+public:
+
+ static const int MAX_WIDTH = 5000;
+ static const int MAX_HEIGHT = 5000;
+ static const int MAX_SIZE = 4096000; // 4Mbyte
+
+ _PngDecoder(void);
+ virtual ~_PngDecoder(void);
+
+ /**
+ * Constructs this instancce with given buffer and length.
+ *
+ * @return An error code
+ * @param[in] buffer The buffer that contains compressed data.
+ * @param[in] length The length of buffer.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual result Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat);
+
+ /**
+ * Decodes current frame and returns decoded data.
+ *
+ * @return A buffer pointer of decoded data
+ * @param[out] outLength The length of outBuf.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_DATA The data is invalid.
+ */
+ virtual byte* DecodeN(int& outLength);
+
+ /**
+ * Sets the decoding region. @n
+ *
+ * @return An error code
+ * @param[in] rect The decoding region.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetDecodingRegion(int x, int y, int width, int height);
+
+ /**
+ * Gets current dimension of image.
+ *
+ * @return An error code
+ * @param[out] width The width of image.
+ * @param[out] height The height of image.
+ */
+ virtual result GetDimension(int& width, int& height);
+
+ /**
+ * Gets the output pixel format.
+ *
+ * @return The output pixel format.
+ */
+ virtual MediaPixelFormat GetPixelFormat(void);
+
+ /**
+ * Sets scale down degree.
+ *
+ * @return An error code
+ * @param[in] scaleDown The level of scale down.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetScaleDown(int scaleDown);
+
+ /**
+ * Gets the value of given key.
+ *
+ * @return An error code
+ * @param[in] key The key of the value.
+ * @param[out] value The output value.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+ void PngReadData(void *pngPtr, byte* data, int size);
+
+ static void PngReadDataStatic(struct png_struct_def* pngPtr, png_bytep data, png_size_t length);
+protected:
+
+
+private:
+ byte* __pBuf;
+ unsigned int __curPos;
+ unsigned int __bufSize;
+
+ struct png_struct_def* __pPng;
+ struct png_info_struct* __pInfo;
+
+ int __srcWidth;
+ int __srcHeight;
+ int __scale;
+ int __decodingRectX;
+ int __decodingRectY;
+ int __decodingRectWidth;
+ int __decodingRectHeight;
+ bool __isDecodeRegionEnabled;
+ MediaPixelFormat __format;
+
+}; // class _PngDecoder
+
+};
+};
+#endif
--- /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_PngEncoder.cpp
+ * @brief This file contains the implementation of _PngEncoder class.
+ */
+
+#include <stdlib.h>
+#include <unique_ptr.h>
+#include <FMediaImageTypes.h>
+#include <FBaseSysLog.h>
+#include "FMedia_PngEncoder.h"
+
+using namespace Tizen::Base;
+
+namespace Tizen { namespace Media
+{
+
+
+void
+_PngEncoder::PngWriteDataStatic(struct png_struct_def* pngPtr, png_bytep data, png_size_t length)
+{
+ ByteBuffer *pBuf = (ByteBuffer*)pngPtr->io_ptr;
+ result r = E_SUCCESS;
+
+ SysTryCatch(NID_MEDIA, pBuf != null, , E_SYSTEM,
+ "[E_SYSTEM] PngWriteData pointer is null");
+
+ if (length > (unsigned int)pBuf->GetRemaining())
+ {
+ r = pBuf->ExpandCapacity(pBuf->GetCapacity()+length);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
+ "[%s] ByteBuffer.ExpandCapacity: from %d by %d bytes failed.",
+ GetErrorMessage(r), pBuf->GetCapacity(), length);
+ }
+
+ r = pBuf->SetArray(data, 0, length);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
+ "[%s] ByteBuffer.SetArray failed for buffer (%x) and length %d",
+ GetErrorMessage(r), data, length);
+
+ return;
+
+CATCH:
+ png_error((struct png_struct_def*)pngPtr, "Write Error");
+ return;
+}
+
+void
+_PngEncoder::PngFlushDataStatic(struct png_struct_def* pngPtr)
+{
+}
+
+_PngEncoder::_PngEncoder(void)
+{
+ __pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
+ __quality = 90;
+ __width = 0;
+ __height = 0;
+}
+
+_PngEncoder::~_PngEncoder(void)
+{
+
+}
+
+result
+_PngEncoder::Construct(int width, int height,
+ MediaPixelFormat srcPixelFormat,
+ MediaPixelFormat& reqPixelFormat,
+ int quality)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturnResult(NID_MEDIA, width >= MIN_WIDTH, E_INVALID_ARG,
+ "Width (%d) should be greater than (%d)", width, MIN_WIDTH);
+ SysTryReturnResult(NID_MEDIA, height >= MIN_HEIGHT, E_INVALID_ARG,
+ "Height (%d) should be greater than (%d)", width, MIN_WIDTH);
+ SysTryReturnResult(NID_MEDIA, quality > 0, E_INVALID_ARG,
+ "Quality (%d) should be greater than zero.", quality);
+ SysTryReturnResult(NID_MEDIA, quality <= 100, E_INVALID_ARG,
+ "Quality (%d) quality should be lesser than 100.", quality);
+
+ __width = width;
+ __height = height;
+ __quality = quality;
+ if (srcPixelFormat == MEDIA_PIXEL_FORMAT_RGBA8888)
+ {
+ __pixelFormat = MEDIA_PIXEL_FORMAT_RGBA8888;
+ reqPixelFormat = MEDIA_PIXEL_FORMAT_RGBA8888;
+ }
+ else if (srcPixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888)
+ {
+ __pixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888;
+ reqPixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888;
+ }
+ else
+ {
+ __pixelFormat = MEDIA_PIXEL_FORMAT_RGBA8888;
+ reqPixelFormat = MEDIA_PIXEL_FORMAT_RGBA8888;
+ }
+ __quality = quality;
+
+ return r;
+}
+
+Tizen::Base::ByteBuffer*
+_PngEncoder::EncodeN(const byte* srcBuf, int srcLength)
+{
+ result r = E_SUCCESS;
+ struct png_struct_def* png = null;
+ png_infop info = null;
+ png_uint_32 bytesPerRow = 0;
+ png_bytepp ppRows = null;
+ png_color_8_struct sigBit;
+ int bytePerPixel = 4; // Fixed. Source format is always RGBA8888 through ColorConverter.
+ std::unique_ptr<ByteBuffer> pRetBuf;
+
+ 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] Failed to create new ByteBuffer");
+
+ r = pRetBuf->Construct(MIN_BUF_SIZE);
+ SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r,
+ "[%s] Propagated. Failed in ByteBuffer Construct for size %d", GetErrorMessage(r), MIN_BUF_SIZE);
+
+ png = png_create_write_struct(PNG_LIBPNG_VER_STRING, null, null, null);
+ SysTryCatch(NID_MEDIA, png != null, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] png_create failed");
+
+ // TODO: add error handling code : setjump()
+ SysTryCatch(NID_MEDIA, !setjmp(png_jmpbuf(png)), r = E_INVALID_DATA, E_INVALID_DATA,
+ "[E_INVALID_DATA] setjmp");
+
+ info = png_create_info_struct(png);
+ SysTryCatch(NID_MEDIA, info != null, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] png_create_info failed");
+
+ // Redirect write func.
+ png_set_write_fn(png, pRetBuf.get(), PngWriteDataStatic, PngFlushDataStatic);
+
+ png_set_IHDR(png, info, __width, __height, 8, PNG_COLOR_TYPE_RGBA,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+ sigBit.red = 8;
+ sigBit.green = 8;
+ sigBit.blue = 8;
+ sigBit.alpha = 8;
+ sigBit.gray = 0;
+
+ png_set_sBIT(png, info, &sigBit);
+
+ if (__quality > 50)
+ {
+ png_set_compression_level(png, Z_BEST_SPEED);
+ }
+ else
+ {
+ png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_SUB);
+ png_set_compression_level(png, Z_BEST_SPEED);
+ }
+ png_set_compression_strategy(png, Z_RLE);
+
+ //write the png header
+ png_write_info(png, info);
+
+ if (__pixelFormat == MEDIA_PIXEL_FORMAT_BGRA8888)
+ png_set_bgr(png);
+
+ // Initialize rows of PNG.
+ bytesPerRow = __width * bytePerPixel;
+ ppRows = new (std::nothrow) png_bytep[__height];
+ SysTryCatch(NID_MEDIA, ppRows != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Failed to create new png_bytep[%d]", __height);
+
+ ppRows[0] = (byte*)srcBuf;
+ for (int y = 1; y < __height; y++)
+ {
+ ppRows[y] = ppRows[y-1] + bytesPerRow;
+ }
+
+ // Actually write the image data.
+ png_write_image(png, ppRows);
+ png_write_end(png, info);
+
+ if (ppRows)
+ {
+ delete[] ppRows;
+ ppRows = null;
+ }
+
+ // Finish writing.
+ png_destroy_write_struct(&png, &info);
+
+ pRetBuf->Flip();
+
+ SysTryCatch(NID_MEDIA, pRetBuf->GetLimit() > 0, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] buf.Limit is %d", pRetBuf->GetLimit());
+
+ return pRetBuf.release();
+
+CATCH:
+ if (png)
+ {
+ if (info)
+ {
+ png_destroy_write_struct(&png, &info);
+ }
+ else
+ {
+ png_destroy_write_struct(&png, (png_infopp)null);
+ }
+ }
+ return null;
+}
+
+result
+_PngEncoder::SetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+}} // Tizen::Media
--- /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_PngEncoder.h
+ * @brief This is header file for _PngEncoder.
+ */
+#ifndef _FMEDIA_INTERNAL_PNG_ENCODER_H_
+#define _FMEDIA_INTERNAL_PNG_ENCODER_H_
+
+#include "FMedia_IImageEncoder.h"
+#include <png.h>
+
+namespace Tizen { namespace Media
+{
+
+class _PngEncoder
+ : public _IImageEncoder
+ , public Tizen::Base::Object
+{
+public:
+ static const int MIN_WIDTH = 8;
+ static const int MIN_HEIGHT = 8;
+ static const int MIN_BUF_SIZE = 67;
+ /**
+ * This is the default constructor for this class.
+ *
+ * @see Construct()
+ */
+ _PngEncoder(void);
+
+ /**
+ * This is the destructor for this class.
+ *
+ * @see Construct()
+ */
+ virtual ~_PngEncoder(void);
+
+ /**
+ * Initialize this instance.
+ * @param[in] dim Encode dimension
+ * @param[in] pixelFormat Encode pixel format
+ * @param[in] quality Encoding quality
+ */
+ virtual result Construct(int width, int height,
+ MediaPixelFormat srcPixelFormat,
+ MediaPixelFormat& reqPixelFormat,
+ int quality);
+
+ /**
+ * Encodes the image data
+ *
+ * @return An error code
+ * @param[in] srcBuf Source raw data
+ * @param[in] srcLength Source data length
+ * @param[out] dstBuf Encoded destination buffer
+ * @param[out] dstLength Destination buffer length
+ *
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual Tizen::Base::ByteBuffer* EncodeN(const byte* srcBuf, int srcLength);
+
+ /**
+ * Set specific key value to the encoder
+ * @return An error code
+ * @param[in] key The key to be set
+ * @param[in] value The value to be set.
+ */
+ virtual result SetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+
+ static void PngWriteDataStatic(struct png_struct_def* pngPtr, png_bytep data, png_size_t length);
+
+ static void PngFlushDataStatic(struct png_struct_def* pngPtr);
+
+private:
+ int __width;
+ int __height;
+ int __quality;
+ MediaPixelFormat __pixelFormat;
+
+}; // class _PngEncoder
+
+
+};
+};
+
+#endif
--- /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_SlpUtil.cpp
+ * @brief This file contains the implementation of _SlpUtil class.
+ */
+
+#include <stdlib.h>
+#include <image_util.h>
+#include <mmf/mm_util_imgp.h>
+#include <FBaseSysLog.h>
+#include <FMediaImageTypes.h>
+#include "FMedia_MediaUtil.h"
+#include "FMedia_SlpUtil.h"
+
+using namespace Tizen::Base;
+using namespace Tizen::Io;
+
+namespace Tizen { namespace Media
+{
+//
+//image_util_colorspace_e
+//_SlpUtil::ToColorspace(Tizen::Graphics::BitmapPixelFormat pixelFormat)
+//{
+// static struct {
+// BitmapPixelFormat key;
+// image_util_colorspace_e value;
+// } map[] = {
+// { BITMAP_PIXEL_FORMAT_RGB565, IMAGE_UTIL_COLORSPACE_RGB565 },
+// { BITMAP_PIXEL_FORMAT_ARGB8888, IMAGE_UTIL_COLORSPACE_BGRA8888 },
+// { BITMAP_PIXEL_FORMAT_R8G8B8A8, IMAGE_UTIL_COLORSPACE_RGBA8888 },
+// };
+// image_util_colorspace_e ret = (image_util_colorspace_e)0xff;
+//
+// SAFE_FIND_KEY(ret, map, pixelFormat);
+//
+// return ret;
+//}
+//
+
+image_util_colorspace_e
+_SlpUtil::ToColorspace(MediaPixelFormat pixelFormat)
+{
+ static struct
+ {
+ MediaPixelFormat key;
+ image_util_colorspace_e value;
+ } map[] = {
+ { MEDIA_PIXEL_FORMAT_RGB565LE, IMAGE_UTIL_COLORSPACE_RGB565 },
+ { MEDIA_PIXEL_FORMAT_BGRA8888, IMAGE_UTIL_COLORSPACE_BGRA8888 },
+ { MEDIA_PIXEL_FORMAT_RGBA8888, IMAGE_UTIL_COLORSPACE_RGBA8888 },
+ { MEDIA_PIXEL_FORMAT_RGB565BE, IMAGE_UTIL_COLORSPACE_RGB565 }, // slp does not support
+ { MEDIA_PIXEL_FORMAT_RGB888, IMAGE_UTIL_COLORSPACE_RGB888 },
+ { MEDIA_PIXEL_FORMAT_BGR888, IMAGE_UTIL_COLORSPACE_RGB888 }, // slp does not support
+ { MEDIA_PIXEL_FORMAT_YUV420P, IMAGE_UTIL_COLORSPACE_YV12 },
+ { MEDIA_PIXEL_FORMAT_YUYV422, IMAGE_UTIL_COLORSPACE_YUYV },
+ { MEDIA_PIXEL_FORMAT_NV12, IMAGE_UTIL_COLORSPACE_NV12 },
+ };
+ image_util_colorspace_e ret = (image_util_colorspace_e)0xff;
+
+ for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
+ {
+ if (map[i].key == pixelFormat)
+ {
+ return map[i].value;
+ }
+ }
+
+ return ret;
+}
+
+image_util_rotation_e
+_SlpUtil::ToRotation(ImageRotationType type)
+{
+ static struct
+ {
+ ImageRotationType key;
+ image_util_rotation_e value;
+ } map[] = {
+ { IMAGE_ROTATION_90, IMAGE_UTIL_ROTATION_90 },
+ { IMAGE_ROTATION_180, IMAGE_UTIL_ROTATION_180 },
+ { IMAGE_ROTATION_270, IMAGE_UTIL_ROTATION_270 },
+ { IMAGE_ROTATION_0, IMAGE_UTIL_ROTATION_FLIP_HORZ },
+ };
+ image_util_rotation_e ret = (image_util_rotation_e)0xff;
+
+ for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
+ {
+ if (map[i].key == type)
+ {
+ return map[i].value;
+ }
+ }
+ return ret;
+}
+
+image_util_rotation_e
+_SlpUtil::ToRotation(ImageFlipType type)
+{
+ static struct
+ {
+ ImageFlipType key;
+ image_util_rotation_e value;
+ } map[] = {
+ {IMAGE_FLIP_HORIZONTAL, IMAGE_UTIL_ROTATION_FLIP_HORZ },
+ {IMAGE_FLIP_VERTICAL, IMAGE_UTIL_ROTATION_FLIP_VERT }
+ };
+ image_util_rotation_e ret = (image_util_rotation_e)0xff;
+
+ for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
+ {
+ if (map[i].key == type)
+ {
+ return map[i].value;
+ }
+ }
+ return ret;
+}
+
+mm_util_img_format
+_SlpUtil::ToMmUtilImgFormat(Tizen::Media::MediaPixelFormat pixelFormat)
+{
+ static struct
+ {
+ MediaPixelFormat key;
+ mm_util_img_format value;
+ } map[] = {
+ { MEDIA_PIXEL_FORMAT_RGB565LE, MM_UTIL_IMG_FMT_RGB565 },
+ { MEDIA_PIXEL_FORMAT_BGRA8888, MM_UTIL_IMG_FMT_BGRA8888 },
+ { MEDIA_PIXEL_FORMAT_RGBA8888, MM_UTIL_IMG_FMT_ARGB8888 },
+ { MEDIA_PIXEL_FORMAT_RGB565BE, MM_UTIL_IMG_FMT_RGB565 }, // slp does not support
+ { MEDIA_PIXEL_FORMAT_RGB888, MM_UTIL_IMG_FMT_RGB888 },
+ { MEDIA_PIXEL_FORMAT_BGR888, MM_UTIL_IMG_FMT_RGB888 }, // slp does not support
+ { MEDIA_PIXEL_FORMAT_YUV420P, MM_UTIL_IMG_FMT_YUV420 },
+ { MEDIA_PIXEL_FORMAT_YUYV422, MM_UTIL_IMG_FMT_YUYV },
+ { MEDIA_PIXEL_FORMAT_NV12, MM_UTIL_IMG_FMT_NV12 },
+ };
+ mm_util_img_format ret = MM_UTIL_IMG_FMT_RGB565;
+
+ for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
+ {
+ if (map[i].key == pixelFormat)
+ {
+ return map[i].value;
+ }
+ }
+ return ret;
+}
+
+mm_util_img_rotate_type
+_SlpUtil::ToMmUtilRotateType(ImageFlipType type)
+{
+ static struct
+ {
+ ImageFlipType key;
+ mm_util_img_rotate_type value;
+ } map[] = {
+ {IMAGE_FLIP_HORIZONTAL, MM_UTIL_ROTATE_FLIP_HORZ},
+ {IMAGE_FLIP_VERTICAL, MM_UTIL_ROTATE_FLIP_VERT}
+ };
+ mm_util_img_rotate_type ret = (mm_util_img_rotate_type)0xff;
+
+ for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
+ {
+ if (map[i].key == type)
+ {
+ return map[i].value;
+ }
+ }
+ return ret;
+}
+
+mm_util_img_rotate_type
+_SlpUtil::ToMmUtilRotateType(ImageRotationType type)
+{
+ static struct
+ {
+ ImageRotationType key;
+ mm_util_img_rotate_type value;
+ } map[] = {
+ { IMAGE_ROTATION_90, MM_UTIL_ROTATE_90},
+ { IMAGE_ROTATION_180, MM_UTIL_ROTATE_180 },
+ { IMAGE_ROTATION_270, MM_UTIL_ROTATE_270 },
+ { IMAGE_ROTATION_0, MM_UTIL_ROTATE_0},
+ };
+ mm_util_img_rotate_type ret = (mm_util_img_rotate_type)0xff;
+
+ for (unsigned int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
+ {
+ if (map[i].key == type)
+ {
+ return map[i].value;
+ }
+ }
+ return ret;
+}
+
+}} // Tizen::Media
--- /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_TiffDecoder.c
+ * @brief This file contains the implementation of _TiffDecoder class.
+ */
+#include <unique_ptr.h>
+#include <FMediaImageTypes.h>
+#include <FBaseSysLog.h>
+#include "FMedia_TiffDecoder.h"
+
+using namespace Tizen::Io;
+using namespace Tizen::Base::Collection;
+
+namespace Tizen { namespace Media
+{
+
+_TiffDecoder::_TiffDecoder(void)
+ : __pTiffMemory(null)
+ , __pTiffHandle(null)
+ , __width(0)
+ , __height(0)
+{
+}
+
+_TiffDecoder::~_TiffDecoder(void)
+{
+ if (__pTiffMemory->pData != null)
+ {
+ delete[] __pTiffMemory->pData;
+ __pTiffMemory->pData = null;
+ }
+
+ if (__pTiffHandle != null)
+ {
+ TIFFClose(__pTiffHandle);
+ __pTiffHandle = null;
+ }
+}
+
+// Tiff call back functions for buffer handling.
+tsize_t
+_TiffDecoder::TiffCbReadData(thandle_t handle, tdata_t pData, tsize_t size)
+{
+ _TiffMemory *pTiffMem = (_TiffMemory*)handle;
+ if (size <= pTiffMem->left)
+ {
+ unsigned char *pFrom = pTiffMem->pData + pTiffMem->point;
+ memcpy(pData, pFrom, size);
+ pTiffMem->left = pTiffMem->left - size;
+ pTiffMem->point = pTiffMem->point + size;
+ return size;
+ }
+ return 0L;
+}
+
+toff_t
+_TiffDecoder::TiffCbSeekData(thandle_t handle, toff_t amount, int indication)
+{
+ _TiffMemory *pTiffMem = (_TiffMemory*)handle;
+ switch (indication)
+ {
+ case SEEK_SET:
+ if (amount <= pTiffMem->size)
+ {
+ pTiffMem->point = amount;
+ pTiffMem->left = pTiffMem->size - amount;
+ return amount;
+ }
+ else
+ {
+ return 0ULL;
+ }
+ break;
+ case SEEK_CUR:
+ if (pTiffMem->left - amount <= (signed int)pTiffMem->size || pTiffMem->left >= amount)
+ {
+ pTiffMem->point = pTiffMem->point + amount;
+ pTiffMem->left = pTiffMem->left - amount;
+ return amount;
+ }
+ else
+ {
+ return 0ULL;
+ }
+ break;
+ case SEEK_END:
+ if (amount >= -pTiffMem->size && amount <= 0)
+ {
+ pTiffMem->point = pTiffMem->size - amount;
+ pTiffMem->left = amount;
+ return amount;
+ }
+ else
+ {
+ return 0ULL;
+ }
+ break;
+ default:
+ return 0ULL;
+ break;
+ }
+
+}
+
+toff_t
+_TiffDecoder::TiffCbGetSize(thandle_t handle)
+{
+ _TiffMemory *pTiffMem = (_TiffMemory*)handle;
+ return pTiffMem->size;
+}
+
+int
+_TiffDecoder::TiffCbMemClose(thandle_t)
+{
+ // Unhandled.
+ return 0;
+}
+
+int
+_TiffDecoder::TiffCbMemMapFileproc(thandle_t, tdata_t*, toff_t*)
+{
+ // Unhandled.
+ return 0;
+}
+
+void
+_TiffDecoder::TiffCbMemUnMapFileProc(thandle_t, tdata_t, toff_t)
+{
+ // Unhandled.
+ return;
+}
+
+// _TiffDecoder functions.
+result
+_TiffDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
+{
+ result r = E_SUCCESS;
+
+ SysTryReturnResult(NID_MEDIA, buffer != null, E_INVALID_ARG,
+ "Input buffer is null");
+
+ __pTiffMemory = std::unique_ptr<_TiffMemory> (new (std::nothrow)_TiffMemory);
+ SysTryReturnResult(NID_MEDIA, __pTiffMemory.get() != null, E_OUT_OF_MEMORY,
+ "Failed to create _TiffMemory structure.");
+
+ __pTiffMemory->pData = new (std::nothrow) byte[length];
+ SysTryCatch(NID_MEDIA, __pTiffMemory->pData != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Failed to allocate _TiffMemory->pData: %d bytes.", length);
+
+ memcpy(__pTiffMemory->pData, buffer, length);
+
+ __pTiffMemory->size = length;
+ __pTiffMemory->left = length;
+ __pTiffMemory->point = 0;
+
+ __pTiffHandle = TIFFClientOpen("dummy", "r", (void *)__pTiffMemory.get(),
+ TiffCbReadData, TiffCbReadData,
+ TiffCbSeekData, TiffCbMemClose,
+ TiffCbGetSize,
+ TiffCbMemMapFileproc, TiffCbMemUnMapFileProc);
+ SysTryCatch(NID_MEDIA, __pTiffHandle != null, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] TIFFClientOpen failed.");
+
+ TIFFGetField(__pTiffHandle, TIFFTAG_IMAGEWIDTH, &__width);
+ SysTryCatch(NID_MEDIA, __width > 0, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] Check image, width is zero.");
+ TIFFGetField(__pTiffHandle, TIFFTAG_IMAGELENGTH, &__height);
+ SysTryCatch(NID_MEDIA, __height > 0, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] Check image, height is zero.");
+
+ return r;
+
+CATCH:
+
+ if (__pTiffMemory->pData != null)
+ {
+ delete[] __pTiffMemory->pData;
+ __pTiffMemory->pData = null;
+ }
+ return r;
+}
+
+byte*
+_TiffDecoder::DecodeN(int& outLength)
+{
+ int tiffRet = 0;
+ int row = 0;
+ int rowSize = 0;
+ byte* pTempDstPtr = null;
+ byte* pTempSrcPtr = null;
+
+ std::unique_ptr<byte[]> pTempDecodeBuf;
+ std::unique_ptr<byte[]> pOutBuf;
+ SysTryReturn(NID_MEDIA, __pTiffHandle != null, null, E_INVALID_STATE,
+ "Instance is not constructed.");
+
+ outLength = __width * __height * BYTES_PER_PIXEL_RGBA;
+ pTempDecodeBuf.reset(new (std::nothrow) byte[outLength]);
+ SysTryReturn(NID_MEDIA, pTempDecodeBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes for temp buffer!", outLength);
+
+ pOutBuf.reset(new (std::nothrow) byte[outLength]);
+ SysTryReturn(NID_MEDIA, pOutBuf.get() != null, null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Could not allocate %d bytes for temp buffer!", outLength);
+
+ tiffRet = TIFFReadRGBAImage(__pTiffHandle, __width, __height, (uint32*)pTempDecodeBuf.get(), 0);
+ SysTryReturn(NID_MEDIA, tiffRet == 1, null, E_SYSTEM,
+ "[E_SYSTEM] TIFFReadRGBAImage failed.");
+
+ rowSize = __width * BYTES_PER_PIXEL_RGBA;
+ pTempDstPtr = pOutBuf.get() + ((__height - 1) * rowSize);
+ pTempSrcPtr = pTempDecodeBuf.get();
+
+ // libtiff returns a vertically flipped image.
+ for (row = 0; row < __height; row++)
+ {
+ memcpy(pTempDstPtr, pTempSrcPtr, rowSize);
+ pTempDstPtr -= rowSize;
+ pTempSrcPtr += rowSize;
+ }
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+}
+
+result
+_TiffDecoder::SetDecodingRegion(int x, int y, int width, int height)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+result
+_TiffDecoder::GetDimension(int& width, int& height)
+{
+ SysTryReturnResult(NID_MEDIA, __pTiffHandle != null, E_INVALID_STATE, "Instance is not constructed.");
+
+ width = __width;
+ height = __height;
+
+ SetLastResult(E_SUCCESS);
+ return E_SUCCESS;
+}
+
+MediaPixelFormat
+_TiffDecoder::GetPixelFormat(void)
+{
+ MediaPixelFormat pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
+
+ pixelFormat = MEDIA_PIXEL_FORMAT_RGBA8888;
+
+ SetLastResult(E_SUCCESS);
+ return pixelFormat;
+}
+
+result
+_TiffDecoder::SetScaleDown(int scaleDown)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+result
+_TiffDecoder::GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+}} // Tizen::Media
--- /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_TiffDecoder.h
+ * @brief This is header file for _TiffDecoder class.
+ */
+#ifndef _FMEDIA_INTERNAL_TIFF_DECODER_H_
+#define _FMEDIA_INTERNAL_TIFF_DECODER_H_
+
+#include <unique_ptr.h>
+#include <tiffio.h>
+
+#include "FMedia_IImageDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+typedef struct
+{
+ unsigned char *pData;
+ unsigned long long size;
+ int left;
+ unsigned int point;
+} _TiffMemory;
+
+class _TiffDecoder
+ : public _IImageDecoder
+ , public Tizen::Base::Object
+{
+public:
+ static const int MAX_SIZE = 4096000;
+ static const int MAX_WIDTH = 3000;
+ static const int MAX_HEIGHT = 3000;
+ static const int BYTES_PER_PIXEL_RGBA = 4;
+
+ _TiffDecoder(void);
+
+ virtual ~_TiffDecoder(void);
+
+ /**
+ * Constructs this instancce with given buffer and length.
+ *
+ * @return An error code
+ * @param[in] buffer The buffer that contains compressed data.
+ * @param[in] length The length of buffer.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual result Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat);
+
+ /**
+ * Decodes current frame and returns decoded data.
+ *
+ * @return A buffer pointer of decoded data
+ * @param[out] outLength The length of outBuf.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_DATA The data is invalid.
+ */
+ virtual byte* DecodeN(int& outLength);
+
+ /**
+ * Sets the decoding region. @n
+ *
+ * @return An error code
+ * @param[in] rect The decoding region.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetDecodingRegion(int x, int y, int width, int height);
+
+ /**
+ * Gets current dimension of image.
+ *
+ * @return An error code
+ * @param[out] width The width of image.
+ * @param[out] height The height of image.
+ */
+ virtual result GetDimension(int& width, int& height);
+
+ /**
+ * Gets the output pixel format.
+ *
+ * @return The output pixel format.
+ */
+ virtual MediaPixelFormat GetPixelFormat(void);
+
+ /**
+ * Sets scale down degree.
+ *
+ * @return An error code
+ * @param[in] scaleDown The level of scale down.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetScaleDown(int scaleDown);
+
+ /**
+ * Gets the value of given key.
+ *
+ * @return An error code
+ * @param[in] key The key of the value.
+ * @param[out] value The output value.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+
+private:
+ // Methods to be passed to libtiff for reading input data.
+ static tsize_t TiffCbReadData(thandle_t handle, tdata_t pData, tsize_t size);
+ static toff_t TiffCbSeekData(thandle_t handle, toff_t amount, int indication);
+ static toff_t TiffCbGetSize(thandle_t handle);
+ static int TiffCbMemClose(thandle_t);
+ static int TiffCbMemMapFileproc(thandle_t, tdata_t*, toff_t*);
+ static void TiffCbMemUnMapFileProc(thandle_t, tdata_t, toff_t);
+
+ _TiffDecoder(const _TiffDecoder& rhs);
+ _TiffDecoder& operator =(const _TiffDecoder& rhs);
+
+ std::unique_ptr<_TiffMemory> __pTiffMemory;
+ TIFF* __pTiffHandle;
+ int __width;
+ int __height;
+
+}; // class _TiffDecoder
+
+} } // Tizen::Media
+
+#endif
--- /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_WbmpDecoder.c
+ * @brief This file contains the implementation of _WbmpDecoder class.
+ *
+ */
+#include <unique_ptr.h>
+#include <Ecore.h>
+#include <Evas.h>
+#include <Ecore_Evas.h>
+#include <FMediaImageTypes.h>
+#include <FBaseSysLog.h>
+#include "FMedia_WbmpDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+_WbmpDecoder::_WbmpDecoder(void)
+ : __pEvas(null)
+ , __pEcoreEvas(null)
+ , __pImageObj(null)
+{
+ // Initialize Evas.
+ ecore_evas_init();
+}
+
+_WbmpDecoder::~_WbmpDecoder(void)
+{
+ if (__pImageObj)
+ {
+ evas_object_image_file_set(__pImageObj, NULL, NULL);
+ }
+ __pImageObj = null;
+
+ if (__pEcoreEvas)
+ {
+ ecore_evas_free(__pEcoreEvas);
+ }
+
+ ecore_evas_shutdown();
+}
+
+result
+_WbmpDecoder::Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat)
+{
+ result r = E_SUCCESS;
+ Evas_Load_Error evas_error = EVAS_LOAD_ERROR_NONE;
+
+ SysTryReturnResult(NID_MEDIA, __pImageObj == null, E_INVALID_STATE,
+ "Already constructed");
+ SysTryReturnResult(NID_MEDIA, buffer != null, E_INVALID_ARG,
+ "Input buffer is null");
+ SysTryReturnResult(NID_MEDIA, length > 0, E_INVALID_ARG,
+ "Length (%d) should be greater than zero", length);
+
+ // Create new instance of ecore evas.
+ __pEcoreEvas = ecore_evas_new(NULL, 0, 0, 0, 0, NULL);
+ SysTryCatch(NID_MEDIA, __pEcoreEvas, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Failed to create ecore_evas.");
+
+ // Get the instance of ecore's evas
+ __pEvas = ecore_evas_get(__pEcoreEvas);
+ SysTryCatch(NID_MEDIA, __pEvas, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] Failed to get evas.");
+
+ // Create evas object handle to which image will be added.
+ __pImageObj = evas_object_image_add(__pEvas);
+ SysTryCatch(NID_MEDIA, __pImageObj, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] Failed to add object to evas.");
+
+ // Set the canvas colorspace to ARGB8888.
+ evas_object_image_colorspace_set(__pImageObj, EVAS_COLORSPACE_ARGB8888);
+
+ // Set the buffer to be decoded.
+ evas_object_image_memfile_set(__pImageObj, (void*) buffer, length, NULL, NULL);
+ // Check for error in the previous step.
+ evas_error = evas_object_image_load_error_get(__pImageObj);
+ SysTryCatch(NID_MEDIA, evas_error == EVAS_LOAD_ERROR_NONE, r = E_UNSUPPORTED_FORMAT,
+ E_UNSUPPORTED_FORMAT, "[E_SYSTEM] Failed to add path to evas object, error: %s.",
+ evas_load_error_str(evas_error));
+
+ return r;
+
+CATCH:
+ if (__pImageObj)
+ {
+ evas_object_image_file_set(__pImageObj, NULL, NULL);
+ __pImageObj = null;
+ }
+
+ if (__pEcoreEvas)
+ {
+ ecore_evas_free(__pEcoreEvas);
+ __pEcoreEvas = null;
+ }
+
+ return r;
+}
+
+byte*
+_WbmpDecoder::DecodeN(int& outLength)
+{
+ Evas_Colorspace colorSpace = EVAS_COLORSPACE_YCBCR420TM12601_PL;
+ int width = 0;
+ int height = 0;
+ byte* pEvasOutBuf = null;
+ std::unique_ptr<byte[]> pOutBuf;
+
+ SysTryReturn(NID_MEDIA, __pImageObj, null, E_INVALID_STATE,
+ "Not yet constructed");
+
+ // Calculate size of output from dimensions and color format
+ evas_object_image_size_get(__pImageObj, &width, &height);
+
+ SysTryReturn(NID_MEDIA, (width && height), null, E_INVALID_DATA,
+ "[E_INVALID_DATA] Evas returned invalid dimensions %d x %d.", width, height);
+
+ outLength = width * height * 4; // 4 because cs is set to EVAS_COLORSPACE_ARGB8888
+
+ pOutBuf.reset(new (std::nothrow) byte[outLength]);
+ SysTryReturn(NID_MEDIA, pOutBuf.get(), null, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] Failed to allocate %d bytes for decoder output.", outLength);
+
+ pEvasOutBuf = (byte*) evas_object_image_data_get(__pImageObj, true);
+ SysTryReturn(NID_MEDIA, pEvasOutBuf, null, E_SYSTEM,
+ "[E_SYSTEM] Evas returned empty buffer.");
+ colorSpace = evas_object_image_colorspace_get(__pImageObj);
+
+ memcpy(pOutBuf.get(), pEvasOutBuf, outLength);
+
+ SetLastResult(E_SUCCESS);
+ return pOutBuf.release();
+}
+
+result
+_WbmpDecoder::SetDecodingRegion(int x, int y, int width, int height)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+result
+_WbmpDecoder::GetDimension(int& width, int& height)
+{
+ SysTryReturnResult(NID_MEDIA, __pImageObj, E_INVALID_STATE, "Not yet constructed");
+ evas_object_image_size_get(__pImageObj, &width, &height);
+
+ return E_SUCCESS;
+}
+
+MediaPixelFormat
+_WbmpDecoder::GetPixelFormat(void)
+{
+ MediaPixelFormat pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
+
+ SysTryReturn(NID_MEDIA, __pImageObj, MEDIA_PIXEL_FORMAT_NONE, E_INVALID_STATE, "[E_INVALID_STATE]");
+
+ pixelFormat = MEDIA_PIXEL_FORMAT_RGBA8888;
+
+ SetLastResult(E_SUCCESS);
+
+ return pixelFormat;
+}
+
+result
+_WbmpDecoder::SetScaleDown(int scaleDown)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+result
+_WbmpDecoder::GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
+{
+ return E_UNSUPPORTED_OPERATION;
+}
+
+}} // Tizen::Media
--- /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_WbmpDecoder.h
+ * @brief This is header file for _WbmpDecoder class.
+ *
+ */
+#ifndef _FMEDIA_INTERNAL_WBMP_DECODER_H_
+#define _FMEDIA_INTERNAL_WBMP_DECODER_H_
+
+#include "FMedia_IImageDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+class _WbmpDecoder
+ : public _IImageDecoder
+ , public Tizen::Base::Object
+{
+public:
+ _WbmpDecoder(void);
+
+ virtual ~_WbmpDecoder(void);
+
+ /**
+ * Constructs this instancce with given buffer and length.
+ *
+ * @return An error code
+ * @param[in] buffer The buffer that contains compressed data.
+ * @param[in] length The length of buffer.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual result Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat);
+
+ /**
+ * Decodes current frame and returns decoded data.
+ *
+ * @return A buffer pointer of decoded data
+ * @param[out] outLength The length of outBuf.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_DATA The data is invalid.
+ */
+ virtual byte* DecodeN(int& outLength);
+
+ /**
+ * Sets the decoding region. @n
+ *
+ * @return An error code
+ * @param[in] rect The decoding region.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetDecodingRegion(int x, int y, int width, int height);
+
+ /**
+ * Gets current dimension of image.
+ *
+ * @return An error code
+ * @param[out] width The width of image.
+ * @param[out] height The height of image.
+ */
+ virtual result GetDimension(int& width, int& height);
+
+ /**
+ * Gets the output pixel format.
+ *
+ * @return The output pixel format.
+ */
+ virtual MediaPixelFormat GetPixelFormat(void);
+
+ /**
+ * Sets scale down degree.
+ *
+ * @return An error code
+ * @param[in] scaleDown The level of scale down.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetScaleDown(int scaleDown);
+
+ /**
+ * Gets the value of given key.
+ *
+ * @return An error code
+ * @param[in] key The key of the value.
+ * @param[out] value The output value.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+
+private:
+ struct _Evas* __pEvas;
+ // Ecore canvas
+ struct _Ecore_Evas* __pEcoreEvas;
+ struct _Evas_Object* __pImageObj;
+ // bool __isConstructed;
+
+}; // class _WbmpDecoder
+
+
+};
+};
+
+#endif
--- /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_ColorConverter.h
+ * @brief This is the header file for the FMedia::_ColorConverter.
+ *
+ * This header file contains the declarations of the FMedia::_ColorConverter.
+ *
+ */
+#ifndef _FMEDIA_INTERNAL_COLORCONVERTER_H_
+#define _FMEDIA_INTERNAL_COLORCONVERTER_H_
+
+#include <FMedia_Ffmpeg.h>
+
+namespace Tizen { namespace Media
+{
+
+class _OSP_EXPORT_ _ColorConverter
+ : public Tizen::Base::Object
+{
+public:
+ _ColorConverter(void);
+
+ virtual ~_ColorConverter(void);
+
+ /**
+ * Initializes this instance of converter
+ *
+ * @return An error code
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The arguments to the method are invalid:
+ * All dimensions should be greater than zero.
+ * @exception E_UNSUPPORTED_FORMAT A pixelformat argument is not supported.
+ * @exception E_SYSTEM A system error has occurred.
+ */
+ result Construct(MediaPixelFormat srcFormat, int srcWidth, int srcHeight,
+ MediaPixelFormat dstFormat, int dstWidth, int dstHeight);
+
+public:
+ /**
+ * convert pixel format
+ *
+ * @return An error code
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_SYSTEM A system error has occurred.
+ */
+ Tizen::Base::ByteBuffer* ConvertN(const Tizen::Base::ByteBuffer& srcBuf);
+
+ /**
+ * convert pixel format
+ *
+ * @return An error code
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_SYSTEM A system error has occurred.
+ */
+ byte* ConvertN(const byte* pSrcBuf, int srcLength, int& dstLength);
+ /**
+ * convert pixel format
+ *
+ * @return An error code
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_SYSTEM A system error has occurred.
+ */
+ result Convert(const byte* srcBuf, int srcLength, byte* dstBuf, int dstLength);
+
+private:
+ int __srcWidth;
+ int __srcHeight;
+ int __dstWidth;
+ int __dstHeight;
+ int __origSrcWidth;
+ int __origSrcHeight;
+ int __origDstWidth;
+ int __origDstHeight;
+ MediaPixelFormat __srcFormat;
+ MediaPixelFormat __dstFormat;
+ PixelFormat __ffSrcFormat;
+ PixelFormat __ffDstFormat;
+
+ struct SwsContext* __pCvtCtxt;
+
+ bool __toResizeIn;
+ bool __toResizeOut;
+}; // class _ColorConverter
+
+}} // Tizen::Media
+
+#endif
--- /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.h
+ * @brief This is the header file for the ffmpeg related header inclusion.
+ *
+ * This header file contains the declarations of the header files for ffmpeg.
+ *
+ */
+#ifndef _FMEDIA_INTERNAL_FFMPEG_H_
+#define _FMEDIA_INTERNAL_FFMPEG_H_
+
+#ifdef __cplusplus
+#define __STDC_CONSTANT_MACROS
+#ifdef _STDINT_H
+#undef _STDINT_H
+#endif
+#include <stdint.h>
+#endif
+
+// #define attribute_deprecated
+
+extern "C" {
+#include <libavutil/avutil.h>
+#include <libavutil/pixfmt.h>
+#include <libavutil/imgutils.h>
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libswscale/swscale.h>
+};
+
+
+#endif
--- /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 FMediaGifDecoder.h
+ * @brief This is header file for _GifDecoder.
+ */
+#ifndef _FMEDIA_INTERNAL_GIF_DECODER_H_
+#define _FMEDIA_INTERNAL_GIF_DECODER_H_
+
+#include <unique_ptr.h>
+#include "FMedia_IImageDecoder.h"
+
+namespace Tizen { namespace Media
+{
+
+class _OSP_EXPORT_ _GifDecoder
+ : public _IImageDecoder
+ , public Tizen::Base::Object
+{
+public:
+ static const int MAX_WIDTH = 3000;
+ static const int MAX_HEIGHT = 3000;
+ static const int MAX_SIZE = 4096000; // 4Mbyte
+ static const int MAX_AGIF_WIDTH = 800;
+ static const int MAX_AGIF_HEIGHT = 800;
+ static const int MAX_AGIF_SIZE = 3072000; // 3Mbyte
+
+ _GifDecoder(void);
+
+ virtual ~_GifDecoder(void);
+
+ /**
+ * Constructs this instancce with given buffer and length.
+ *
+ * @return An error code
+ * @param[in] buffer The buffer that contains compressed data.
+ * @param[in] length The length of buffer.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual result Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat);
+
+ /**
+ * Decodes current frame and returns decoded data.
+ *
+ * @return A buffer pointer of decoded data
+ * @param[out] outLength The length of outBuf.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_DATA The data is invalid.
+ */
+ virtual byte* DecodeN(int& outLength);
+
+ /**
+ * Sets the decoding region. @n
+ *
+ * @return An error code
+ * @param[in] rect The decoding region.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetDecodingRegion(int x, int y, int width, int height);
+
+ /**
+ * Gets current dimension of image.
+ *
+ * @return An error code
+ * @param[out] width The width of image.
+ * @param[out] height The height of image.
+ */
+ virtual result GetDimension(int& width, int& height);
+
+ /**
+ * Gets the output pixel format.
+ *
+ * @return The output pixel format.
+ */
+ virtual MediaPixelFormat GetPixelFormat(void);
+
+ /**
+ * Sets scale down degree.
+ *
+ * @return An error code
+ * @param[in] scaleDown The level of scale down.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetScaleDown(int scaleDown);
+
+ /**
+ * Gets the value of given key.
+ *
+ * @return An error code
+ * @param[in] key The key of the value.
+ * @param[out] value The output value.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value);
+
+private:
+ static int BufferReadFuncStatic(struct GifFileType* gifFile, unsigned char* buf, int count);
+ int BufferReadFunc(unsigned char* buf, int count);
+ static byte* GeneratePaletteN(MediaPixelFormat pixelFormat, struct ColorMapObject* colorMap);
+ result ConstructBuffer(MediaPixelFormat pixelFormat);
+ result DecodeOneFrame(unsigned char* pDstBuffer, unsigned int length);
+
+ struct GifFileType* __pDec;
+ // ByteBuffer Input
+ Tizen::Base::ByteBuffer __srcBuf;
+ MediaPixelFormat __pixelFormat;
+ std::unique_ptr<byte[]> __pGlobalPalette;
+ std::unique_ptr<byte[]> __pLocalPalette;
+ int __bpp;
+ std::unique_ptr<byte[]> __pDstByte;
+ int __dstLength;
+ int __firstFramePos;
+ bool __transparent;
+ unsigned int __transColor;
+ // Paramaters;
+ int __srcWidth;
+ int __srcHeight;
+ int __frameIndex;
+// int __requestedIndex;
+ int __duration;
+ int __totalFrames;
+ _GifDecoder(const _GifDecoder& gifDecoder);
+ _GifDecoder& operator =(const _GifDecoder& gifDecoder);
+
+}; // class _GifDecoder
+
+
+}}
+
+#endif
--- /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_IImageDecoder.h
+ * @brief This is interface for each image format decoder.
+ *
+ */
+#ifndef _FMEDIA_INTERNAL_IIMAGE_DECODER_H_
+#define _FMEDIA_INTERNAL_IIMAGE_DECODER_H_
+
+namespace Tizen { namespace Media
+{
+
+class _OSP_EXPORT_ _IImageDecoder
+{
+public:
+
+ /**
+ * This polymorphic destructor should be overridden if required. This way,
+ * the destructors of derived classes are called when the destructor of this
+ * interface is called.
+ */
+ virtual ~_IImageDecoder(void) {};
+
+ /**
+ * Constructs this instancce with given buffer and length.
+ *
+ * @return An error code
+ * @param[in] buffer The buffer that contains compressed data.
+ * @param[in] length The length of buffer.
+ * @param[in] pixelFormat The recommended output pixel format.
+ * @exception E_SUCCESS The method is successful.
+ *
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual result Construct(const byte* buffer, int length, MediaPixelFormat pixelFormat) = 0;
+
+ /**
+ * Decodes current frame and returns decoded data.
+ *
+ * @return A buffer pointer of decoded data
+ * @param[out] outLength The length of outBuf.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_DATA The data is invalid.
+ */
+ virtual byte* DecodeN(int& outLength) = 0;
+
+ /**
+ * Sets the decoding region. @n
+ *
+ * @return An error code
+ * @param[in] rect The decoding region.
+ *
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetDecodingRegion(int x, int y, int width, int height) = 0;
+
+ /**
+ * Gets current dimension of image.
+ *
+ * @return An error code
+ * @param[out] width The width of image.
+ * @param[out] height The height of image.
+ */
+ virtual result GetDimension(int& width, int& height) = 0;
+
+ /**
+ * Gets the output pixel format.
+ *
+ * @return The output pixel format.
+ */
+ virtual MediaPixelFormat GetPixelFormat(void) = 0;
+
+ /**
+ * Sets scale down degree.
+ *
+ * @return An error code
+ * @param[in] scaleDown The level of scale down.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result SetScaleDown(int scaleDown) = 0;
+
+ /**
+ * Gets the value of given key.
+ *
+ * @return An error code
+ * @param[in] key The key of the value.
+ * @param[out] value The output value.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_OPERATION This method is unsupported.
+ */
+ virtual result GetValue(const Tizen::Base::String& key, Tizen::Base::Object &value) = 0;
+}; // class _IImageDecoder
+
+};
+};
+
+#endif
--- /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_IImageEncoder.h
+ * @brief This is interface for each image format encoder.
+ *
+ */
+#ifndef _FMEDIA_INTERNAL_IIMAGE_ENCODER_H_
+#define _FMEDIA_INTERNAL_IIMAGE_ENCODER_H_
+
+namespace Tizen { namespace Media
+{
+
+ enum MediaPixelFormat;
+
+class _OSP_EXPORT_ _IImageEncoder
+{
+public:
+
+ /**
+ * This polymorphic destructor should be overridden if required. This way,
+ * the destructors of derived classes are called when the destructor of this
+ * interface is called.
+ */
+ virtual ~_IImageEncoder(void) {};
+
+ /**
+ * Construct _IImageEncoder instance
+ *
+ * @return An error code
+ * @param[in] dim Encode dimension
+ * @param[in] srcPixelFormat source pixel format
+ * @param[out] reqPixelFormat required pixel format.
+ * @param[in] quality encoding quality
+ */
+ virtual result Construct(int width, int height,
+ MediaPixelFormat srcPixelFormat,
+ MediaPixelFormat& reqPixelFormat,
+ int quality) = 0;
+
+ /**
+ * Encodes the image data
+ *
+ * @return An error code
+ * @param[in] srcBuf Source raw data
+ * @param[in] srcLength Source data length
+ * @param[out] dstBuf Encoded destination buffer
+ * @param[out] dstLength Destination buffer length
+ *
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ virtual Tizen::Base::ByteBuffer* EncodeN(const byte* srcBuf, int srcLength) = 0;
+
+
+ /**
+ * Set specific key value to the encoder
+ * @return An error code
+ * @param[in] key The key to be set
+ * @param[in] value The value to be set.
+ */
+ virtual result SetValue(const Tizen::Base::String& key, Tizen::Base::Object &value) = 0;
+}; // class _IImageEncoder
+
+};
+};
+
+#endif
--- /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_ImageDecoder.h
+ * @brief This is the header file for the _ImageDecoder.
+ */
+
+#ifndef _FMEDIA_INTERNAL_IMAGE_DECODER_H_
+#define _FMEDIA_INTERNAL_IMAGE_DECODER_H_
+
+#include <unique_ptr.h>
+#include <FBaseObject.h>
+#include <FMediaImageTypes.h>
+
+namespace Tizen { namespace Base {
+class ByteBuffer;
+class String;
+} }
+
+namespace Tizen { namespace Media
+{
+
+class _IImageDecoder;
+
+/**
+ * @class _ImageDecoder
+ * @brief This class provides internal APIs for image decoding.
+ *
+ * This class provides internal methods for image decoding.
+ */
+class _OSP_EXPORT_ _ImageDecoder
+ : virtual public Tizen::Base::Object
+{
+public:
+ /**
+ * Decodes an image data into the decoded byte buffer container without resizing. @n
+ * The currently supported decoding formats are JPEG, GIF, PNG, BMP, TIFF, and WBMP.
+ *
+ * @return A decoded byte data that is not resized, @n
+ * else @c null if an exception occurs
+ * @param[in] filePath The image file path to decode.
+ * @param[in] pixelFormat The output pixel format. @c
+ * @param[out] width The width of image. @n
+ * @param[out] height The height of image.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG A specified color format is not supported.
+ * @exception E_OVERFLOW The source image exceeds max size or length.
+ * @exception E_UNSUPPORTED_FORMAT The specified format is not supported.
+ * @exception E_OUT_OF_MEMORY The memory is insufficient.
+ * @exception E_FILE_NOT_FOUND The specified image file cannot be found.
+ * @exception E_SYSTEM A system error has occurred.
+ * @remarks The specific error code can be accessed using the GetLastResult() method.
+ * @remarks Supported pixel formats are MEDIA_PIXEL_FORMAT_RGB565LE,
+ * MEDIA_PIXEL_FORMAT_BGRA8888, and MEDIA_PIXEL_FORMAT_RGBA8888.
+ */
+ static Tizen::Base::ByteBuffer*
+ DecodeToBufferN(const Tizen::Base::String& filePath, MediaPixelFormat pixelFormat,
+ int &width, int &height);
+
+ /**
+ * Decodes a region of image data into the decoded byte buffer container without resizing. @n
+ * The currently supported decoding formats are JPEG, GIF, PNG, BMP, TIFF, and WBMP.
+ *
+ * @return A decoded byte data that is not resized, @n
+ * else @c null if an exception occurs
+ * @param[in] filePath The image file path to decode.
+ * @param[in] pixelFormat The output pixel format. @c
+ * @param[in] x The x position of decoding region
+ * @param[in] y The y position of decoding region
+ * @param[in] width The width of decoding region.
+ * @param[in] height The height of decoding region.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG A specified color format is not supported.
+ * @exception E_OVERFLOW The source image exceeds max size or length.
+ * @exception E_UNSUPPORTED_FORMAT The specified format is not supported.
+ * @exception E_OUT_OF_MEMORY The memory is insufficient.
+ * @exception E_FILE_NOT_FOUND The specified image file cannot be found.
+ * @exception E_SYSTEM A system error has occurred.
+ * @remarks The specific error code can be accessed using the GetLastResult() method.
+ * @remarks Supported pixel formats are MEDIA_PIXEL_FORMAT_RGB565LE,
+ * MEDIA_PIXEL_FORMAT_BGRA8888, and MEDIA_PIXEL_FORMAT_RGBA8888.
+ */
+ static Tizen::Base::ByteBuffer*
+ DecodeRegionToBufferN(const Tizen::Base::String& filePath, MediaPixelFormat pixelFormat,
+ int x, int y, int width, int height);
+
+ /**
+ * Decodes a region of image data into the decoded byte buffer container without resizing. @n
+ * The currently supported decoding formats are JPEG, GIF, PNG, BMP, TIFF, and WBMP.
+ *
+ * @return A decoded byte data that is not resized, @n
+ * else @c null if an exception occurs
+ * @param[in] srcBuf The buffer that contains source data.
+ * @param[in] pixelFormat The output pixel format. @c
+ * @param[in] x The x position of decoding region
+ * @param[in] y The y position of decoding region
+ * @param[in] width The width of decoding region.
+ * @param[in] height The height of decoding region.
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_INVALID_ARG A specified color format is not supported.
+ * @exception E_OVERFLOW The source image exceeds max size or length.
+ * @exception E_UNSUPPORTED_FORMAT The specified format is not supported.
+ * @exception E_OUT_OF_MEMORY The memory is insufficient.
+ * @exception E_SYSTEM A system error has occurred.
+ * @remarks The specific error code can be accessed using the GetLastResult() method.
+ * @remarks Supported pixel formats are MEDIA_PIXEL_FORMAT_RGB565LE,
+ * MEDIA_PIXEL_FORMAT_BGRA8888, and MEDIA_PIXEL_FORMAT_RGBA8888.
+ */
+ static Tizen::Base::ByteBuffer*
+ DecodeRegionToBufferN(const Tizen::Base::ByteBuffer& srcBuf, MediaPixelFormat pixelFormat,
+ int x, int y, int width, int height);
+
+ /**
+ * Gets image informations
+ *
+ * @return An error code
+ * @param[in] filePath The path of image file
+ * @param[out] imFormat The format of image
+ * @param[out] width The width of image
+ * @param[out] height The height of image
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_UNSUPPORTED_FORMAT The specified format is not supported.
+ * @exception E_OUT_OF_MEMORY The memory is insufficient.
+ * @exception E_FILE_NOT_FOUND The specified file cannot be found or accessed.
+ * @exception E_SYSTEM A system error has occurred.
+ */
+ static result GetImageInfo(const Tizen::Base::String& filePath, ImageFormat &imgFormat,
+ int &width, int &height);
+
+// DO NOT USE these APIs outside of Tizen::Media
+ _ImageDecoder(void);
+
+ virtual ~_ImageDecoder(void);
+
+ /**
+ * Initializes this instance of ImageDecode.
+ *
+ * param[in] srcPath Source image file path.
+ * param[in] pixelFormat Output pixel format.
+ * param[in] imgFormat Input image format.
+ * @return An error code
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_SYSTEM A system error has occurred.
+ */
+ result Construct(const Tizen::Base::String& srcPath,
+ MediaPixelFormat pixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888,
+ ImageFormat imgFormat = IMG_FORMAT_NONE);
+
+ /**
+ * Initializes this instance of ImageDecode.
+ *
+ * param[in] srcBuffer Source image buffer.
+ * param[in] pixelFormat Output pixel format.
+ * param[in] imgFormat Input image format.
+ * @return An error code
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_SYSTEM A system error has occurred.
+ */
+ result Construct(const Tizen::Base::ByteBuffer& srcBuffer,
+ MediaPixelFormat pixelFormat = MEDIA_PIXEL_FORMAT_BGRA8888,
+ ImageFormat imgFormat = IMG_FORMAT_NONE);
+
+ /**
+ * Decodes image buffer.
+ *
+ * param[out] outLength Output buffer length
+ * @return A byte pointer that contains decoded image data.
+ * @exception E_SUCCESS The method is successful.
+ * @remark
+ */
+ byte* DecodeN(int& outLength);
+
+ /**
+ * Decodes image buffer.
+ *
+ * @return A ByteBuffer pointer that contains decoded image data.
+ * @exception E_SUCCESS The method is successful.
+ * @remark
+ */
+ Tizen::Base::ByteBuffer* DecodeN(void);
+
+ /**
+ * Gets image format
+ *
+ * return Image format
+ * @exception E_SUCCESS The method is successful.
+ * @remark
+ */
+ ImageFormat GetImageFormat(void) const;
+
+ /**
+ * Sets region of decoding
+ *
+ * return An error code
+ * param[in] x x position
+ * param[in] y y position
+ * param[in] width width of decoding region
+ * param[in] height height of decoding region
+ * @exception E_SUCCESS The method is successful.
+ * @remark
+ */
+ result SetDecodingRegion(int x, int y, int width, int height);
+
+ /**
+ * Get the demension of decoded image
+ *
+ * return An error code
+ * param[out] width The width of image
+ * param[out] height The height of image
+ * @exception E_SUCCESS The method is successful.
+ * @remark
+ */
+ result GetDimension(int &width, int &height) const;
+
+ /**
+ * Get pixel format
+ *
+ * return image pixel format
+ * @exception E_SUCCESS The method is successful.
+ * @remark
+ */
+ MediaPixelFormat GetPixelFormat(void) const;
+
+ /**
+ * Set demension of output
+ *
+ * return An error code
+ * param[in] width The width of output image
+ * param[in] height The height of output image
+ * @exception E_SUCCESS The method is successful.
+ * @remark
+ */
+ result SetOutputDimension(int width, int height, bool keepAspectRatio);
+
+private:
+ _ImageDecoder(const _ImageDecoder& dec);
+ _ImageDecoder& operator =(const _ImageDecoder& dec);
+
+ static _IImageDecoder* CreateDecoderN(ImageFormat srcFormat);
+
+ //_IImageDecoder* __pDec;
+ std::unique_ptr<_IImageDecoder> __pDec;
+ ImageFormat __imgFormat;
+ struct
+ {
+ int width;
+ int height;
+ } __orgDim;
+ struct
+ {
+ int width;
+ int height;
+ } __outDim;
+ MediaPixelFormat __pixelFormat;
+ std::unique_ptr<Tizen::Base::ByteBuffer> __pSrcBuf;
+
+}; // class _ImageDecoder
+
+}}
+
+#endif
--- /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_ImageEncoder.h
+ * @brief This is the header file for the _ImageEncoder.
+ */
+
+#ifndef _FMEDIA_INTERNAL_IMAGE_ENCODER_H_
+#define _FMEDIA_INTERNAL_IMAGE_ENCODER_H_
+
+#include <unique_ptr.h>
+#include <FBaseObject.h>
+#include <FMediaImageTypes.h>
+
+namespace Tizen { namespace Base {
+class ByteBuffer;
+} }
+
+namespace Tizen { namespace Media
+{
+
+class _IImageEncoder;
+
+/**
+ * @class _ImageEncoder
+ * @brief This class provides internal APIs for image encoding.
+ *
+ * This class provides internal methods for image encoding.
+ */
+class _OSP_EXPORT_ _ImageEncoder
+ : virtual public Tizen::Base::Object
+{
+public:
+ /**
+ * Encodes the raw data into compressed image format.
+ *
+ * @return A byte buffer that has the encoded data
+ * @param[in] srcBuf The buffer that contains source data.
+ * @param[in] width The width of source data
+ * @param[in] height The height of source data
+ * @param[in] pixelFormat The pixel format of source data.
+ * @param[in] imgFormat Encoder's image format.
+ * @param[in] quality Encoding quality.
+ * Valid range of this parameter is @c 1 to @c 100
+ *
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_RANGE One of input paramter is out of range.
+ * @exception E_OVERFLOW The width or height exceeds the limit.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ * @exception E_UNSUPPORTED_FORMAT The @c imgFormat is not supported format.
+ * @exception E_SYSTEM A system error has occurred.
+ * @remarks Only PNG, JPEG, and BMP image format is supported.
+ * @remarks The specific error code can be accessed using the GetLastResult() method.
+ */
+ static Tizen::Base::ByteBuffer*
+ EncodeToBufferN(const Tizen::Base::ByteBuffer &srcBuf,
+ int width, int height, MediaPixelFormat pixelFormat,
+ ImageFormat imgFormat, int quality = 90);
+
+// DO NOT USE these APIs outside of Tizen::Media
+ /**
+ * Encodes the image data
+ *
+ * @return An error code
+ * @param[in] imgFormat Encoder's image format.
+ * @param[in] srcBuf Source raw data
+ * @param[in] srcLength Source data length
+ * @param[in] dim Encode dimension
+ * @param[in] pixelFormat Encode pixel format
+ * @param[out] dstBuf Encoded destination buffer
+ * @param[out] dstLength Destination buffer length
+ * @param[in] quality Encoding quality
+ *
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ static Tizen::Base::ByteBuffer* EncodeN(ImageFormat imgFormat, const byte* srcBuf, int srcLength,
+ int width, int height,
+ MediaPixelFormat pixelFormat, int quality);
+
+ _ImageEncoder(void);
+
+ virtual ~_ImageEncoder(void);
+
+ /**
+ * Initializes this instance of ImageEncode.
+ *
+ * @return An error code
+ * @param[in] format Source image format.
+ * @param[in] dim Encode dimension
+ * @param[in] pixelFormat Encode pixel format
+ * @param[in] quality Encoding quality
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_SYSTEM A system error has occurred.
+ */
+ result Construct(ImageFormat format, int width, int height,
+ MediaPixelFormat pixelFormat, int quality);
+
+ /**
+ * Encodes the image data
+ *
+ * @return The buffer that contains encoded data.
+ * @param[in] srcBuf Source raw data
+ * @param[in] srcLength Source data length
+ * @param[out] dstBuf Encoded destination buffer
+ * @param[out] dstLength Destination buffer length
+ *
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_OUT_OF_MEMORY Memory is insufficient.
+ * @exception E_INVALID_ARG The input parameter is invalid.
+ */
+ Tizen::Base::ByteBuffer* EncodeN(const byte* srcBuf, int srcLength);
+
+private:
+ _ImageEncoder(const _ImageEncoder& enc);
+ _ImageEncoder& operator =(const _ImageEncoder& enc);
+
+ static _IImageEncoder* CreateEncoderN(ImageFormat srcFormat);
+
+ std::unique_ptr<_IImageEncoder> __pEnc;
+ ImageFormat __format;
+ MediaPixelFormat __reqPixelFormat;
+ std::unique_ptr<class _ColorConverter> __pCvt;
+}; // class _ImageEncoderImpl
+
+}}
+
+#endif
--- /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_ImageUtil.h
+ * @brief This is the header file for the _ImageUtil.
+ */
+
+#ifndef _FMEDIA_INTERNAL_IMAGE_UTIL_H_
+#define _FMEDIA_INTERNAL_IMAGE_UTIL_H_
+
+
+#include <FBaseTypes.h>
+#include <FMediaImageTypes.h>
+namespace Tizen { namespace Base {
+class ByteBuffer;
+class String;
+} }
+
+
+namespace Tizen { namespace Media
+{
+
+/**
+ * @class _ImageUtil
+ * @brief This class provides internal APIs for image files, such as alpha channel check.
+ *
+ * This class provides internal methods for image files. @n@n
+ */
+class _OSP_EXPORT_ _ImageUtil
+{
+public:
+ /**
+ * Checks whether the specified image file has alpha channel. @n
+ * Currently, only 32-bit PNG images are supported.
+ *
+ * @return @c true if the image has alpha channel, @n
+ * else @c false
+ * @param[in] srcImagePath The local file path of the image file
+ * @exception E_SUCCESS The method is successful.
+ * @exception E_UNSUPPORTED_FORMAT The image format is not supported.
+ * @exception E_FILE_NOT_FOUND The specified image file cannot be found.
+ * @exception E_OUT_OF_MEMORY The memory is insufficient.
+ * @exception E_SYSTEM A system error has occurred.
+ * @remarks The specific error code can be accessed using the GetLastResult() method.
+ */
+ static bool HasAlphaChannel(const Tizen::Base::String& srcImagePath);
+
+// DO NOT USE these APIs outside of Tizen::Media
+ static result ConvertPixelFormat(const Tizen::Base::ByteBuffer& srcBuf,
+ MediaPixelFormat srcPixelFormat,
+ int width, int height,
+ Tizen::Base::ByteBuffer& destBuf,
+ MediaPixelFormat destPixelFormat);
+
+ static result Resize(const Tizen::Base::ByteBuffer& srcBuf, MediaPixelFormat srcPixelFormat,
+ int srcWidth, int srcHeight,
+ Tizen::Base::ByteBuffer& destBuf,
+ int destWidth, int destHeight);
+
+ static result ResizeBuffer(const byte* pInBuf, MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ byte* pOutBuf, int dstWidth, int dstHeight);
+
+ static result Rotate(const Tizen::Base::ByteBuffer& srcBuf,
+ MediaPixelFormat pixelFormat,
+ int width, int height,
+ Tizen::Base::ByteBuffer& destBuf,
+ ImageRotationType rotate);
+
+ static result RotateBuffer(const byte* srcBuf,
+ MediaPixelFormat pixelFormat,
+ int width, int height,
+ byte* destBuf, int& outWidth, int& outHeight,
+ ImageRotationType rotate);
+
+ static result Flip(const Tizen::Base::ByteBuffer& srcBuf,
+ MediaPixelFormat pixelFormat, int width, int height,
+ Tizen::Base::ByteBuffer& destBuf,
+ ImageFlipType flip);
+
+ static result FlipBuffer(const byte* srcBuf,
+ MediaPixelFormat pixelFormat, int width, int height,
+ byte* destBuf,
+ ImageFlipType flip);
+
+ static int MinImageFormatLength(void);
+
+ static ImageFormat GetImageFormat(const Tizen::Base::ByteBuffer& srcImageBuf);
+
+ static ImageFormat GetImageFormat(const Tizen::Base::String& srcImageFile);
+
+ static bool HasAlphaChannel(const Tizen::Base::ByteBuffer& srcImageBuf);
+
+ static Tizen::Base::ByteBuffer* ResizeN(const Tizen::Base::ByteBuffer &srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ int dstWidth, int dstHeight);
+
+ static Tizen::Base::ByteBuffer* CropN(const Tizen::Base::ByteBuffer &srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ int dstX, int dstY, int dstWidth, int dstHeight);
+
+ static result Crop(const Tizen::Base::ByteBuffer &srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ Tizen::Base::ByteBuffer &dstBuf,
+ int dstX, int dstY, int dstWidth, int dstHeight);
+
+ static result CropBuffer(const byte* srcBuf,
+ MediaPixelFormat pixelFormat,
+ int srcWidth, int srcHeight,
+ byte* dstBuf,
+ int dstX, int dstY, int dstWidth, int dstHeight);
+
+ static int GetBufferSize(MediaPixelFormat pixelFormat, int width, int height);
+
+ static bool IsValidDimension(MediaPixelFormat pixelFormat, int width, int height);
+
+ static int ToFfmpegPixelFormat(MediaPixelFormat pixelFmt);
+
+ static MediaPixelFormat ToMediaPixelFormatFromFfmpeg(int pixelFormat);
+private:
+ _ImageUtil();
+
+ static result Resize8888(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight);
+
+ static result ResizeRGB888(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight);
+
+ static result ResizeRGB565(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight);
+
+ static result ResizeYUV444(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight);
+
+ static result ResizeYUYV422(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight);
+
+ static result ResizeYUV420P(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight);
+
+ static result ResizeNV12(const byte* pDataIn, byte* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight);
+};
+
+}
+}
+
+#endif
--- /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_MediaUtil.h
+ * @brief This file defines the utility functions for the Media framework
+ */
+
+#ifndef _FMEDIA_INTERNAL_MEDIA_UTIL_H_
+#define _FMEDIA_INTERNAL_MEDIA_UTIL_H_
+
+namespace Tizen { namespace Media
+{
+
+class _OSP_EXPORT_ _MediaUtil
+{
+public:
+ static Tizen::Base::ByteBuffer* FileToBufferN(const Tizen::Base::String &path, int maxSize = 0);
+ static result BufferToFile(const Tizen::Base::ByteBuffer &srcBuf,
+ const Tizen::Base::String &dstPath, bool overwrite = true);
+
+private:
+ _MediaUtil(void);
+ ~_MediaUtil(void);
+};
+
+}} // Tizen::Media
+
+#endif // _FMEDIA_INTERNAL_MEDIAUTIL_H_
--- /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_SlpUtil.h
+ * @brief This is the header file for the _SlpUtil.
+ */
+
+#ifndef _FMEDIA_INTERNAL_SLP_UTIL_H_
+#define _FMEDIA_INTERNAL_SLP_UTIL_H_
+
+namespace Tizen { namespace Media
+{
+
+/**
+ * Provides core functionalities of SLP Osp format conversion.
+ */
+class _OSP_EXPORT_ _SlpUtil
+{
+public:
+ static image_util_colorspace_e ToColorspace(MediaPixelFormat pixelFormat);
+ static image_util_rotation_e ToRotation(ImageRotationType type);
+ static image_util_rotation_e ToRotation(ImageFlipType type);
+ static mm_util_img_format ToMmUtilImgFormat(MediaPixelFormat pixelFormat);
+ static mm_util_img_rotate_type ToMmUtilRotateType(ImageFlipType type);
+ static mm_util_img_rotate_type ToMmUtilRotateType(ImageRotationType type);
+
+};
+
+}
+}
+
+#endif // _FMEDIA_INTERNAL_SLP_UTIL_H_