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