]> mj.ucw.cz Git - libucw.git/blob - images/image-test.c
Added a new mempool primitive mp_spread().
[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 "lib/lib.h"
13 #include "lib/mempool.h"
14 #include "lib/fastbuf.h"
15 #include "lib/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 #include <time.h>
23 #include <unistd.h>
24
25 static uns want_image_iface;
26 static uns want_threads;
27
28 #define TRY(x) do { if (!(x)) ASSERT(0); } while (0)
29
30 static void
31 test_image_iface(void)
32 {
33   struct mempool *pool;
34   struct image_context ctx;
35   struct image *i1, *i2;
36   struct image s1;
37
38   pool = mp_new(1024);
39   image_context_init(&ctx);
40
41   /* Image allocation */
42   i1 = image_new(&ctx, 731, 327, COLOR_SPACE_RGB, NULL);
43   ASSERT(i1);
44   ASSERT(i1->pixel_size == 3);
45   image_destroy(i1);
46
47   /* Test invalid image size  */
48   ctx.msg_callback = image_context_msg_silent;
49   i1 = image_new(&ctx, 2214, 0, COLOR_SPACE_RGB, NULL);
50   ASSERT(!i1);
51   i1 = image_new(&ctx, 0xffffff, 0xffffff, COLOR_SPACE_RGB, NULL);
52   ASSERT(!i1);
53   ctx.msg_callback = image_context_msg_default;
54
55   /* Various image allocatio parameters */
56   i1 = image_new(&ctx, 370, 100, COLOR_SPACE_GRAYSCALE, pool);
57   ASSERT(i1);
58   ASSERT(i1->pixel_size == 1);
59   image_destroy(i1);
60   mp_flush(pool);
61
62   i1 = image_new(&ctx, 373, 101, COLOR_SPACE_RGB | IMAGE_ALIGNED, NULL);
63   ASSERT(i1);
64   ASSERT(i1->pixel_size == 4);
65   ASSERT(IMAGE_SSE_ALIGN_SIZE >= 16);
66   ASSERT(!(i1->row_size & (IMAGE_SSE_ALIGN_SIZE - 1)));
67   ASSERT(!((uintptr_t)i1->pixels & (IMAGE_SSE_ALIGN_SIZE - 1)));
68   image_destroy(i1);
69
70   i1 = image_new(&ctx, 283, 329, COLOR_SPACE_RGB, NULL);
71   ASSERT(i1);
72   ASSERT(i1->pixel_size == 3);
73
74   /* Image structures cloning */
75   i2 = image_clone(&ctx, i1, COLOR_SPACE_RGB, NULL);
76   ASSERT(i2);
77   ASSERT(i2->pixel_size == 3);
78   image_destroy(i2);
79
80   i2 = image_clone(&ctx, i1, COLOR_SPACE_RGB | IMAGE_PIXELS_ALIGNED, NULL);
81   ASSERT(i2);
82   ASSERT(i2->pixel_size == 4);
83   image_destroy(i2);
84
85   /* Subimages */
86   i2 = image_init_subimage(&ctx, &s1, i1, 29, 39, 283 - 29, 100);
87   ASSERT(i2);
88   image_destroy(&s1);
89
90   image_destroy(i1);
91
92   image_context_cleanup(&ctx);
93   mp_delete(pool);
94 }
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 (uns 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           uns 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 static void
191 test_threads(void)
192 {
193   pthread_t threads[TEST_THREADS_COUNT - 1];
194   pthread_attr_t attr;
195   if (pthread_attr_init(&attr) < 0 ||
196       pthread_attr_setstacksize(&attr, default_thread_stack_size) < 0)
197     ASSERT(0);
198   for (uns i = 0; i < TEST_THREADS_COUNT - 1; i++)
199     {
200       if (pthread_create(threads + i, &attr, test_threads_thread, NULL) < 0)
201         die("Unable to create thread: %m");
202     }
203   test_threads_thread(NULL);
204   for (uns i = 0; i < TEST_THREADS_COUNT - 1; i++)
205     if (pthread_join(threads[i], NULL) < 0)
206       die("Cannot join thread: %m");
207 }
208
209 int
210 main(int argc, char **argv)
211 {
212   for (int i = 1; i < argc; i++)
213     if (!strcmp(argv[i], "image-iface"))
214       want_image_iface++;
215     else if (!strcmp(argv[i], "threads"))
216       want_threads++;
217     else
218       die("Invalid parameter");
219
220   srandom(time(NULL) ^ getpid());
221
222   if (want_image_iface)
223     test_image_iface();
224   if (want_threads)
225     test_threads();
226
227   return 0;
228 }
229