]> mj.ucw.cz Git - libucw.git/blob - images/image-test.c
xtypes: Small code cleanups.
[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 #include <time.h>
23 #include <unistd.h>
24
25 static uint want_image_iface;
26 static uint 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 #ifdef CONFIG_UCW_THREADS
97
98 #define TEST_THREADS_COUNT 4
99
100 static void *
101 test_threads_thread(void *param UNUSED)
102 {
103   DBG("Starting thread");
104   struct image_context ctx;
105   struct image_io io;
106   image_context_init(&ctx);
107   TRY(image_io_init(&ctx, &io));
108
109   for (uint num = 0; num < 200; num++)
110     {
111       int r0 = random_max(100);
112
113       /* realloc context */
114       if ((r0 -= 2) < 0)
115         {
116           image_io_cleanup(&io);
117           image_context_cleanup(&ctx);
118           image_context_init(&ctx);
119           TRY(image_io_init(&ctx, &io));
120         }
121
122       /* realloc I/O */
123       else if ((r0 -= 2) < 0)
124         {
125           image_io_cleanup(&io);
126           TRY(image_io_init(&ctx, &io));
127         }
128
129       /* encode and decode random image */
130       else
131         {
132           struct image *img;
133
134           TRY(img = image_new(&ctx, 10 + random_max(140), 10 + random_max(140), COLOR_SPACE_RGB, NULL));
135           image_clear(&ctx, img);
136
137 #if defined(CONFIG_IMAGES_LIBJPEG) || defined(CONFIG_IMAGES_LIBPNG) || defined(CONFIG_IMAGES_LIBMAGICK)
138
139           struct fastbuf *wfb = fbmem_create(10000);
140           struct fastbuf *rfb;
141           uint format = 0;
142           while (!format)
143             {
144               switch (random_max(3))
145                 {
146                   case 0:
147 #if defined(CONFIG_IMAGES_LIBJPEG) || defined(CONFIG_IMAGES_LIBMAGICK)
148                     format = IMAGE_FORMAT_JPEG;
149 #endif
150                     break;
151                   case 1:
152 #if defined(CONFIG_IMAGES_LIBPNG) || defined(CONFIG_IMAGES_LIBMAGICK)
153                     format = IMAGE_FORMAT_PNG;
154 #endif
155                     break;
156                   case 2:
157 #if defined(CONFIG_IMAGES_LIBMAGICK)
158                     format = IMAGE_FORMAT_GIF;
159 #endif
160                     break;
161                   default:
162                     ASSERT(0);
163                 }
164             }
165
166           io.format = format;
167           io.fastbuf = wfb;
168           io.image = img;
169           TRY(image_io_write(&io));
170           image_io_reset(&io);
171
172           rfb = fbmem_clone_read(wfb);
173           io.format = format;
174           io.fastbuf = rfb;
175           TRY(image_io_read(&io, 0));
176           image_io_reset(&io);
177
178           bclose(rfb);
179           bclose(wfb);
180
181 #endif
182           image_destroy(img);
183         }
184     }
185
186   image_io_cleanup(&io);
187   image_context_cleanup(&ctx);
188   DBG("Stopping thread");
189   return NULL;
190 }
191
192 #endif
193
194 static void
195 test_threads(void)
196 {
197 #ifdef CONFIG_UCW_THREADS
198   pthread_t threads[TEST_THREADS_COUNT - 1];
199   pthread_attr_t attr;
200   if (pthread_attr_init(&attr) < 0 ||
201       pthread_attr_setstacksize(&attr, ucwlib_thread_stack_size) < 0)
202     ASSERT(0);
203   for (uint i = 0; i < TEST_THREADS_COUNT - 1; i++)
204     {
205       if (pthread_create(threads + i, &attr, test_threads_thread, NULL) < 0)
206         die("Unable to create thread: %m");
207     }
208   test_threads_thread(NULL);
209   for (uint i = 0; i < TEST_THREADS_COUNT - 1; i++)
210     if (pthread_join(threads[i], NULL) < 0)
211       die("Cannot join thread: %m");
212 #else
213   msg(L_WARN, "Disabled CONFIG_UCW_THREADS, threaded tests skipped");
214 #endif
215 }
216
217 int
218 main(int argc, char **argv)
219 {
220   for (int i = 1; i < argc; i++)
221     if (!strcmp(argv[i], "image-iface"))
222       want_image_iface++;
223     else if (!strcmp(argv[i], "threads"))
224       want_threads++;
225     else
226       die("Invalid parameter");
227
228   srandom(time(NULL) ^ getpid());
229
230   if (want_image_iface)
231     test_image_iface();
232   if (want_threads)
233     test_threads();
234
235   return 0;
236 }
237