Add bmp2png utility. accepted/tizen_7.0_unified accepted/tizen_7.0_unified_hotfix tizen_7.0 tizen_7.0_hotfix accepted/tizen/7.0/unified/20221110.061323 accepted/tizen/7.0/unified/hotfix/20221116.110552 accepted/tizen/unified/20220707.133437 submit/tizen/20220706.044004 tizen_7.0_m2_release
authorMyungJoo Ham <myungjoo.ham@samsung.com>
Fri, 1 Jul 2022 06:51:55 +0000 (15:51 +0900)
committerMyungJoo Ham <myungjoo.ham@samsung.com>
Wed, 6 Jul 2022 04:38:49 +0000 (13:38 +0900)
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 <myungjoo.ham@samsung.com>
README.md
debian/control
debian/rules
debian/ssat.install
packaging/ssat.spec
util/bmp2png.c [new file with mode: 0644]
util/meson.build [new file with mode: 0644]

index b53f0bc..9f84310 100644 (file)
--- 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.
index ed33462..64b7cab 100644 (file)
@@ -2,7 +2,7 @@ Source: ssat
 Section: devel
 Priority: optional
 Maintainer: MyungJoo Ham <myungjoo.ham@samsung.com>
-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/
 
index 9ab59f3..ae4ea45 100755 (executable)
 %:
        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
index fbe115c..9647864 100644 (file)
@@ -1,3 +1,4 @@
 ssat.sh usr/bin
 ssat-api.sh usr/bin
 ssat usr/bin
+/usr/bin/bmp2png
index 70ddb37..61e4c39 100644 (file)
@@ -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 <myungjoo.ham@samsung.com>
 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 (file)
index 0000000..b822144
--- /dev/null
@@ -0,0 +1,301 @@
+// SPDX-License-Identifier: Apache-2.0
+/**
+ * BMP2PNG Converter with libpng
+ * Copyright (C) 2018 MyungJoo Ham <myungjoo.ham@samsung.com>
+ */
+/**
+ * @file       bmp2png.c
+ * @date       13 Jul 2018
+ * @brief      Simple bmp2png converter for testcases
+ * @see                http://github.com/nnstreamer/nnstreamer
+ * @author     MyungJoo Ham <myungjoo.ham@samsung.com>
+ * @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 <benkasminbullock@gmail.com>", 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 <myungjoo.ham@samsung.com>", changing
+ * the licence to Apache 2.0
+ */
+
+#include <png.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <glib.h>
+
+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 (file)
index 0000000..2fcb289
--- /dev/null
@@ -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,
+)