]> mj.ucw.cz Git - libucw.git/commitdiff
- removed testing code from io-libungif
authorPavel Charvat <pavel.charvat@netcentrum.cz>
Wed, 2 Aug 2006 07:51:26 +0000 (09:51 +0200)
committerPavel Charvat <pavel.charvat@netcentrum.cz>
Wed, 2 Aug 2006 07:51:26 +0000 (09:51 +0200)
- simplified image_destroy interface
- added simple tests

images/Makefile
images/image-test.c
images/image.c
images/images.h
images/io-libungif.c

index f7d6873e838ba29e20018a461432309d8f452e4e..b8b002204d58631eb791cf82ca00839765a67082 100644 (file)
@@ -42,6 +42,11 @@ $(o)/images/libimages.so: $(addsuffix .oo,$(addprefix $(o)/images/,$(LIBIMAGES_M
 $(o)/images/image-tool: $(o)/images/image-tool.o $(LIBIMAGES) $(LIBUCW)
 $(o)/images/image-tool: LIBS+=$(LIBIMAGES_LIBS)
 
+TESTS+=$(o)/images/image-test.test
+$(o)/images/image-test: $(o)/images/image-test.o $(LIBIMAGES) $(LIBUCW)
+$(o)/images/image-test: LIBS+=$(LIBIMAGES_LIBS)
+$(o)/images/image-test.test: $(o)/images/image-test
+
 TESTS+=$(o)/images/hilbert-test.test
 $(o)/images/hilbert-test: LIBS+=-lm $(LIBSH)
 $(o)/images/hilbert-test.test: $(o)/images/hilbert-test
index b909ed65965b2df4cdc53f0f188e0551dbabac39..1e49d284dd1b66d68044aff9bcf397bc9de9b440 100644 (file)
 #undef LOCAL_DEBUG
 
-#include "sherlock/sherlock.h"
-#include "lib/fastbuf.h"
-#include "images/images.h"
-//#include "images/image-sig.h"
-//#include "images/kd-tree.h"
-#include "sherlock/index.h"
+#include "lib/lib.h"
 #include "lib/mempool.h"
-#include "sherlock/object.h"
-#include "sherlock/lizard-fb.h"
-#include <fcntl.h>
-#include <stdio.h>
+#include "images/images.h"
+#include <string.h>
 
-#include "sherlock/sherlock.h"
-#include "lib/fastbuf.h"
-//#include "images/images.h"
-#include "sherlock/index.h"
+static uns want_image_iface;
 
-#include <stdio.h>
-#include <fcntl.h>
-#include <alloca.h>
+static void
+test_image_iface(void)
+{
+  struct mempool *pool;
+  struct image_thread it;
+  struct image *i1, *i2;
+  struct image s1;
+  int i;
 
-#define BEST_CNT 30
+  pool = mp_new(1024);
+  image_thread_init(&it);
 
-struct image_tree image_tree;
+  i1 = image_new(&it, 731, 327, COLOR_SPACE_RGB, NULL);
+  ASSERT(i1);
+  ASSERT(i1->pixel_size == 3);
+  image_destroy(i1);
 
-static void
-image_tree_init(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);
-}
+  i1 = image_new(&it, 2214, 0, COLOR_SPACE_RGB, NULL);
+  ASSERT(!i1);
 
-static void
-image_tree_done(void)
-{
-  DBG("Freeing image search structures");
-  xfree(image_tree.nodes);
-  xfree(image_tree.leaves);
+  i1 = image_new(&it, 0xffffff, 0xffffff, COLOR_SPACE_RGB, NULL);
+  ASSERT(!i1);
+
+  i1 = image_new(&it, 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);
+  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)));
+  image_destroy(i1);
+
+  i1 = image_new(&it, 283, 329, COLOR_SPACE_RGB, NULL);
+  ASSERT(i1);
+  ASSERT(i1->pixel_size == 3);
+
+  i2 = image_clone(&it, 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);
+  ASSERT(i2);
+  ASSERT(i2->pixel_size == 4);
+  image_destroy(i2);
+
+  i = image_init_subimage(&it, &s1, i1, 29, 39, 283 - 29, 100);
+  ASSERT(i);
+  image_destroy(&s1);
+
+  image_destroy(i1);
+
+  image_thread_cleanup(&it);
+  mp_delete(pool);
 }
