]> mj.ucw.cz Git - libucw.git/blobdiff - images/image-test.c
Opt: Documented opt and its interaction with conf
[libucw.git] / images / image-test.c
index 1e49d284dd1b66d68044aff9bcf397bc9de9b440..aeae9dd2380f9f43cde72ffd792282ff7cb102cb 100644 (file)
+/*
+ *     Image Library -- Simple automatic tests
+ *
+ *     (c) 2006 Pavel Charvat <pchar@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
 #undef LOCAL_DEBUG
 
-#include "lib/lib.h"
-#include "lib/mempool.h"
-#include "images/images.h"
+#include <ucw/lib.h>
+#include <ucw/mempool.h>
+#include <ucw/fastbuf.h>
+#include <ucw/threads.h>
+#include <images/images.h>
+#include <images/color.h>
+
+#include <stdlib.h>
 #include <string.h>
+#include <pthread.h>
+#include <time.h>
+#include <unistd.h>
 
 static uns want_image_iface;
+static uns want_threads;
+
+#define TRY(x) do { if (!(x)) ASSERT(0); } while (0)
 
 static void
 test_image_iface(void)
 {
   struct mempool *pool;
-  struct image_thread it;
+  struct image_context ctx;
   struct image *i1, *i2;
   struct image s1;
-  int i;
 
   pool = mp_new(1024);
-  image_thread_init(&it);
+  image_context_init(&ctx);
 
-  i1 = image_new(&it, 731, 327, COLOR_SPACE_RGB, NULL);
+  /* Image allocation */
+  i1 = image_new(&ctx, 731, 327, COLOR_SPACE_RGB, NULL);
   ASSERT(i1);
   ASSERT(i1->pixel_size == 3);
   image_destroy(i1);
 
-  i1 = image_new(&it, 2214, 0, COLOR_SPACE_RGB, NULL);
+  /* Test invalid image size  */
+  ctx.msg_callback = image_context_msg_silent;
+  i1 = image_new(&ctx, 2214, 0, COLOR_SPACE_RGB, NULL);
   ASSERT(!i1);
-
-  i1 = image_new(&it, 0xffffff, 0xffffff, COLOR_SPACE_RGB, NULL);
+  i1 = image_new(&ctx, 0xffffff, 0xffffff, COLOR_SPACE_RGB, NULL);
   ASSERT(!i1);
+  ctx.msg_callback = image_context_msg_default;
 
-  i1 = image_new(&it, 370, 100, COLOR_SPACE_GRAYSCALE, pool);
+  /* Various image allocatio parameters */
+  i1 = image_new(&ctx, 370, 100, COLOR_SPACE_GRAYSCALE, pool);
   ASSERT(i1);
   ASSERT(i1->pixel_size == 1);
   image_destroy(i1);
   mp_flush(pool);
 
-  i1 = image_new(&it, 373, 101, COLOR_SPACE_RGB | IMAGE_ALIGNED, NULL);
+  i1 = image_new(&ctx, 373, 101, COLOR_SPACE_RGB | IMAGE_ALIGNED, NULL);
   ASSERT(i1);
   ASSERT(i1->pixel_size == 4);
   ASSERT(IMAGE_SSE_ALIGN_SIZE >= 16);
   ASSERT(!(i1->row_size & (IMAGE_SSE_ALIGN_SIZE - 1)));
-  ASSERT(!((addr_int_t)i1->pixels & (IMAGE_SSE_ALIGN_SIZE - 1)));
+  ASSERT(!((uintptr_t)i1->pixels & (IMAGE_SSE_ALIGN_SIZE - 1)));
   image_destroy(i1);
 
-  i1 = image_new(&it, 283, 329, COLOR_SPACE_RGB, NULL);
+  i1 = image_new(&ctx, 283, 329, COLOR_SPACE_RGB, NULL);
   ASSERT(i1);
   ASSERT(i1->pixel_size == 3);
 
-  i2 = image_clone(&it, i1, COLOR_SPACE_RGB, NULL);
+  /* Image structures cloning */
+  i2 = image_clone(&ctx, i1, COLOR_SPACE_RGB, NULL);
   ASSERT(i2);
   ASSERT(i2->pixel_size == 3);
   image_destroy(i2);
 
-  i2 = image_clone(&it, i1, COLOR_SPACE_RGB | IMAGE_PIXELS_ALIGNED, NULL);
+  i2 = image_clone(&ctx, i1, COLOR_SPACE_RGB | IMAGE_PIXELS_ALIGNED, NULL);
   ASSERT(i2);
   ASSERT(i2->pixel_size == 4);
   image_destroy(i2);
 
