From: MyungJoo Ham Date: Fri, 1 Jul 2022 06:51:55 +0000 (+0900) Subject: Add bmp2png utility. X-Git-Tag: accepted/tizen/7.0/unified/20221110.061323^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Faccepted%2Ftizen_7.0_unified;p=platform%2Fupstream%2FSSAT.git Add bmp2png utility. SSAT API has bmp2png, which is supposed to be installed by SSAT user. However, this introduces circular dependency; thus, it is refactored to have bmp2png in SSAT as a utility. Signed-off-by: MyungJoo Ham --- diff --git a/README.md b/README.md index b53f0bc..9f84310 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,11 @@ # SSAT Shell Script Automated Tester (unit testing executable files) + + +## Files + +ssat.sh: the main executable (bash script) + +ssat-api.sh: API function definitions that user script can use. + +util/: utility binaries for extended features usually implemented for nnstreamer/nntrainer community. diff --git a/debian/control b/debian/control index ed33462..64b7cab 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: ssat Section: devel Priority: optional Maintainer: MyungJoo Ham -Build-Depends: bash, debhelper (>=9) +Build-Depends: bash, debhelper (>=9), meson (>=0.50), ninja-build, libpng-dev, libglib2.0-dev, Standards-Version: 3.9.6 Homepage: https://github.com/myungjoo/SSAT/ diff --git a/debian/rules b/debian/rules index 9ab59f3..ae4ea45 100755 --- a/debian/rules +++ b/debian/rules @@ -16,7 +16,14 @@ %: dh $@ +override_dh_auto_configure: + mkdir -p build + meson --buildtype=plain --prefix=/usr --bindir=bin build util +override_dh_auto_build: + ninja -C build override_dh_auto_clean: rm -f ssat + rm -f build override_dh_auto_install: + DESTDIR=$(CURDIR)/debian/tmp ninja -C build install ln -s ssat.sh ssat diff --git a/debian/ssat.install b/debian/ssat.install index fbe115c..9647864 100644 --- a/debian/ssat.install +++ b/debian/ssat.install @@ -1,3 +1,4 @@ ssat.sh usr/bin ssat-api.sh usr/bin ssat usr/bin +/usr/bin/bmp2png diff --git a/packaging/ssat.spec b/packaging/ssat.spec index 70ddb37..61e4c39 100644 --- a/packaging/ssat.spec +++ b/packaging/ssat.spec @@ -1,17 +1,22 @@ Name: ssat Summary: Shell Script Automated Tester -Version: 1.2.0 -Release: 1 +Version: 1.3.0 +Release: 0 Group: Development/Tools Packager: MyungJoo Ham License: Apache-2.0 Source0: ssat-%{version}.tar.gz Source1001: ssat.manifest -BuildArch: noarch Requires: bash Requires: perl +## For the utility +BuildRequires: meson +BuildRequires: ninja +BuildRequires: pkgconfig(libpng) +BuildRequires: glib2-devel + %description SSAT provides testing environment for shell scripts with Apache-2.0 license. This is created to avoid any complications related with GPL licenses. @@ -21,7 +26,9 @@ This is created to avoid any complications related with GPL licenses. cp %{SOURCE1001} . %build -# DO NOTHING +# Utilities +meson --prefix=%{_prefix} --bindir=bin build util +ninja -C build %install mkdir -p %{buildroot}%{_bindir} @@ -30,9 +37,11 @@ install -p -m 0644 ssat-api.sh %{buildroot}%{_bindir}/ pushd %{buildroot}%{_bindir} ln -s ssat.sh ssat popd +DESTDIR=%{buildroot} ninja -C build install %files %manifest ssat.manifest %{_bindir}/ssat %{_bindir}/ssat.sh %{_bindir}/ssat-api.sh +%{_bindir}/bmp2png diff --git a/util/bmp2png.c b/util/bmp2png.c new file mode 100644 index 0000000..b822144 --- /dev/null +++ b/util/bmp2png.c @@ -0,0 +1,301 @@ +// SPDX-License-Identifier: Apache-2.0 +/** + * BMP2PNG Converter with libpng + * Copyright (C) 2018 MyungJoo Ham + */ +/** + * @file bmp2png.c + * @date 13 Jul 2018 + * @brief Simple bmp2png converter for testcases + * @see http://github.com/nnstreamer/nnstreamer + * @author MyungJoo Ham + * @bug No known bugs except for NYI items + * + * This converts bmp files created by gen24bBMP.py. + * This won't support general bmp files. + * + * Adopted code from https://www.lemoda.net/c/write-png/ + * The author, "Ben Bullock ", has authorized + * to adopt the code as LGPL-2.1 on 2018-07-13 + * + * Then, migrated code from https://github.com/nnstreamer/nnstreamer + * by the author, "MyungJoo Ham ", changing + * the licence to Apache 2.0 + */ + +#include +#include +#include +#include +#include +#include + +typedef enum +{ + RGB = 0, + GRAY8, +} colorformat_t; + +typedef union +{ + struct + { + uint8_t red; + uint8_t green; + uint8_t blue; + }; + struct + { + uint8_t gray; + }; +} pixel_t; + +typedef struct +{ + pixel_t *pixels; + size_t width; + size_t height; + colorformat_t color_format; +} bitmap_t; + +/** + * @brief Given "bitmap", this returns the pixel of bitmap at the point + * ("x", "y"). + */ +static pixel_t * +pixel_at (bitmap_t * bitmap, int x, int y) +{ + return bitmap->pixels + bitmap->width * y + x; +} + +/** + * @brief Write "bitmap" to a PNG file specified by "path" + * @return 0 on success, non-zero on error. + */ +static int +save_png_to_file (bitmap_t * bitmap, const char *path) +{ + FILE *fp; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + size_t x, y; + png_byte **row_pointers = NULL; + /** + * "status" contains the return value of this function. At first + * it is set to a value which means 'failure'. When the routine + * has finished its work, it is set to a value which means + * 'success'. + */ + int status = -1; + /** + * The following number is set by trial and error only. I cannot + * see where it it is documented in the libpng manual. + */ + int pixel_size; + int depth = 8; + int color_type; + + fp = fopen (path, "wb"); + if (!fp) { + goto fopen_failed; + } + + png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) { + goto png_create_write_struct_failed; + } + + info_ptr = png_create_info_struct (png_ptr); + if (info_ptr == NULL) { + goto png_create_info_struct_failed; + } + + /** Set up error handling. */ + + if (setjmp (png_jmpbuf (png_ptr))) { + status = -1; + goto png_failure; + } + + /** Set image attributes. */ + if (bitmap->color_format == GRAY8) { + pixel_size = 1; + color_type = PNG_COLOR_TYPE_GRAY; + } else { + pixel_size = 3; + color_type = PNG_COLOR_TYPE_RGB; + } + + png_set_IHDR (png_ptr, + info_ptr, + bitmap->width, + bitmap->height, + depth, + color_type, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + /** Initialize rows of PNG. */ + row_pointers = png_malloc (png_ptr, bitmap->height * sizeof (png_byte *)); + g_assert (row_pointers != NULL); + for (y = 0; y < bitmap->height; y++) { + png_byte *row = + png_malloc (png_ptr, sizeof (uint8_t) * bitmap->width * pixel_size); + g_assert (row != NULL); + row_pointers[y] = row; + for (x = 0; x < bitmap->width; x++) { + pixel_t *pixel = pixel_at (bitmap, x, y); + if (bitmap->color_format == GRAY8) { + *row++ = pixel->gray; + } else { + *row++ = pixel->red; + *row++ = pixel->green; + *row++ = pixel->blue; + } + } + } + + /** Write the image data to "fp". */ + + png_init_io (png_ptr, fp); + png_set_rows (png_ptr, info_ptr, row_pointers); + png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + + /** + * The routine has successfully written the file, so we set + * "status" to a value which indicates success. + */ + + status = 0; + + for (y = 0; y < bitmap->height; y++) { + png_free (png_ptr, row_pointers[y]); + } + png_free (png_ptr, row_pointers); + +png_failure: +png_create_info_struct_failed: + png_destroy_write_struct (&png_ptr, &info_ptr); +png_create_write_struct_failed: + fclose (fp); +fopen_failed: + return status; +} + +/** + * @brief The main function, provide filename of a bmp file as the 1st argument. + */ +int +main (int argc, char *argv[]) +{ + const char option_gray[] = "--GRAY8"; + FILE *bmpF; + bitmap_t bmp; + int x, y; + uint16_t width, height, *ptr16; + size_t size; + char byte; + char header[26]; /** gen24bBMP.py gives you 24B headered bmp file */ + int ret; + char *pngfilename; + unsigned int strn; + + /** Read the .bmp file (argv[1]) */ + if (argc < 2 || argc > 3) { + printf ("Usage: %s BMPfilename [OPTION:--GRAY8]\n\n", argv[0]); + return 1; + } + strn = strlen (argv[1]); + if (strn < 5 || argv[1][strn - 4] != '.' || argv[1][strn - 3] != 'b' || + argv[1][strn - 2] != 'm' || argv[1][strn - 1] != 'p') { + printf ("The BMPfilename must be ending with \".bmp\"\n\n"); + return 1; + } + /** Check the option, --GRAY8 */ + strn = strlen (option_gray); + if ((argc == 3) && (strlen (argv[2]) == strn) + && (!strncmp (option_gray, argv[2], strn))) { + bmp.color_format = GRAY8; + } else { + bmp.color_format = RGB; + } + + bmpF = fopen (argv[1], "rb"); + if (!bmpF) { + printf ("Cannot open the file: %s\n", argv[1]); + return 2; + } + + size = fread (header, 1, 26, bmpF); + if (size != 26) { + printf ("Cannot read the header from the file: %s\n", argv[1]); + fclose (bmpF); + return 3; + } + + ptr16 = (uint16_t *) & (header[18]); + width = *ptr16; + ptr16 = (uint16_t *) & (header[20]); + height = *ptr16; + + /** Let's not accept BMP files larger than 10000 x 10000 (Fix Covertify Issue #1029514) */ + if (width > 10000 || height > 10000 || width < 4 || height < 4) { + printf + ("We do not accept BMP files with height or width larger than 10000.\n"); + fclose (bmpF); + return 100; + } + bmp.width = width; + bmp.height = height; + + bmp.pixels = calloc (bmp.width * bmp.height, sizeof (pixel_t)); + g_assert (bmp.pixels != NULL); + + for (y = (int) height - 1; y >= 0; y--) { + for (x = 0; x < (int) width; x++) { + pixel_t *pixel = pixel_at (&bmp, x, y); + if (bmp.color_format == GRAY8) { + uint8_t gray; + size = fread (&gray, 1, 1, bmpF); + if (size != 1) { + printf ("x = %d / y = %d / (%d,%d) / size = %zu\n", x, y, width, + height, size); + goto error; + } + pixel->gray = gray; + } else { + uint8_t bgr[3]; + size = fread (bgr, 1, 3, bmpF); + if (size != 3) { + printf ("x = %d / y = %d / (%d,%d) / size = %zu\n", x, y, width, + height, size); + goto error; + } + pixel->red = bgr[2]; + pixel->green = bgr[1]; + pixel->blue = bgr[0]; + } + } + for (x = 0; x < (width * 3) % 4; x++) { + size = fread (&byte, 1, 1, bmpF); + /** Go through zero padding */ + if (size != 1) + goto error; + } + } + fclose (bmpF); + + pngfilename = g_strdup (argv[1]); + + /** Assume the last 4 characters are ".bmp" */ + strncpy (pngfilename + strlen (argv[1]) - 4, ".png", 5); + ret = save_png_to_file (&bmp, pngfilename); + free (bmp.pixels); + + return ret; +error: + printf ("File read size error.\n"); + free (bmp.pixels); + fclose (bmpF); + return 10; +} diff --git a/util/meson.build b/util/meson.build new file mode 100644 index 0000000..2fcb289 --- /dev/null +++ b/util/meson.build @@ -0,0 +1,26 @@ +# Build utility binaries for SSAT APIs. +project('ssat-util', 'c', + version: '1.3.0', + license: ['Apache-2.0'], + meson_version: '>=0.50.0', + default_options: [ + 'werror=true', + 'warning_level=2', + 'c_std=gnu89', + 'cpp_std=c++14' + ] +) + +cc = meson.get_compiler('c') + + +################################################# +# bmp2png +################################################# +libpng_dep = dependency('libpng', required: true) +glib_dep = dependency('glib-2.0', required: true) +b2p = executable('bmp2png', + 'bmp2png.c', + dependencies: [libpng_dep, glib_dep], + install: true, +)