From 2a1f031ba8adbeb3335f79889a14f65f7a5dc76b Mon Sep 17 00:00:00 2001 From: Vineeth TM Date: Wed, 2 Dec 2015 13:59:52 +0900 Subject: [PATCH] libmmutility: Add bmp encode/decode utility Change-Id: I4c218d4cd0aeef436bc8236a2c6572f17be7a9eb Signed-off-by: Vineeth TM --- Makefile.am | 6 +- bmp/Makefile.am | 33 +++++ bmp/include/mm_util_bmp.h | 157 +++++++++++++++++++++++ bmp/mm_util_bmp.c | 261 +++++++++++++++++++++++++++++++++++++++ bmp/mmutil-bmp.pc.in | 12 ++ bmp/test/Makefile.am | 16 +++ bmp/test/mm_util_bmp_testsuite.c | 81 ++++++++++++ configure.ac | 3 + packaging/libmm-utility.spec | 3 + 9 files changed, 570 insertions(+), 2 deletions(-) create mode 100644 bmp/Makefile.am create mode 100755 bmp/include/mm_util_bmp.h create mode 100755 bmp/mm_util_bmp.c create mode 100644 bmp/mmutil-bmp.pc.in create mode 100755 bmp/test/Makefile.am create mode 100755 bmp/test/mm_util_bmp_testsuite.c diff --git a/Makefile.am b/Makefile.am index 9a13337..51cf6a7 100755 --- a/Makefile.am +++ b/Makefile.am @@ -8,14 +8,16 @@ SUBDIRS = \ jpeg \ imgcv \ png \ - gif + gif \ + bmp DIST_SUBDIRS = \ imgp \ jpeg \ imgcv \ png \ - gif + gif \ + bmp EXTRA_DIST = \ configure.ac autogen.sh depcomp diff --git a/bmp/Makefile.am b/bmp/Makefile.am new file mode 100644 index 0000000..43f8a86 --- /dev/null +++ b/bmp/Makefile.am @@ -0,0 +1,33 @@ +ACLOCAL_AMFLAGS='-I m4' + +lib_LTLIBRARIES = libmmutil_bmp.la + +installmmutil_bmpdir = $(includedir)/mmf +installmmutil_bmp_HEADERS = include/mm_util_bmp.h + +libmmutil_bmp_la_SOURCES = mm_util_bmp.c + +libmmutil_bmp_la_CFLAGS = -I$(srcdir)/include \ + -I$(srcdir)/../imgp/include \ + $(GLIB_CFLAGS) \ + $(MEDIA_CFLAGS) \ + $(MMCOMMON_CFLAGS) \ + -I/usr/include \ + $(SYSTEMINFO_CFLAGS) \ + $(srcdir)/../imgp/libmmutil_imgp.la + +libmmutil_bmp_la_LIBADD = $(MMCOMMON_LIBS) -lnsbmp -lbmp -ldl -lexif -lttrace\ + $(GLIB_LIBS) \ + $(GMODULE_LIBS) \ + $(SYSTEMINFO_LIBS)\ + $(MEDIA_LIBS) + +libmmutil_bmp_la_CFLAGS += $(MMLOG_CFLAGS) -DMMF_LOG_OWNER=0x0100 -DMMF_DEBUG_PREFIX=\"MMF-IMAGE\" + +libmmutil_bmp_la_DEPENDENCIES = $(srcdir)/../imgp/libmmutil_imgp.la + +pcfiles = mmutil-bmp.pc +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = $(pcfiles) +EXTRA_DIST = $(pcfiles) +SUBDIRS = . test diff --git a/bmp/include/mm_util_bmp.h b/bmp/include/mm_util_bmp.h new file mode 100755 index 0000000..0c7df2c --- /dev/null +++ b/bmp/include/mm_util_bmp.h @@ -0,0 +1,157 @@ +/* + * libmm-utility + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Vineeth T M + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __MM_UTIL_BMP_H__ +#define __MM_UTIL_BMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "libnsbmp.h" +#include "bmpfile.h" + +/** + @addtogroup UTILITY + @{ + + @par + This part describes the APIs with repect to multimedia image library. +*/ + +/** + * format for bmp + */ +typedef enum +{ + MM_UTIL_BMP_FMT_RGBA8888, /**< RGBA8888 format */ +} mm_util_bmp_format; + +typedef struct { + unsigned long width; /**< width */ + unsigned long height; /**< height */ + unsigned long long size; /**< size */ + void *data; /**< data */ +} mm_util_bmp_data; + +/** + * This function extracts raw data from bmp file + * + * @param decoded [out] pointer of mm_util_bmp_data. + * After using it, please free the allocated memory. + * @param filename [in] input file name, encoded stream file + * @return This function returns zero on success, or negative value with error code. + * @remark + * @see mm_util_bmp_data + * @since R1, 1.0 + */ +int mm_util_decode_from_bmp_file(mm_util_bmp_data * decoded, const char *filename); + +/** + * This function extracts raw data from bmp memory + * + * @param decoded [out] pointer of mm_util_bmp_data. + * After using it, please free the allocated memory. + * @param memory [in] input memory, encoded stream file + * @param src_size [in] input src size, encoded stream file + * @return This function returns zero on success, or negative value with error code. + * @remark + * @see mm_util_bmp_data + * @since R1, 1.0 + */ +int mm_util_decode_from_bmp_memory(mm_util_bmp_data * decoded, void **memory, unsigned long long src_size); + +/** + * This function gets the width of the decoded image. + * This should be called after the actual decoding. + * + * @param data [in] pointer of mm_util_bmp_data. + * @return Width of the decoded image. + * @remark + * @see mm_util_bmp_data + * @since R1, 1.0 + */ +unsigned long mm_util_bmp_decode_get_width(mm_util_bmp_data * data); + +/** + * This function gets the height of the decoded image. + * This should be called after the actual decoding. + * + * @param data [in] pointer of mm_util_bmp_data. + * @return Height of the decoded image. + * @remark + * @see mm_util_bmp_data + * @since R1, 1.0 + */ +unsigned long mm_util_bmp_decode_get_height(mm_util_bmp_data * data); + +/** + * This function gets the size of the decoded image. + * This should be called after the actual decoding. + * + * @param data [in] pointer of mm_util_bmp_data. + * @return Size of the decoded image. + * @remark + * @see mm_util_bmp_data + * @since R1, 1.0 + */ +unsigned long long mm_util_bmp_decode_get_size(mm_util_bmp_data * data); + +/** + * This function encodes raw data to bmp file + * + * @param encoded [in ] pointer of mm_util_bmp_data. + * After using it, please free the allocated memory. + * @param filename [out] output file name on to which the encoded stream will be written. + * @return This function returns zero on success, or negative value with error code. + * @remark + * @see mm_util_bmp_data + * @since R1, 1.0 + */ +int mm_util_encode_bmp_to_file(mm_util_bmp_data * encoded, const char *filename); + +/** + * This function sets width of the encoded image. + * + * @param data [in] pointer of mm_util_bmp_data. + * @param width [in] width of the encoded image. + * @return None. + * @remark + * @see mm_util_bmp_data + * @since R1, 1.0 + */ +void mm_util_bmp_encode_set_width(mm_util_bmp_data * data, unsigned long width); + +/** + * This function sets height of the encoded image. + * + * @param data [in] pointer of mm_util_bmp_data. + * @param height [in] height of the encoded image. + * @return None. + * @remark + * @see mm_util_bmp_data + * @since R1, 1.0 + */ +void mm_util_bmp_encode_set_height(mm_util_bmp_data * data, unsigned long height); + +#ifdef __cplusplus +} +#endif +#endif /*__MM_UTIL_BMP_H__*/ diff --git a/bmp/mm_util_bmp.c b/bmp/mm_util_bmp.c new file mode 100755 index 0000000..5d4d5af --- /dev/null +++ b/bmp/mm_util_bmp.c @@ -0,0 +1,261 @@ +/* + * libmm-utility + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Vineeth T M + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* fopen() */ +#include +#include + +#include +#include +#include + +#include "mm_util_bmp.h" + +#define BYTES_PER_PIXEL 4 + +void *bitmap_create(int width, int height, unsigned int state); +unsigned char *bitmap_get_buffer(void *bitmap); +size_t bitmap_get_bpp(void *bitmap); +void bitmap_destroy(void *bitmap); + +unsigned char *load_file(const char *path, size_t * data_size) +{ + FILE *fd; + struct stat sb; + unsigned char *buffer; + size_t size; + size_t n; + + fd = fopen(path, "rb"); + if (!fd) { + debug_error("file open failed"); + return NULL; + } + + if (stat(path, &sb)) { + debug_error("file stat failed"); + fclose(fd); + return NULL; + } + size = sb.st_size; + + buffer = malloc(size); + if (!buffer) { + debug_error("Unable to allocate %lld bytes", (long long)size); + fclose(fd); + return NULL; + } + + n = fread(buffer, 1, size, fd); + if (n != size) { + debug_error("file read failed"); + free(buffer); + return NULL; + } + + fclose(fd); + *data_size = size; + return buffer; +} + +void print_error(const char *context, bmp_result code) +{ + switch (code) { + case BMP_INSUFFICIENT_MEMORY: + debug_error("%s failed: BMP_INSUFFICIENT_MEMORY", context); + break; + case BMP_INSUFFICIENT_DATA: + debug_error("%s failed: BMP_INSUFFICIENT_DATA", context); + break; + case BMP_DATA_ERROR: + debug_error("%s failed: BMP_DATA_ERROR", context); + break; + default: + debug_error("%s failed: unknown code %i", context, code); + break; + } +} + +void *bitmap_create(int width, int height, unsigned int state) +{ + return calloc(width * height, BYTES_PER_PIXEL); +} + +unsigned char *bitmap_get_buffer(void *bitmap) +{ + return bitmap; +} + +size_t bitmap_get_bpp(void *bitmap) +{ + return BYTES_PER_PIXEL; +} + +void bitmap_destroy(void *bitmap) +{ + free(bitmap); +} + +static int read_bmp(mm_util_bmp_data * decoded, const char *filename, void *memory, unsigned long long src_size) +{ + bmp_bitmap_callback_vt bitmap_callbacks = { + bitmap_create, + bitmap_destroy, + bitmap_get_buffer, + bitmap_get_bpp + }; + bmp_result code; + bmp_image bmp; + size_t size; + int res = MM_ERROR_NONE; + unsigned char *data = NULL; + + if (filename) { + data = load_file(filename, &size); + if (data == NULL) + return MM_ERROR_IMAGE_INTERNAL; + } else if (memory) { + data = (unsigned char *)memory; + size = src_size; + } else { + debug_error("Bmp File wrong decode parameters"); + return MM_ERROR_IMAGE_INTERNAL; + } + + nsbmp_create(&bmp, &bitmap_callbacks); + + code = bmp_analyse(&bmp, size, data); + if (code != BMP_OK) { + print_error("bmp_analyse", code); + res = MM_ERROR_IMAGE_INTERNAL; + goto cleanup; + } + + code = bmp_decode(&bmp); + + if (code != BMP_OK) { + print_error("bmp_decode", code); + /* allow partially decoded images */ + if (code != BMP_INSUFFICIENT_DATA) { + res = MM_ERROR_IMAGE_INTERNAL; + goto cleanup; + } + } + + decoded->width = bmp.width; + decoded->height = bmp.height; + decoded->size = bmp.width * bmp.height * BYTES_PER_PIXEL; + decoded->data = malloc(decoded->size); + memcpy(decoded->data, bmp.bitmap, decoded->size); + + cleanup: + bmp_finalise(&bmp); + if (filename) + free(data); + return res; +} + +int mm_util_decode_from_bmp_file(mm_util_bmp_data * decoded, const char *filename) +{ + int ret; + + debug_log("mm_util_decode_from_gif_file"); + + ret = read_bmp(decoded, filename, NULL, 0); + + return ret; +} + +int mm_util_decode_from_bmp_memory(mm_util_bmp_data * decoded, void **memory, unsigned long long src_size) +{ + int ret; + + debug_log("mm_util_decode_from_gif_file"); + + ret = read_bmp(decoded, NULL, *memory, src_size); + + return ret; +} + +unsigned long mm_util_decode_get_width(mm_util_bmp_data * data) +{ + return data->width; +} + +unsigned long mm_util_decode_get_height(mm_util_bmp_data * data) +{ + return data->height; +} + +unsigned long long mm_util_decode_get_size(mm_util_bmp_data * data) +{ + return data->size; +} + +int mm_util_encode_bmp_to_file(mm_util_bmp_data * encoded, const char *filename) +{ + bmpfile_t *bmp; + rgb_pixel_t pixel = { 0, 0, 0, 0 }; + uint16_t row, col; + uint8_t *image; + + if ((bmp = bmp_create(encoded->width, encoded->height, BYTES_PER_PIXEL * 8)) == NULL) { + printf("Invalid depth value.\n"); + return MM_ERROR_IMAGE_INTERNAL; + } + + image = (uint8_t *) encoded->data; + for (row = 0; row != encoded->height; row++) { + for (col = 0; col != encoded->width; col++) { + size_t z = (row * encoded->width + col) * BYTES_PER_PIXEL; + pixel.red = image[z]; + pixel.green = image[z + 1]; + pixel.blue = image[z + 2]; + bmp_set_pixel(bmp, col, row, pixel); + } + } + + bmp_save(bmp, filename); + bmp_destroy(bmp); + return MM_ERROR_NONE; +} + +void mm_util_bmp_encode_set_width(mm_util_bmp_data * data, unsigned long width) +{ + data->width = width; +} + +void mm_util_bmp_encode_set_height(mm_util_bmp_data * data, unsigned long height) +{ + data->height = height; +} diff --git a/bmp/mmutil-bmp.pc.in b/bmp/mmutil-bmp.pc.in new file mode 100644 index 0000000..38cb6a2 --- /dev/null +++ b/bmp/mmutil-bmp.pc.in @@ -0,0 +1,12 @@ +prefix = @prefix@ +exec_prefix=@exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +Name : mmutil-bmp +Description : Multimedia Framework Utility Library +Requires : @BMP_REQPKG@ +Version : @VERSION@ +Libs : -L${libdir} -lmmutil_bmp +Cflags : -I${includedir}/mmf + diff --git a/bmp/test/Makefile.am b/bmp/test/Makefile.am new file mode 100755 index 0000000..13240a6 --- /dev/null +++ b/bmp/test/Makefile.am @@ -0,0 +1,16 @@ +bin_PROGRAMS = mm_util_bmp_testsuite + +mm_util_bmp_testsuite_SOURCES = mm_util_bmp_testsuite.c + +mm_util_bmp_testsuite_CFLAGS = -I$(srcdir)/../include +mm_util_bmp_testsuite_CFLAGS += $(MMCOMMON_CFLAGS) \ + $(MMLOG_CFLAGS) -DMMF_LOG_OWNER=0x0100 -DMMF_DEBUG_PREFIX=\"MMF-IMAGE\" -fPIE -pie + + +############################################ + +mm_util_bmp_testsuite_DEPENDENCIES = $(srcdir)/../libmmutil_bmp.la + +mm_util_bmp_testsuite_LDADD = $(srcdir)/../libmmutil_bmp.la +mm_util_bmp_testsuite_LDADD += $(MMCOMMON_LIBS) + diff --git a/bmp/test/mm_util_bmp_testsuite.c b/bmp/test/mm_util_bmp_testsuite.c new file mode 100755 index 0000000..048a243 --- /dev/null +++ b/bmp/test/mm_util_bmp_testsuite.c @@ -0,0 +1,81 @@ +/* + * libmm-utility + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Vineeth T M + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DECODE_RESULT_PATH "/opt/usr/media/decode_test." +#define BUFFER_SIZE 128 + +static inline void flush_stdin() +{ + int ch; + while ((ch = getchar()) != EOF && ch != '\n') ; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + mm_util_bmp_data decoded; + + if (argc < 2) { + fprintf(stderr, "\t[usage]\n"); + fprintf(stderr, "\t\t1. decode : mm_util_bmp_testsuite decode filepath.bmp\n"); + return 0; + } + + if (!strcmp("decode", argv[1])) { + ret = mm_util_decode_from_bmp_file(&decoded, argv[2]); + } else { + fprintf(stderr, "\tunknown command [%s]\n", argv[1]); + return 0; + } + + if (ret != MM_ERROR_NONE) { + fprintf(stderr, "\tERROR is occurred %x\n", ret); + } else { + fprintf(stderr, "\tBMP OPERATION SUCCESS\n"); + { + if (decoded.data) { + fprintf(stderr, "\t##Decoded data##: %p\t width: %lu\t height:%lu\t size: %llu\n", decoded.data, decoded.width, decoded.height, decoded.size); + char filename[BUFFER_SIZE] = { 0, }; + memset(filename, 0, BUFFER_SIZE); + { + snprintf(filename, BUFFER_SIZE, "%s%s", DECODE_RESULT_PATH, "bmp"); + } + + ret = mm_util_encode_bmp_to_file(&decoded, filename); + + free(decoded.data); + } else { + fprintf(stderr, "\tDECODED data is NULL\n"); + } + } + } + return 0; +} diff --git a/configure.ac b/configure.ac index 4321687..8b3c779 100755 --- a/configure.ac +++ b/configure.ac @@ -89,6 +89,9 @@ AC_CONFIG_FILES([Makefile gif/Makefile gif/test/Makefile gif/mmutil-gif.pc + bmp/Makefile + bmp/test/Makefile + bmp/mmutil-bmp.pc test/Makefile ]) diff --git a/packaging/libmm-utility.spec b/packaging/libmm-utility.spec index ea25002..4a5c07d 100755 --- a/packaging/libmm-utility.spec +++ b/packaging/libmm-utility.spec @@ -22,6 +22,8 @@ BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(ttrace) BuildRequires: libpng-devel BuildRequires: giflib-devel +BuildRequires: libbmp-devel +BuildRequires: libnsbmp-devel BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -63,6 +65,7 @@ sed -i -e "s#@JPEG_REQPKG@#$JPEG_REQPKG#g" jpeg/mmutil-jpeg.pc sed -i -e "s#@IMGCV_REQPKG@#$IMGCV_REQPKG#g" imgcv/mmutil-imgcv.pc sed -i -e "s#@PNG_REQPKG@#$PNG_REQPKG#g" png/mmutil-png.pc sed -i -e "s#@GIF_REQPKG@#$GIF_REQPKG#g" gif/mmutil-gif.pc +sed -i -e "s#@BMP_REQPKG@#$BMP_REQPKG#g" bmp/mmutil-bmp.pc %install rm -rf %{buildroot} -- 2.7.4