X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=images%2Fimage-test.c;h=4bf02b3992d742c997c3dc9b37c15a8c33632577;hb=09e7fe5641b94148d998a1b620bf694f353cb17b;hp=69820fd4a60d106a299bc0be9175e023a644695a;hpb=865c98d50c1be6edef8cc8c892637b8518d0672b;p=libucw.git diff --git a/images/image-test.c b/images/image-test.c index 69820fd4..4bf02b39 100644 --- a/images/image-test.c +++ b/images/image-test.c @@ -1,120 +1,237 @@ +/* + * Image Library -- Simple automatic tests + * + * (c) 2006 Pavel Charvat + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + #undef LOCAL_DEBUG -#include "sherlock/sherlock.h" -#include "lib/fastbuf.h" -#include "images/images.h" -#include "images/image-sig.h" -#include "images/image-search.h" -#include "sherlock/index.h" -#include "lib/mempool.h" -#include "sherlock/object.h" -#include "sherlock/lizard-fb.h" -#include -#include - -#include "sherlock/sherlock.h" -#include "lib/fastbuf.h" +#include "ucw/lib.h" +#include "ucw/mempool.h" +#include "ucw/fastbuf.h" +#include "ucw/threads.h" #include "images/images.h" -#include "sherlock/index.h" +#include "images/color.h" -#include -#include +#include +#include +#include +#include +#include -#define BEST_CNT 30 +static uns want_image_iface; +static uns want_threads; -struct image_tree image_tree; +#define TRY(x) do { if (!(x)) ASSERT(0); } while (0) static void -image_tree_init(void) +test_image_iface(void) { - DBG("Initializing image search structures"); - struct fastbuf *fb = bopen("index/image-tree", O_RDONLY, 1 << 16); /* FIXME: filename hack */ - image_tree.count = bgetl(fb); - image_tree.depth = bgetl(fb); - ASSERT(image_tree.count < 0x80000000 && image_tree.depth > 0 && image_tree.depth < 30); - image_tree.nodes = xmalloc((1 << image_tree.depth) * sizeof(struct image_node)); - image_tree.leaves = xmalloc(image_tree.count * sizeof(struct image_leaf)); - bread(fb, &image_tree.bbox, sizeof(struct image_bbox)); - bread(fb, image_tree.nodes + 1, ((1 << image_tree.depth) - 1) * sizeof(struct image_node)); - bread(fb, image_tree.leaves, image_tree.count * sizeof(struct image_leaf)); - DBG("Search tree with depth %d and %d leaves loaded", image_tree.depth, image_tree.count); - bclose(fb); -} + struct mempool *pool; + struct image_context ctx; + struct image *i1, *i2; + struct image s1; -static void -image_tree_done(void) -{ - DBG("Freeing image search structures"); - xfree(image_tree.nodes); - xfree(image_tree.leaves); + 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); } - -int -main(int argc, char **argv) + +#ifdef CONFIG_UCW_THREADS + +#define TEST_THREADS_COUNT 4 + +static void * +test_threads_thread(void *param UNUSED) { - struct image_vector query; - if (argc != IMAGE_VEC_K + 1) - die("Invalid number of arguments"); + DBG("Starting thread"); + struct image_context ctx; + struct image_io io; + image_context_init(&ctx); + TRY(image_io_init(&ctx, &io)); - for (uns i = 0; i < IMAGE_VEC_K; i++) - { - uns v; - if (sscanf(argv[i + 1], "%d", &v) != 1) - die("Invalid numeric format"); - query.f[i] = v; - } - - - struct image_search is; - oid_t best[BEST_CNT]; - uns dist[BEST_CNT]; - uns cardpos[BEST_CNT]; - uns best_n = 0; - - image_tree_init(); - log(L_INFO, "Executing query (%s)", stk_print_image_vector(&query)); - image_search_init(&is, &image_tree, &query, IMAGE_SEARCH_DIST_UNLIMITED); - for (uns i = 0; i < BEST_CNT; i++) + for (uns num = 0; num < 200; num++) { - if (!image_search_next(&is, best + i, dist + i)) + int r0 = random_max(100); + + /* realloc context */ + if ((r0 -= 2) < 0) { - log(L_INFO, "No more images"); - break; - } - DBG("*** Found %d. best image with oid=%d", i + 1, best[i]); - best_n++; - } - image_search_done(&is); - image_tree_done(); - - log(L_INFO, "Resolving URLs"); - struct mempool *pool = mp_new(1 << 16); - struct buck2obj_buf *bob = buck2obj_alloc(); - struct fastbuf *fb = bopen("index/card-attrs", O_RDONLY, 1 << 10); - for (uns i = 0; i < best_n; i++) - { - bsetpos(fb, best[i] * sizeof(struct card_attr)); - struct card_attr ca; - bread(fb, &ca, sizeof(ca)); - cardpos[i] = ca.card; + 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); + } } - bclose(fb); - fb = bopen("index/cards", O_RDONLY, 1 << 14); - for (uns i = 0; i < best_n; i++) + + 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, default_thread_stack_size) < 0) + ASSERT(0); + for (uns i = 0; i < TEST_THREADS_COUNT - 1; i++) { - bsetpos(fb, (sh_off_t)cardpos[i] << CARD_POS_SHIFT); - uns buck_len = bgetl(fb) - (LIZARD_COMPRESS_HEADER - 1); - uns buck_type = bgetc(fb) + BUCKET_TYPE_PLAIN; - mp_flush(pool); - struct odes *obj = obj_read_bucket(bob, pool, buck_type, buck_len, fb, NULL); - - printf("%2d. match: dist=%-8d oid=%-8d url=%s\n", i + 1, dist[i], best[i], - obj_find_aval(obj_find_attr(obj, 'U' + OBJ_ATTR_SON)->son, 'U')); + if (pthread_create(threads + i, &attr, test_threads_thread, NULL) < 0) + die("Unable to create thread: %m"); } - bclose(fb); - buck2obj_free(bob); - mp_delete(pool); - + 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 = 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"); + + srandom(time(NULL) ^ getpid()); + + if (want_image_iface) + test_image_iface(); + if (want_threads) + test_threads(); + return 0; }