Workshop o mikrokontrolérech na SKSP 2024.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
5.2 KiB

3 months ago
/*
* 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 <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>
static uint want_image_iface;
static uint want_threads;
#define TRY(x) do { if (!(x)) ASSERT(0); } while (0)
static void
test_image_iface(void)
{
struct mempool *pool;
struct image_context ctx;
struct image *i1, *i2;
struct image s1;
pool = mp_new(1024);
image_context_init(&ctx);
/* Image allocation */
i1 = image_new(&ctx, 731, 327, COLOR_SPACE_RGB, NULL);
ASSERT(i1);
ASSERT(i1->pixel_size == 3);
image_destroy(i1);
/* 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(&ctx, 0xffffff, 0xffffff, COLOR_SPACE_RGB, NULL);
ASSERT(!i1);
ctx.msg_callback = image_context_msg_default;
/* 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(&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(!((uintptr_t)i1->pixels & (IMAGE_SSE_ALIGN_SIZE - 1)));
image_destroy(i1);
i1 = image_new(&ctx, 283, 329, COLOR_SPACE_RGB, NULL);
ASSERT(i1);
ASSERT(i1->pixel_size == 3);
/* 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(&ctx, i1, COLOR_SPACE_RGB | IMAGE_PIXELS_ALIGNED, NULL);
ASSERT(i2);
ASSERT(i2->pixel_size == 4);
image_destroy(i2);
/* Subimages */
i2 = image_init_subimage(&ctx, &s1, i1, 29, 39, 283 - 29, 100);
ASSERT(i2);
image_destroy(&s1);
image_destroy(i1);
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 (uint 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;
uint 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 (uint 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 (uint 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 = 1; i < argc; i++)
if (!strcmp(argv[i], "image-iface"))
want_image_iface++;
else if (!strcmp(argv[i], "threads"))
want_threads++;
else
die("Invalid parameter");
random_gen_seed();
if (want_image_iface)
test_image_iface();
if (want_threads)
test_threads();
return 0;
}