-  
+
 int
 main(int argc, char **argv)
 {
-  struct image_vector query;
-  if (argc != IMAGE_VEC_K + 1)
-    die("Invalid number of arguments");
-
-  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++)
-    {
-      if (!image_search_next(&is, best + i, dist + i))
-        {
-          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;
-    }
-  bclose(fb);
-  fb = bopen("index/cards", O_RDONLY, 1 << 14);
-  for (uns i = 0; i < best_n; 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'));
-    }
-  bclose(fb);
-  buck2obj_free(bob);
-  mp_delete(pool);
-     
+  for (int i = 0; i < argc; i++)
+    if (!strcmp(argv[i], "image-iface"))
+      want_image_iface = 1;
+  if (want_image_iface)
+    test_image_iface();
   return 0;
 }
 
index 13576d8cd72e7a7fe9c49d59f300f8dd354adeaa..828313d53d8ec5099480582b5e8782b9ff9b19db 100644 (file)
@@ -45,13 +45,14 @@ struct image *
 image_new(struct image_thread *it, uns cols, uns rows, uns flags, struct mempool *pool)
 {
   DBG("image_new(cols=%u rows=%u flags=0x%x pool=%p)", cols, rows, flags, pool);
-  if (cols > IMAGE_MAX_SIZE || rows > IMAGE_MAX_SIZE)
+  flags &= IMAGE_PIXEL_FORMAT | IMAGE_SSE_ALIGNED;
+  if (unlikely(!image_dimensions_valid(cols, rows)))
     {
-      image_thread_err(it, IMAGE_ERR_INVALID_DIMENSIONS, "Image dimension(s) too large");
+      image_thread_err_format(it, IMAGE_ERR_INVALID_DIMENSIONS, "Invalid image dimensions (%ux%u)", cols, rows);
       return NULL;
     }
   struct image *img;
-  uns pixel_size, row_size, image_size, align;
+  uns pixel_size, row_size, align;
   switch (flags & IMAGE_COLOR_SPACE)
     {
       case COLOR_SPACE_GRAYSCALE:
@@ -89,17 +90,18 @@ image_new(struct image_thread *it, uns cols, uns rows, uns flags, struct mempool
   row_size = ALIGN(row_size, align);
   u64 image_size_64 = (u64)row_size * rows;
   u64 bytes_64 = image_size_64 + (sizeof(struct image) + IMAGE_SSE_ALIGN_SIZE - 1 + sizeof(uns));
-  if (bytes_64 > MAX_IMAGE_BYTES)
+  if (unlikely(bytes_64 > MAX_IMAGE_BYTES))
     {
       image_thread_err(it, IMAGE_ERR_INVALID_DIMENSIONS, "Image does not fit in memory");
       return NULL;
     }
-  if (!(image_size = image_size_64))
+  if (pool)
+    img = mp_alloc(pool, bytes_64);
+  else
     {
-      image_thread_err(it, IMAGE_ERR_INVALID_DIMENSIONS, "Zero dimension(s)");
-      return NULL;
+      img = xmalloc(bytes_64);
+      flags |= IMAGE_NEED_DESTROY;
     }
-  img = pool ? mp_alloc(pool, (uns)bytes_64) : xmalloc((uns)bytes_64);
   bzero(img, sizeof(struct image));
   byte *p = (byte *)img + sizeof(struct image);
   img->pixels = ALIGN_PTR(p, IMAGE_SSE_ALIGN_SIZE);
@@ -108,7 +110,7 @@ image_new(struct image_thread *it, uns cols, uns rows, uns flags, struct mempool
   img->cols = cols;
   img->rows = rows;
   img->row_size = row_size;
-  img->image_size = image_size;
+  img->image_size = bytes_64;
   DBG("img=%p flags=0x%x pixel_size=%u row_size=%u image_size=%u pixels=%p",
     img, img->flags, img->pixel_size, img->row_size, img->image_size, img->pixels);
   return img;
@@ -157,7 +159,8 @@ void
 image_destroy(struct image *img)
 {
   DBG("image_destroy(img=%p)", img);
-  xfree(img);
+  if (img->flags & IMAGE_NEED_DESTROY)
+    xfree(img);
 }
 
 void
@@ -168,6 +171,38 @@ image_clear(struct image_thread *it UNUSED, struct image *img)
     bzero(img->pixels, img->image_size);
 }
 
+int
+image_init_matrix(struct image_thread *it, struct image *img, byte *pixels, uns cols, uns rows, uns row_size, uns flags)
+{
+  DBG("image_init_matrix(img=%p cols=%u rows=%u row_size=%u flags=0x%x)", img, cols, rows, row_size, uns flags);
+  if (unlikely(!image_dimensions_valid(cols, rows)))
+    {
+      image_thread_err_format(it, IMAGE_ERR_INVALID_DIMENSIONS, "Invalid image dimensions (%ux%u)", cols, rows);
+      return 0;
+    }
+  img->pixels = pixels;
+  img->cols = cols;
+  img->rows = rows;
+  img->row_size = row_size;
+  img->image_size = rows * row_size;
+  img->flags = flags & (IMAGE_PIXEL_FORMAT | IMAGE_SSE_ALIGNED);
+  return 1;
+}
+
+int
+image_init_subimage(struct image_thread *it UNUSED, struct image *img, struct image *src, uns left, uns top, uns cols, uns rows)
+{
+  DBG("image_init_subimage(img=%p src=%p left=%u top=%u cols=%u rows=%u)");
+  ASSERT(left + cols <= src->cols && top + rows <= src->rows);
+  img->pixels = src->pixels + left * src->pixel_size + top * src->row_size;
+  img->cols = cols;
+  img->rows = rows;
+  img->row_size = src->row_size;
+  img->image_size = src->row_size * rows;
+  img->flags = src->flags & ~IMAGE_NEED_DESTROY; 
+  return 1;
+}
+
 byte *
 color_space_to_name(enum color_space cs)
 {
index 282489fd7a1ddb88378296fd06be4a4769311b19..485c3eb3a346b72526f593d1056923d25e6ea069 100644 (file)
@@ -69,6 +69,7 @@ enum image_flag {
   IMAGE_ALPHA = 0x8,           /* alpha channel */
   IMAGE_PIXELS_ALIGNED = 0x10, /* align pixel size to the nearest power of two  */
   IMAGE_SSE_ALIGNED = 0x20,    /* align scanlines to multiples of 16 bytes (both start and size) */
+  IMAGE_NEED_DESTROY = 0x40,   /* image is allocated with xmalloc */
   IMAGE_CHANNELS_FORMAT = IMAGE_COLOR_SPACE | IMAGE_ALPHA,
   IMAGE_PIXEL_FORMAT = IMAGE_CHANNELS_FORMAT | IMAGE_PIXELS_ALIGNED,
   IMAGE_ALIGNED = IMAGE_PIXELS_ALIGNED | IMAGE_SSE_ALIGNED,
@@ -81,7 +82,7 @@ struct image {
   u32 rows;                    /* number of rows */
   u32 pixel_size;              /* size of pixel (1, 2, 3 or 4) */
   u32 row_size;                        /* scanline size in bytes */
-  u32 image_size;              /* size of pixels buffer (rows * rows_size) */
+  u32 image_size;              /* rows * rows_size */
   u32 flags;                   /* enum image_flag */
 };
 
@@ -89,6 +90,14 @@ struct image *image_new(struct image_thread *it, uns cols, uns rows, uns flags,
 struct image *image_clone(struct image_thread *it, struct image *src, uns flags, struct mempool *pool);
 void image_destroy(struct image *img); /* only with NULL mempool */
 void image_clear(struct image_thread *it, struct image *img);
+int image_init_matrix(struct image_thread *it, struct image *img, byte *pixels, uns cols, uns rows, uns row_size, uns flags);
+int image_init_subimage(struct image_thread *it, struct image *img, struct image *src, uns left, uns top, uns cols, uns rows);
+
+static inline int
+image_dimensions_valid(uns cols, uns rows)
+{
+  return cols && rows && cols <= IMAGE_MAX_SIZE && rows <= IMAGE_MAX_SIZE;
+}
 
 byte *color_space_to_name(enum color_space cs);
 byte *image_channels_format_to_name(uns format);
index 3faf6c51bd5f8637c6a211214284b73799d5a332..5eb7aece2424b65217d325c301daaa9e45366967 100644 (file)
@@ -26,14 +26,7 @@ static int
 libungif_read_func(GifFileType *gif, GifByteType *ptr, int len)
 {
   DBG("libungif_read_func(len=%d)", len);
-  uns readed, total = 0;
-  while (len && (readed = bread((struct fastbuf *)gif->UserData, (byte *)ptr, len)))
-    {
-      len -= readed;
-      ptr += readed;
-      total += readed;
-    }
-  return total;
+  return bread((struct fastbuf *)gif->UserData, (byte *)ptr, len);
 }
 
 static void