-  i = image_init_subimage(&it, &s1, i1, 29, 39, 283 - 29, 100);
-  ASSERT(i);
+  /* Subimages */
+  i2 = image_init_subimage(&ctx, &s1, i1, 29, 39, 283 - 29, 100);
+  ASSERT(i2);
   image_destroy(&s1);
 
   image_destroy(i1);
 
-  image_thread_cleanup(&it);
+  image_context_cleanup(&ctx);
   mp_delete(pool);
 }
 
+#ifdef CONFIG_UCW_THREADS
+
+#define TEST_THREADS_COUNT 4
+
+static void *
+test_threads_thread(void *param UNUSED)
+{
+  DBG("Starting thread");
+  struct image_context ctx;
+  struct image_io io;
+  image_context_init(&ctx);
+  TRY(image_io_init(&ctx, &io));
+
+  for (uns num = 0; num < 200; num++)
+    {
+      int r0 = random_max(100);
+
+      /* realloc context */
+      if ((r0 -= 2) < 0)
+        {
+         image_io_cleanup(&io);
+         image_context_cleanup(&ctx);
+         image_context_init(&ctx);
+         TRY(image_io_init(&ctx, &io));
+       }
+
+      /* realloc I/O */
+      else if ((r0 -= 2) < 0)
+        {
+         image_io_cleanup(&io);
+         TRY(image_io_init(&ctx, &io));
+       }
+
+      /* encode and decode random image */
+      else
+        {
+          struct image *img;
+
+          TRY(img = image_new(&ctx, 10 + random_max(140), 10 + random_max(140), COLOR_SPACE_RGB, NULL));
+         image_clear(&ctx, img);
+
+#if defined(CONFIG_IMAGES_LIBJPEG) || defined(CONFIG_IMAGES_LIBPNG) || defined(CONFIG_IMAGES_LIBMAGICK)
+
+         struct fastbuf *wfb = fbmem_create(10000);
+         struct fastbuf *rfb;
+         uns format = 0;
+         while (!format)
+           {
+             switch (random_max(3))
+               {
+                 case 0:
+#if defined(CONFIG_IMAGES_LIBJPEG) || defined(CONFIG_IMAGES_LIBMAGICK)
+                   format = IMAGE_FORMAT_JPEG;
+#endif
+                   break;
+                 case 1:
+#if defined(CONFIG_IMAGES_LIBPNG) || defined(CONFIG_IMAGES_LIBMAGICK)
+                   format = IMAGE_FORMAT_PNG;
+#endif
+                   break;
+                 case 2:
+#if defined(CONFIG_IMAGES_LIBMAGICK)
+                   format = IMAGE_FORMAT_GIF;
+#endif
+                   break;
+                 default:
+                   ASSERT(0);
+               }
+           }
+
+         io.format = format;
+         io.fastbuf = wfb;
+         io.image = img;
+         TRY(image_io_write(&io));
+         image_io_reset(&io);
+
+         rfb = fbmem_clone_read(wfb);
+         io.format = format;
+         io.fastbuf = rfb;
+         TRY(image_io_read(&io, 0));
+         image_io_reset(&io);
+
+         bclose(rfb);
+         bclose(wfb);
+
+#endif
+          image_destroy(img);
+       }
+    }
+
+  image_io_cleanup(&io);
+  image_context_cleanup(&ctx);
+  DBG("Stopping thread");
+  return NULL;
+}
+
+#endif
+
+static void
+test_threads(void)
+{
+#ifdef CONFIG_UCW_THREADS
+  pthread_t threads[TEST_THREADS_COUNT - 1];
+  pthread_attr_t attr;
+  if (pthread_attr_init(&attr) < 0 ||
+      pthread_attr_setstacksize(&attr, ucwlib_thread_stack_size) < 0)
+    ASSERT(0);
+  for (uns i = 0; i < TEST_THREADS_COUNT - 1; i++)
+    {
+      if (pthread_create(threads + i, &attr, test_threads_thread, NULL) < 0)
+        die("Unable to create thread: %m");
+    }
+  test_threads_thread(NULL);
+  for (uns i = 0; i < TEST_THREADS_COUNT - 1; i++)
+    if (pthread_join(threads[i], NULL) < 0)
+      die("Cannot join thread: %m");
+#else
+  msg(L_WARN, "Disabled CONFIG_UCW_THREADS, threaded tests skipped");
+#endif
+}
+
 int
 main(int argc, char **argv)
 {
-  for (int i = 0; i < argc; i++)
+  for (int i = 1; i < argc; i++)
     if (!strcmp(argv[i], "image-iface"))
-      want_image_iface = 1;
+      want_image_iface++;
+    else if (!strcmp(argv[i], "threads"))
+      want_threads++;
+    else
+      die("Invalid parameter");
+
+  srandom(time(NULL) ^ getpid());
+
   if (want_image_iface)
     test_image_iface();
+  if (want_threads)
+    test_threads();
+
   return 0;
 }