]> mj.ucw.cz Git - libucw.git/blob - images/image-test.c
Released as 6.5.16.
[libucw.git] / images / image-test.c
1 /*
2  *      Image Library -- Simple automatic tests
3  *
4  *      (c) 2006 Pavel Charvat <pchar@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #undef LOCAL_DEBUG
11
12 #include <ucw/lib.h>
13 #include <ucw/mempool.h>
14 #include <ucw/fastbuf.h>
15 #include <ucw/threads.h>
16 #include <images/images.h>
17 #include <images/color.h>
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <pthread.h>
22
23 static uint want_image_iface;
24 static uint want_threads;
25
26 #define TRY(x) do { if (!(x)) ASSERT(0); } while (0)
27
28 static void
29 test_image_iface(void)
30 {
31   struct mempool *pool;
32   struct image_context ctx;
33   struct image *i1, *i2;
34   struct image s1;
35
36   pool = mp_new(1024);
37   image_context_init(&ctx);
38
39   /* Image allocation */
40   i1 = image_new(&ctx, 731, 327, COLOR_SPACE_RGB, NULL);
41   ASSERT(i1);
42   ASSERT(i1->pixel_size == 3);
43   image_destroy(i1);
44
45   /* Test invalid image size  */
46   ctx.msg_callback = image_context_msg_silent;
47   i1 = image_new(&ctx, 2214, 0, COLOR_SPACE_RGB, NULL);
48   ASSERT(!i1);
49   i1 = image_new(&ctx, 0xffffff, 0xffffff, COLOR_SPACE_RGB, NULL);
50   ASSERT(!i1);
51   ctx.msg_callback = image_context_msg_default;
52
53   /* Various image allocatio parameters */
54   i1 = image_new(&ctx, 370, 100, COLOR_SPACE_GRAYSCALE, pool);
55   ASSERT(i1);
56   ASSERT(i1->pixel_size == 1);
57   image_destroy(i1);
58   mp_flush(pool);
59
60   i1 = image_new(&ctx, 373, 101, COLOR_SPACE_RGB | IMAGE_ALIGNED, NULL);
61   ASSERT(i1);
62   ASSERT(i1->pixel_size == 4);
63   ASSERT(IMAGE_SSE_ALIGN_SIZE >= 16);
64   ASSERT(!(i1->row_size & (IMAGE_SSE_ALIGN_SIZE - 1)));
65   ASSERT(!((uintptr_t)i1->pixels & (IMAGE_SSE_ALIGN_SIZE - 1)));
66   image_destroy(i1);
67
68   i1 = image_new(&ctx, 283, 329, COLOR_SPACE_RGB, NULL);
69   ASSERT(i1);
70   ASSERT(i1->pixel_size == 3);
71
72   /* Image structures cloning */
73   i2 = image_clone(&ctx, i1, COLOR_SPACE_RGB, NULL);
74   ASSERT(i2);
75   ASSERT(i2->pixel_size == 3);
76   image_destroy(i2);
77
78   i2 = image_clone(&ctx, i1, COLOR_SPACE_RGB | IMAGE_PIXELS_ALIGNED, NULL);
79   ASSERT(i2);
80   ASSERT(i2->pixel_size == 4);
81   image_destroy(i2);
82
83   /* Subimages */
84   i2 = image_init_subimage(&ctx, &s1, i1, 29, 39, 283 - 29, 100);
85   ASSERT(i2);
86   image_destroy(&s1);
87
88   image_destroy(i1);
89
90   image_context_cleanup(&ctx);
91   mp_delete(pool);
92 }
93
94 #ifdef CONFIG_UCW_THREADS
95
96 #define TEST_THREADS_COUNT 4
97
98 static void *
99 test_threads_thread(void *param UNUSED)
100 {
101   DBG("Starting thread");
102   struct image_context ctx;
103   struct image_io io;
104   image_context_init(&ctx);
105   TRY(image_io_init(&ctx, &io));
106
107   for (uint num = 0; num < 200; num++)
108     {
109       int r0 = random_max(100);
110
111       /* realloc context */
112       if ((r0 -= 2) < 0)
113         {
114           image_io_cleanup(&io);
115           image_context_cleanup(&ctx);
116           image_context_init(&ctx);
117           TRY(image_io_init(&ctx, &io));
118         }
119
120       /* realloc I/O */
121       else if ((r0 -= 2) < 0)
122         {
123           image_io_cleanup(&io);
124           TRY(image_io_init(&ctx, &io));
125         }
126
127       /* encode and decode random image */
128       else
129         {
130           struct image *img;
131
132           TRY(img = image_new(&ctx, 10 + random_max(140), 10 + random_max(140), COLOR_SPACE_RGB, NULL));
133           image_clear(&ctx, img);
134
135 #if defined(CONFIG_IMAGES_LIBJPEG) || defined(CONFIG_IMAGES_LIBPNG) || defined(CONFIG_IMAGES_LIBMAGICK)
136
137           struct fastbuf *wfb = fbmem_create(10000);
138           struct fastbuf *rfb;
139           uint format = 0;
140           while (!format)
141             {
142               switch (random_max(3))
143                 {
144                   case 0:
145 #if defined(CONFIG_IMAGES_LIBJPEG) || defined(CONFIG_IMAGES_LIBMAGICK)
146                     format = IMAGE_FORMAT_JPEG;
147 #endif
148                     break;
149                   case 1:
150 #if defined(CONFIG_IMAGES_LIBPNG) || defined(CONFIG_IMAGES_LIBMAGICK)
151                     format = IMAGE_FORMAT_PNG;
152 #endif
153                     break;
154                   case 2:
155 #if defined(CONFIG_IMAGES_LIBMAGICK)
156                     format = IMAGE_FORMAT_GIF;
157 #endif
158                     break;
159                   default:
160                     ASSERT(0);
161                 }
162             }
163
164           io.format = format;
165           io.fastbuf = wfb;
166           io.image = img;
167           TRY(image_io_write(&io));
168           image_io_reset(&io);
169
170           rfb = fbmem_clone_read(wfb);
171           io.format = format;
172           io.fastbuf = rfb;
173           TRY(image_io_read(&io, 0));
174           image_io_reset(&io);
175
176           bclose(rfb);
177           bclose(wfb);
178
179 #endif
180           image_destroy(img);
181         }
182     }
183
184   image_io_cleanup(&io);
185   image_context_cleanup(&ctx);
186   DBG("Stopping thread");
187   return NULL;
188 }
189
190 #endif
191
192 static void
193 test_threads(void)
194 {
195 #ifdef CONFIG_UCW_THREADS
196   pthread_t threads[TEST_THREADS_COUNT - 1];
197   pthread_attr_t attr;
198   if (pthread_attr_init(&attr) < 0 ||
199       pthread_attr_setstacksize(&attr, ucwlib_thread_stack_size) < 0)
200     ASSERT(0);
201   for (uint i = 0; i < TEST_THREADS_COUNT - 1; i++)
202     {
203       if (pthread_create(threads + i, &attr, test_threads_thread, NULL) < 0)
204         die("Unable to create thread: %m");
205     }
206   test_threads_thread(NULL);
207   for (uint i = 0; i < TEST_THREADS_COUNT - 1; i++)
208     if (pthread_join(threads[i], NULL) < 0)
209       die("Cannot join thread: %m");
210 #else
211   msg(L_WARN, "Disabled CONFIG_UCW_THREADS, threaded tests skipped");
212 #endif
213 }
214
215 int
216 main(int argc, char **argv)
217 {
218   for (int i = 1; i < argc; i++)
219     if (!strcmp(argv[i], "image-iface"))
220       want_image_iface++;
221     else if (!strcmp(argv[i], "threads"))
222       want_threads++;
223     else
224       die("Invalid parameter");
225
226   random_gen_seed();
227
228   if (want_image_iface)
229     test_image_iface();
230   if (want_threads)
231     test_threads();
232
233   return 0;
234 }
235