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