1 #include "common.h"
2 #include "vnstat_tests.h"
3 #include "image_tests.h"
4 #include "dbsql.h"
5 #include "cfg.h"
6 #include "image.h"
7 #include "image_support.h"
8 
START_TEST(initimagecontent_does_not_crash)9 START_TEST(initimagecontent_does_not_crash)
10 {
11 	IMAGECONTENT ic;
12 	initimagecontent(&ic);
13 }
14 END_TEST
15 
START_TEST(imageinit_does_not_crash)16 START_TEST(imageinit_does_not_crash)
17 {
18 	IMAGECONTENT ic;
19 	imageinit(&ic, 2, 2);
20 	gdImageDestroy(ic.im);
21 }
22 END_TEST
23 
START_TEST(layoutinit_does_not_crash)24 START_TEST(layoutinit_does_not_crash)
25 {
26 	IMAGECONTENT ic;
27 	initimagecontent(&ic);
28 	imageinit(&ic, 640, 480);
29 	ic.interface.updated = time(NULL);
30 	layoutinit(&ic, "testing 123", 640, 480);
31 	gdImageDestroy(ic.im);
32 }
33 END_TEST
34 
START_TEST(getimagevalue_zeropadding)35 START_TEST(getimagevalue_zeropadding)
36 {
37 	ck_assert_str_eq(getimagevalue(0, 0, 0), "--");
38 	ck_assert_str_eq(getimagevalue(0, 2, 0), "--");
39 	ck_assert_str_eq(getimagevalue(0, 3, 0), " --");
40 	ck_assert_str_eq(getimagevalue(0, 0, 1), "--");
41 	ck_assert_str_eq(getimagevalue(0, 2, 1), "--");
42 	ck_assert_str_eq(getimagevalue(0, 3, 1), " --");
43 }
44 END_TEST
45 
START_TEST(getimagevalue_normal)46 START_TEST(getimagevalue_normal)
47 {
48 	ck_assert_str_eq(getimagevalue(1, 0, 0), "1");
49 	ck_assert_str_eq(getimagevalue(2, 0, 0), "2");
50 	ck_assert_str_eq(getimagevalue(1000, 0, 0), "1");
51 	ck_assert_str_eq(getimagevalue(1024, 0, 0), "1");
52 	ck_assert_str_eq(getimagevalue(2000, 0, 0), "2");
53 	ck_assert_str_eq(getimagevalue(2345, 0, 0), "2");
54 	ck_assert_str_eq(getimagevalue(123000, 0, 0), "120");
55 	ck_assert_str_eq(getimagevalue(1024000, 0, 0), "1");
56 	ck_assert_str_eq(getimagevalue(1048576, 0, 0), "1");
57 	ck_assert_str_eq(getimagevalue(1048576000, 0, 0), "1");
58 	ck_assert_str_eq(getimagevalue(1073741824, 0, 0), "1");
59 	ck_assert_str_eq(getimagevalue(1073741824000ULL, 0, 0), "1");
60 	ck_assert_str_eq(getimagevalue(1099511627776ULL, 0, 0), "1");
61 }
62 END_TEST
63 
START_TEST(getimagevalue_rate_1024)64 START_TEST(getimagevalue_rate_1024)
65 {
66 	cfg.rateunit = 0;
67 	cfg.rateunitmode = 0;
68 	ck_assert_str_eq(getimagevalue(1, 0, 1), "1");
69 	ck_assert_str_eq(getimagevalue(2, 0, 1), "2");
70 	ck_assert_str_eq(getimagevalue(1000, 0, 1), "1");
71 	ck_assert_str_eq(getimagevalue(2000, 0, 1), "2");
72 	ck_assert_str_eq(getimagevalue(1024000, 0, 1), "1");
73 	ck_assert_str_eq(getimagevalue(1048576000, 0, 1), "1");
74 	ck_assert_str_eq(getimagevalue(1073741824000ULL, 0, 1), "1");
75 }
76 END_TEST
77 
START_TEST(getimagevalue_rate_1000)78 START_TEST(getimagevalue_rate_1000)
79 {
80 	cfg.rateunit = 1;
81 	cfg.rateunitmode = 1;
82 	ck_assert_str_eq(getimagevalue(1, 0, 1), "1");
83 	ck_assert_str_eq(getimagevalue(2, 0, 1), "2");
84 	ck_assert_str_eq(getimagevalue(1000, 0, 1), "1");
85 	ck_assert_str_eq(getimagevalue(2000, 0, 1), "2");
86 	ck_assert_str_eq(getimagevalue(1000000, 0, 1), "1");
87 	ck_assert_str_eq(getimagevalue(1000000000, 0, 1), "1");
88 	ck_assert_str_eq(getimagevalue(1000000000000ULL, 0, 1), "1");
89 }
90 END_TEST
91 
START_TEST(getimagescale_zero)92 START_TEST(getimagescale_zero)
93 {
94 	cfg.rateunit = 0;
95 	ck_assert_str_eq(getimagescale(0, 0), "--");
96 	ck_assert_str_eq(getimagescale(0, 1), "--");
97 }
98 END_TEST
99 
START_TEST(getimagescale_normal)100 START_TEST(getimagescale_normal)
101 {
102 	cfg.rateunit = 0;
103 	ck_assert_str_eq(getimagescale(1, 0), "B");
104 	ck_assert_str_eq(getimagescale(2, 0), "B");
105 	ck_assert_str_eq(getimagescale(10, 0), "B");
106 	ck_assert_str_eq(getimagescale(100, 0), "B");
107 	ck_assert_str_eq(getimagescale(1000, 0), "KiB");
108 	ck_assert_str_eq(getimagescale(1024, 0), "KiB");
109 	ck_assert_str_eq(getimagescale(1030, 0), "KiB");
110 	ck_assert_str_eq(getimagescale(1024000, 0), "MiB");
111 	ck_assert_str_eq(getimagescale(1048576000, 0), "GiB");
112 	ck_assert_str_eq(getimagescale(1073741824000ULL, 0), "TiB");
113 }
114 END_TEST
115 
START_TEST(getimagescale_rate)116 START_TEST(getimagescale_rate)
117 {
118 	cfg.rateunit = 0;
119 	ck_assert_str_eq(getimagescale(1, 1), "B/s");
120 	ck_assert_str_eq(getimagescale(2, 1), "B/s");
121 	ck_assert_str_eq(getimagescale(10, 1), "B/s");
122 	ck_assert_str_eq(getimagescale(100, 1), "B/s");
123 	ck_assert_str_eq(getimagescale(1000, 1), "KiB/s");
124 	ck_assert_str_eq(getimagescale(1024, 1), "KiB/s");
125 	ck_assert_str_eq(getimagescale(1030, 1), "KiB/s");
126 	ck_assert_str_eq(getimagescale(1024000, 1), "MiB/s");
127 	ck_assert_str_eq(getimagescale(1048576000, 1), "GiB/s");
128 	ck_assert_str_eq(getimagescale(1073741824000ULL, 1), "TiB/s");
129 }
130 END_TEST
131 
START_TEST(getscale_zero)132 START_TEST(getscale_zero)
133 {
134 	ck_assert_int_eq(getscale(0, 0), 1);
135 }
136 END_TEST
137 
START_TEST(getscale_nonzero_1024)138 START_TEST(getscale_nonzero_1024)
139 {
140 	cfg.rateunit = 0;
141 	cfg.rateunitmode = 0;
142 	ck_assert_int_eq(getscale(1, 0), 1);
143 	ck_assert_int_eq(getscale(2, 0), 1);
144 	ck_assert_int_eq(getscale(10, 0), 2);
145 	ck_assert_int_eq(getscale(20, 0), 5);
146 	ck_assert_int_eq(getscale(50, 0), 20);
147 	ck_assert_int_eq(getscale(1000, 0), 300);
148 	ck_assert_int_eq(getscale(1023, 0), 300);
149 	ck_assert_int_eq(getscale(1024, 0), 1024);
150 	ck_assert_int_eq(getscale(1025, 0), 1024);
151 	ck_assert_int_eq(getscale(1026, 0), 1024);
152 	ck_assert_int_eq(getscale(1500, 0), 1024);
153 	ck_assert_int_eq(getscale(2047, 0), 1024);
154 	ck_assert_int_eq(getscale(2048, 0), 1024);
155 	ck_assert_int_eq(getscale(2049, 0), 1024);
156 	ck_assert_int_eq(getscale(8191, 0), 1024);
157 	ck_assert_int_eq(getscale(8192, 0), 2048);
158 	ck_assert_int_eq(getscale(8193, 0), 2048);
159 	ck_assert_int_eq(getscale(20000, 0), 4096);
160 
161 	ck_assert_int_eq(getscale(1, 1), 1);
162 	ck_assert_int_eq(getscale(2, 1), 1);
163 	ck_assert_int_eq(getscale(10, 1), 2);
164 	ck_assert_int_eq(getscale(20, 1), 5);
165 	ck_assert_int_eq(getscale(50, 1), 20);
166 	ck_assert_int_eq(getscale(1000, 1), 300);
167 	ck_assert_int_eq(getscale(1023, 1), 300);
168 	ck_assert_int_eq(getscale(1024, 1), 1024);
169 	ck_assert_int_eq(getscale(1025, 1), 1024);
170 	ck_assert_int_eq(getscale(1026, 1), 1024);
171 	ck_assert_int_eq(getscale(1500, 1), 1024);
172 	ck_assert_int_eq(getscale(2047, 1), 1024);
173 	ck_assert_int_eq(getscale(2048, 1), 1024);
174 	ck_assert_int_eq(getscale(2049, 1), 1024);
175 	ck_assert_int_eq(getscale(8191, 1), 1024);
176 	ck_assert_int_eq(getscale(8192, 1), 2048);
177 	ck_assert_int_eq(getscale(8193, 1), 2048);
178 	ck_assert_int_eq(getscale(20000, 1), 4096);
179 	ck_assert_int_eq(getscale(720000, 1), 204800);
180 }
181 END_TEST
182 
START_TEST(getscale_nonzero_1000)183 START_TEST(getscale_nonzero_1000)
184 {
185 	cfg.rateunit = 1;
186 	cfg.rateunitmode = 1;
187 	ck_assert_int_eq(getscale(1, 0), 1);
188 	ck_assert_int_eq(getscale(2, 0), 1);
189 	ck_assert_int_eq(getscale(10, 0), 2);
190 	ck_assert_int_eq(getscale(20, 0), 5);
191 	ck_assert_int_eq(getscale(50, 0), 20);
192 	ck_assert_int_eq(getscale(1000, 0), 300);
193 	ck_assert_int_eq(getscale(1023, 0), 300);
194 	ck_assert_int_eq(getscale(1024, 0), 1024);
195 	ck_assert_int_eq(getscale(1025, 0), 1024);
196 	ck_assert_int_eq(getscale(1026, 0), 1024);
197 	ck_assert_int_eq(getscale(1500, 0), 1024);
198 	ck_assert_int_eq(getscale(2047, 0), 1024);
199 	ck_assert_int_eq(getscale(2048, 0), 1024);
200 	ck_assert_int_eq(getscale(2049, 0), 1024);
201 	ck_assert_int_eq(getscale(8191, 0), 1024);
202 	ck_assert_int_eq(getscale(8192, 0), 2048);
203 	ck_assert_int_eq(getscale(8193, 0), 2048);
204 	ck_assert_int_eq(getscale(20000, 0), 4096);
205 
206 	ck_assert_int_eq(getscale(1, 1), 1);
207 	ck_assert_int_eq(getscale(2, 1), 1);
208 	ck_assert_int_eq(getscale(10, 1), 2);
209 	ck_assert_int_eq(getscale(20, 1), 5);
210 	ck_assert_int_eq(getscale(50, 1), 20);
211 	ck_assert_int_eq(getscale(1000, 1), 1000);
212 	ck_assert_int_eq(getscale(1023, 1), 1000);
213 	ck_assert_int_eq(getscale(1024, 1), 1000);
214 	ck_assert_int_eq(getscale(1025, 1), 1000);
215 	ck_assert_int_eq(getscale(1026, 1), 1000);
216 	ck_assert_int_eq(getscale(1500, 1), 1000);
217 	ck_assert_int_eq(getscale(2047, 1), 1000);
218 	ck_assert_int_eq(getscale(2048, 1), 1000);
219 	ck_assert_int_eq(getscale(2049, 1), 1000);
220 	ck_assert_int_eq(getscale(8191, 1), 2000);
221 	ck_assert_int_eq(getscale(8192, 1), 2000);
222 	ck_assert_int_eq(getscale(8193, 1), 2000);
223 	ck_assert_int_eq(getscale(20000, 1), 5000);
224 }
225 END_TEST
226 
227 /* this function needs to match the logic used in image.c drawhours() */
228 /* in order to test the right thing */
hourly_imagescale_logic(const uint64_t max,const int rate)229 char *hourly_imagescale_logic(const uint64_t max, const int rate)
230 {
231 	// int i, prev = 0;
232 	int step = 0, s, extray = 0;
233 	uint64_t scaleunit;
234 
235 	scaleunit = getscale(max, rate);
236 
237 	s = (int)lrint(((double)scaleunit / (double)max) * (124 + extray));
238 	if (s == 0) {
239 		s = 1;
240 	}
241 	while (s * step < SCALEMINPIXELS) {
242 		step++;
243 	}
244 	/*
245 	for (i = step; i * s <= (124 + extray + 4); i = i + step) {
246 		prev = i * s;
247 	}
248 	*/
249 	/* debug for times when things don't appear to make sense */
250 	/*printf("\nrate:       %d\n", rate);
251 	printf("lines:      %d\n", i-1);
252 	printf("max:        %"PRIu64"\n", max);
253 	printf("scaleunit:  %"PRIu64"\n", scaleunit);
254 	printf("old 2.0:    %"PRIu64" (i: %d, step: %d)\n", scaleunit * (i - step), i, step);
255 	printf("old 2.6:    %"PRIu64" (i: %d, step: %d)\n", scaleunit * i, i, step);
256 	printf("now:        %"PRIu64" (i: %d, step: %d)\n", scaleunit * step, i, step);
257 	fflush(stdout);*/
258 
259 	return getimagescale(scaleunit * (unsigned int)step, rate);
260 }
261 
START_TEST(hourly_imagescaling_normal)262 START_TEST(hourly_imagescaling_normal)
263 {
264 	char *unittext;
265 
266 	cfg.unitmode = 0;
267 	cfg.rateunit = 1;
268 	cfg.rateunitmode = 1;
269 
270 	unittext = hourly_imagescale_logic(1, 0);
271 	ck_assert_str_eq(unittext, "B");
272 
273 	unittext = hourly_imagescale_logic(100, 0);
274 	ck_assert_str_eq(unittext, "B");
275 
276 	unittext = hourly_imagescale_logic(981, 0);
277 	ck_assert_str_eq(unittext, "B");
278 
279 	unittext = hourly_imagescale_logic(1000, 0);
280 	ck_assert_str_eq(unittext, "B");
281 
282 	unittext = hourly_imagescale_logic(1024, 0);
283 	ck_assert_str_eq(unittext, "KiB");
284 
285 	unittext = hourly_imagescale_logic(2000, 0);
286 	ck_assert_str_eq(unittext, "KiB");
287 
288 	unittext = hourly_imagescale_logic(1000000, 0);
289 	ck_assert_str_eq(unittext, "KiB");
290 
291 	unittext = hourly_imagescale_logic(1024000, 0);
292 	ck_assert_str_eq(unittext, "KiB");
293 
294 	unittext = hourly_imagescale_logic(1300000, 0);
295 	ck_assert_str_eq(unittext, "MiB");
296 
297 	unittext = hourly_imagescale_logic(2000000, 0);
298 	ck_assert_str_eq(unittext, "MiB");
299 
300 	unittext = hourly_imagescale_logic(1000000000, 0);
301 	ck_assert_str_eq(unittext, "MiB");
302 
303 	unittext = hourly_imagescale_logic(2000000000, 0);
304 	ck_assert_str_eq(unittext, "GiB");
305 
306 	unittext = hourly_imagescale_logic(2000000000000ULL, 0);
307 	ck_assert_str_eq(unittext, "TiB");
308 }
309 END_TEST
310 
START_TEST(hourly_imagescaling_rate_1024)311 START_TEST(hourly_imagescaling_rate_1024)
312 {
313 	char *unittext;
314 
315 	cfg.unitmode = 0;
316 	cfg.rateunit = 0;
317 	cfg.rateunitmode = 0;
318 
319 	unittext = hourly_imagescale_logic(1, 1);
320 	ck_assert_str_eq(unittext, "B/s");
321 
322 	unittext = hourly_imagescale_logic(100, 1);
323 	ck_assert_str_eq(unittext, "B/s");
324 
325 	unittext = hourly_imagescale_logic(981, 1);
326 	ck_assert_str_eq(unittext, "B/s");
327 
328 	unittext = hourly_imagescale_logic(1000, 1);
329 	ck_assert_str_eq(unittext, "B/s");
330 
331 	unittext = hourly_imagescale_logic(1024, 1);
332 	ck_assert_str_eq(unittext, "KiB/s");
333 
334 	unittext = hourly_imagescale_logic(2000, 1);
335 	ck_assert_str_eq(unittext, "KiB/s");
336 
337 	unittext = hourly_imagescale_logic(1000000, 1);
338 	ck_assert_str_eq(unittext, "KiB/s");
339 
340 	unittext = hourly_imagescale_logic(1024000, 1);
341 	ck_assert_str_eq(unittext, "KiB/s");
342 
343 	unittext = hourly_imagescale_logic(1300000, 1);
344 	ck_assert_str_eq(unittext, "MiB/s");
345 
346 	unittext = hourly_imagescale_logic(2000000, 1);
347 	ck_assert_str_eq(unittext, "MiB/s");
348 
349 	unittext = hourly_imagescale_logic(1000000000, 1);
350 	ck_assert_str_eq(unittext, "MiB/s");
351 
352 	unittext = hourly_imagescale_logic(2000000000, 1);
353 	ck_assert_str_eq(unittext, "GiB/s");
354 
355 	unittext = hourly_imagescale_logic(2000000000000ULL, 1);
356 	ck_assert_str_eq(unittext, "TiB/s");
357 }
358 END_TEST
359 
START_TEST(hourly_imagescaling_rate_1000)360 START_TEST(hourly_imagescaling_rate_1000)
361 {
362 	char *unittext;
363 
364 	cfg.unitmode = 0;
365 	cfg.rateunit = 1;
366 	cfg.rateunitmode = 1;
367 
368 	unittext = hourly_imagescale_logic(1, 1);
369 	ck_assert_str_eq(unittext, "bit/s");
370 
371 	unittext = hourly_imagescale_logic(100, 1);
372 	ck_assert_str_eq(unittext, "bit/s");
373 
374 	unittext = hourly_imagescale_logic(981, 1);
375 	ck_assert_str_eq(unittext, "bit/s");
376 
377 	unittext = hourly_imagescale_logic(1000, 1);
378 	ck_assert_str_eq(unittext, "kbit/s");
379 
380 	unittext = hourly_imagescale_logic(1024, 1);
381 	ck_assert_str_eq(unittext, "kbit/s");
382 
383 	unittext = hourly_imagescale_logic(2000, 1);
384 	ck_assert_str_eq(unittext, "kbit/s");
385 
386 	unittext = hourly_imagescale_logic(1000000, 1);
387 	ck_assert_str_eq(unittext, "Mbit/s");
388 
389 	unittext = hourly_imagescale_logic(1024000, 1);
390 	ck_assert_str_eq(unittext, "Mbit/s");
391 
392 	unittext = hourly_imagescale_logic(1300000, 1);
393 	ck_assert_str_eq(unittext, "Mbit/s");
394 
395 	unittext = hourly_imagescale_logic(2000000, 1);
396 	ck_assert_str_eq(unittext, "Mbit/s");
397 
398 	unittext = hourly_imagescale_logic(1000000000, 1);
399 	ck_assert_str_eq(unittext, "Gbit/s");
400 
401 	unittext = hourly_imagescale_logic(2000000000, 1);
402 	ck_assert_str_eq(unittext, "Gbit/s");
403 
404 	unittext = hourly_imagescale_logic(2000000000000ULL, 1);
405 	ck_assert_str_eq(unittext, "Tbit/s");
406 }
407 END_TEST
408 
START_TEST(libgd_output_comparison)409 START_TEST(libgd_output_comparison)
410 {
411 	int ret, x, y;
412 	IMAGECONTENT ic;
413 	FILE *pngout;
414 
415 	x = 1060;
416 	y = 420;
417 
418 	initimagecontent(&ic);
419 	imageinit(&ic, x, y);
420 	ic.interface.updated = (time_t)get_timestamp(2001, 2, 3, 4, 5);
421 	layoutinit(&ic, "vnstati libgd output comparison", x, y);
422 
423 	pngout = fopen("vnstati_libgd_comparison_check.png", "w");
424 	ck_assert_ptr_ne(pngout, NULL);
425 
426 	drawlegend(&ic, 40, 30, 0);
427 	drawlegend(&ic, 240, 30, 1);
428 
429 	/* line 1 */
430 	x = 40;
431 	y = 80;
432 	gdImageStringUp(ic.im, gdFontGetSmall(), 1, y + 105, (unsigned char *)"libgd bug workaround", ic.ctext);
433 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)0, (float)0, 49, 15);
434 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)50, (float)50, 49, 15);
435 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"0/0 - 50/50", ic.ctext);
436 
437 	x += 130;
438 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)100, (float)0, 49, 15);
439 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)0, (float)100, 49, 15);
440 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"100/0 - 0/100", ic.ctext);
441 
442 	x += 130;
443 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)60, (float)40, 49, 15);
444 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)40, (float)60, 49, 15);
445 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"60/40 - 40/60", ic.ctext);
446 
447 	x += 130;
448 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)75, (float)25, 49, 15);
449 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)25, (float)75, 49, 15);
450 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"75/25 - 25/75", ic.ctext);
451 
452 	x += 130;
453 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)90, (float)10, 49, 15);
454 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)10, (float)90, 49, 15);
455 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"90/10 - 10/90", ic.ctext);
456 
457 	x += 130;
458 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)95, (float)5, 49, 15);
459 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)5, (float)95, 49, 15);
460 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"95/5 - 5/95", ic.ctext);
461 
462 	x += 130;
463 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)99, (float)1, 49, 15);
464 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)1, (float)99, 49, 15);
465 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"99/1 - 1/99", ic.ctext);
466 
467 	x += 130;
468 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)99.9, (float)0.1, 49, 15);
469 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)0.1, (float)99.9, 49, 15);
470 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"99.9/0.1 - 0.1/99.9", ic.ctext);
471 
472 	/* line 2 */
473 	x = 40;
474 	y = 160;
475 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)0, (float)0, 49, 15);
476 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)25, (float)25, 49, 15);
477 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"0/0 - 25/25", ic.ctext);
478 
479 	x += 130;
480 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)50, (float)0, 49, 15);
481 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)0, (float)50, 49, 15);
482 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"50/0 - 0/50", ic.ctext);
483 
484 	x += 130;
485 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)40, (float)30, 49, 15);
486 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)30, (float)40, 49, 15);
487 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"40/30 - 30/40", ic.ctext);
488 
489 	x += 130;
490 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)30, (float)20, 49, 15);
491 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)20, (float)30, 49, 15);
492 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"30/20 - 20/30", ic.ctext);
493 
494 	x += 130;
495 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)20, (float)10, 49, 15);
496 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)10, (float)20, 49, 15);
497 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"20/10 - 10/20", ic.ctext);
498 
499 	x += 130;
500 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)15, (float)5, 49, 15);
501 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)5, (float)15, 49, 15);
502 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"15/5 - 5/15", ic.ctext);
503 
504 	x += 130;
505 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)10, (float)1, 49, 15);
506 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)1, (float)10, 49, 15);
507 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"10/1 - 1/10", ic.ctext);
508 
509 	x += 130;
510 	drawdonut_libgd_bug_workaround(&ic, x, y, (float)1, (float)0.1, 49, 15);
511 	drawdonut_libgd_bug_workaround(&ic, x + 55, y, (float)0.1, (float)1, 49, 15);
512 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"1.0/0.1 - 0.1/1.0", ic.ctext);
513 
514 	/* line 3 */
515 	x = 40;
516 	y = 270;
517 	gdImageStringUp(ic.im, gdFontGetSmall(), 1, y + 105, (unsigned char *)"libgd native", ic.ctext);
518 	drawdonut_libgd_native(&ic, x, y, (float)0, (float)0, 49, 15);
519 	drawdonut_libgd_native(&ic, x + 55, y, (float)50, (float)50, 49, 15);
520 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"0/0 - 50/50", ic.ctext);
521 
522 	x += 130;
523 	drawdonut_libgd_native(&ic, x, y, (float)100, (float)0, 49, 15);
524 	drawdonut_libgd_native(&ic, x + 55, y, (float)0, (float)100, 49, 15);
525 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"100/0 - 0/100", ic.ctext);
526 
527 	x += 130;
528 	drawdonut_libgd_native(&ic, x, y, (float)60, (float)40, 49, 15);
529 	drawdonut_libgd_native(&ic, x + 55, y, (float)40, (float)60, 49, 15);
530 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"60/40 - 40/60", ic.ctext);
531 
532 	x += 130;
533 	drawdonut_libgd_native(&ic, x, y, (float)75, (float)25, 49, 15);
534 	drawdonut_libgd_native(&ic, x + 55, y, (float)25, (float)75, 49, 15);
535 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"75/25 - 25/75", ic.ctext);
536 
537 	x += 130;
538 	drawdonut_libgd_native(&ic, x, y, (float)90, (float)10, 49, 15);
539 	drawdonut_libgd_native(&ic, x + 55, y, (float)10, (float)90, 49, 15);
540 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"90/10 - 10/90", ic.ctext);
541 
542 	x += 130;
543 	drawdonut_libgd_native(&ic, x, y, (float)95, (float)5, 49, 15);
544 	drawdonut_libgd_native(&ic, x + 55, y, (float)5, (float)95, 49, 15);
545 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"95/5 - 5/95", ic.ctext);
546 
547 	x += 130;
548 	drawdonut_libgd_native(&ic, x, y, (float)99, (float)1, 49, 15);
549 	drawdonut_libgd_native(&ic, x + 55, y, (float)1, (float)99, 49, 15);
550 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"99/1 - 1/99", ic.ctext);
551 
552 	x += 130;
553 	drawdonut_libgd_native(&ic, x, y, (float)99.9, (float)0.1, 49, 15);
554 	drawdonut_libgd_native(&ic, x + 55, y, (float)0.1, (float)99.9, 49, 15);
555 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"99.9/0.1 - 0.1/99.9", ic.ctext);
556 
557 	/* line 4 */
558 	x = 40;
559 	y = 350;
560 	drawdonut_libgd_native(&ic, x, y, (float)0, (float)0, 49, 15);
561 	drawdonut_libgd_native(&ic, x + 55, y, (float)25, (float)25, 49, 15);
562 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"0/0 - 25/25", ic.ctext);
563 
564 	x += 130;
565 	drawdonut_libgd_native(&ic, x, y, (float)50, (float)0, 49, 15);
566 	drawdonut_libgd_native(&ic, x + 55, y, (float)0, (float)50, 49, 15);
567 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"50/0 - 0/50", ic.ctext);
568 
569 	x += 130;
570 	drawdonut_libgd_native(&ic, x, y, (float)40, (float)30, 49, 15);
571 	drawdonut_libgd_native(&ic, x + 55, y, (float)30, (float)40, 49, 15);
572 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"40/30 - 30/40", ic.ctext);
573 
574 	x += 130;
575 	drawdonut_libgd_native(&ic, x, y, (float)30, (float)20, 49, 15);
576 	drawdonut_libgd_native(&ic, x + 55, y, (float)20, (float)30, 49, 15);
577 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"30/20 - 20/30", ic.ctext);
578 
579 	x += 130;
580 	drawdonut_libgd_native(&ic, x, y, (float)20, (float)10, 49, 15);
581 	drawdonut_libgd_native(&ic, x + 55, y, (float)10, (float)20, 49, 15);
582 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"20/10 - 10/20", ic.ctext);
583 
584 	x += 130;
585 	drawdonut_libgd_native(&ic, x, y, (float)15, (float)5, 49, 15);
586 	drawdonut_libgd_native(&ic, x + 55, y, (float)5, (float)15, 49, 15);
587 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"15/5 - 5/15", ic.ctext);
588 
589 	x += 130;
590 	drawdonut_libgd_native(&ic, x, y, (float)10, (float)1, 49, 15);
591 	drawdonut_libgd_native(&ic, x + 55, y, (float)1, (float)10, 49, 15);
592 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"10/1 - 1/10", ic.ctext);
593 
594 	x += 130;
595 	drawdonut_libgd_native(&ic, x, y, (float)1, (float)0.1, 49, 15);
596 	drawdonut_libgd_native(&ic, x + 55, y, (float)0.1, (float)1, 49, 15);
597 	gdImageString(ic.im, gdFontGetSmall(), x - 20, y + 30, (unsigned char *)"1.0/0.1 - 0.1/1.0", ic.ctext);
598 
599 	gdImagePng(ic.im, pngout);
600 	ret = fclose(pngout);
601 	ck_assert_int_eq(ret, 0);
602 	gdImageDestroy(ic.im);
603 }
604 END_TEST
605 
START_TEST(element_output_check)606 START_TEST(element_output_check)
607 {
608 	int ret, x, y, i;
609 	float f;
610 	char buffer[6];
611 	IMAGECONTENT ic;
612 	FILE *pngout;
613 
614 	x = 1500;
615 	y = 900;
616 
617 	initimagecontent(&ic);
618 	imageinit(&ic, x, y);
619 	ic.interface.updated = (time_t)get_timestamp(2012, 3, 4, 5, 6);
620 	layoutinit(&ic, "donut with 0.2% input steps and other elements", x, y);
621 
622 	pngout = fopen("vnstati_element_check.png", "w");
623 	ck_assert_ptr_ne(pngout, NULL);
624 
625 	x = 40;
626 	y = 70;
627 
628 	gdImageStringUp(ic.im, gdFontGetSmall(), 1, y + 15, (unsigned char *)"50.0%", ic.ctext);
629 
630 	for (f = 50.0; f >= 0; f -= (float)0.2) {
631 
632 		drawdonut(&ic, x, y, f, f, 49, 15);
633 		x += 55;
634 
635 		if (x > 1000) {
636 			x = 40;
637 			y += 60;
638 
639 			snprintf(buffer, 6, "%3.1f%%", (double)f - 0.2);
640 			gdImageStringUp(ic.im, gdFontGetSmall(), 1, y + 15, (unsigned char *)buffer, ic.ctext);
641 		}
642 	}
643 
644 	gdImageString(ic.im, gdFontGetGiant(), 1020, 40, (unsigned char *)"Giant - The quick brown fox jumps over the lazy dog", ic.ctext);
645 	gdImageString(ic.im, gdFontGetLarge(), 1020, 60, (unsigned char *)"Large - The quick brown fox jumps over the lazy dog", ic.ctext);
646 	gdImageString(ic.im, gdFontGetMediumBold(), 1020, 80, (unsigned char *)"MediumBold - The quick brown fox jumps over the lazy dog", ic.ctext);
647 	gdImageString(ic.im, gdFontGetSmall(), 1020, 100, (unsigned char *)"Small - The quick brown fox jumps over the lazy dog", ic.ctext);
648 	gdImageString(ic.im, gdFontGetTiny(), 1020, 120, (unsigned char *)"Tiny - The quick brown fox jumps over the lazy dog", ic.ctext);
649 
650 	drawlegend(&ic, 1130, 140, 0);
651 	drawlegend(&ic, 1330, 140, 1);
652 
653 	drawbar(&ic, 1050, 160, 100, 50, 50, 100, 0);
654 	drawbar(&ic, 1050, 180, 100, 25, 75, 100, 0);
655 	drawbar(&ic, 1050, 200, 100, 75, 25, 100, 0);
656 	drawbar(&ic, 1050, 220, 100, 0, 100, 100, 0);
657 	drawbar(&ic, 1050, 240, 100, 100, 0, 100, 0);
658 
659 	drawbar(&ic, 1050, 260, 100, 1, 99, 100, 0);
660 	drawbar(&ic, 1050, 280, 100, 2, 98, 100, 0);
661 
662 	drawbar(&ic, 1050, 300, 100, 99, 1, 100, 0);
663 	drawbar(&ic, 1050, 320, 100, 98, 2, 100, 0);
664 
665 	drawbar(&ic, 1200, 160, 100, 1, 0, 100, 0);
666 	drawbar(&ic, 1200, 180, 100, 2, 0, 100, 0);
667 	drawbar(&ic, 1200, 200, 100, 3, 0, 100, 0);
668 
669 	drawbar(&ic, 1200, 220, 100, 0, 1, 100, 0);
670 	drawbar(&ic, 1200, 240, 100, 0, 2, 100, 0);
671 	drawbar(&ic, 1200, 260, 100, 0, 3, 100, 0);
672 
673 	drawbar(&ic, 1200, 280, 100, 25, 25, 100, 0);
674 	drawbar(&ic, 1200, 300, 100, 10, 30, 100, 0);
675 	drawbar(&ic, 1200, 320, 100, 30, 10, 100, 0);
676 
677 	gdImageLine(ic.im, 1040, 360, 1260, 360, ic.ctext);
678 	gdImageLine(ic.im, 1040, 760, 1260, 760, ic.ctext);
679 
680 	gdImageLine(ic.im, 1250, 350, 1250, 770, ic.ctext);
681 
682 	drawarrowup(&ic, 1250, 350);
683 	drawarrowright(&ic, 1260, 360);
684 
685 	drawpoles(&ic, 1050, 360, 400, 50, 50, 100);
686 	drawpoles(&ic, 1070, 360, 400, 25, 75, 100);
687 	drawpoles(&ic, 1090, 360, 400, 75, 25, 100);
688 	drawpoles(&ic, 1110, 360, 400, 0, 100, 100);
689 	drawpoles(&ic, 1130, 360, 400, 100, 0, 100);
690 
691 	drawpoles(&ic, 1150, 360, 400, 50, 50, 130);
692 	drawpoles(&ic, 1170, 360, 400, 25, 75, 130);
693 	drawpoles(&ic, 1190, 360, 400, 75, 25, 130);
694 	drawpoles(&ic, 1210, 360, 400, 0, 100, 130);
695 	drawpoles(&ic, 1230, 360, 400, 100, 0, 130);
696 
697 	gdImageLine(ic.im, 1040, 870, 1160, 870, ic.ctext);
698 	gdImageLine(ic.im, 1040, 820, 1160, 820, ic.ctext);
699 	gdImageLine(ic.im, 1040, 770, 1160, 770, ic.ctext);
700 
701 	for (i = 0; i < 100; i++) {
702 		drawpole(&ic, 1050 + i, 819, i % 50, 1, ic.crx);
703 		drawpole(&ic, 1050 + i, 821, i % 50, 2, ic.ctx);
704 	}
705 
706 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 400, (unsigned char *)"Color: ctext", ic.ctext);
707 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 420, (unsigned char *)"Color: cedge", ic.cedge);
708 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 440, (unsigned char *)"Color: cheader", ic.cheader);
709 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 460, (unsigned char *)"Color: cheadertitle", ic.cheadertitle);
710 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 480, (unsigned char *)"Color: cheaderdate", ic.cheaderdate);
711 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 500, (unsigned char *)"Color: cline", ic.cline);
712 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 520, (unsigned char *)"Color: clinel", ic.clinel);
713 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 540, (unsigned char *)"Color: cbackground", ic.cbackground);
714 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 560, (unsigned char *)"Color: cvnstat", ic.cvnstat);
715 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 580, (unsigned char *)"Color: cbgoffset", ic.cbgoffset);
716 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 600, (unsigned char *)"Color: crx", ic.crx);
717 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 620, (unsigned char *)"Color: crxd", ic.crxd);
718 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 640, (unsigned char *)"Color: ctx", ic.ctx);
719 	gdImageString(ic.im, gdFontGetMediumBold(), 1280, 660, (unsigned char *)"Color: ctxd", ic.ctxd);
720 
721 	gdImagePng(ic.im, pngout);
722 	ret = fclose(pngout);
723 	ck_assert_int_eq(ret, 0);
724 	gdImageDestroy(ic.im);
725 }
726 END_TEST
727 
START_TEST(hextorgb_can_convert)728 START_TEST(hextorgb_can_convert)
729 {
730 	debug = 1;
731 	int rgb[3];
732 
733 	suppress_output();
734 
735 	rgb[0] = 1;
736 	rgb[1] = 2;
737 	rgb[2] = 3;
738 	hextorgb("000000", rgb);
739 	ck_assert_int_eq(rgb[0], 0);
740 	ck_assert_int_eq(rgb[1], 0);
741 	ck_assert_int_eq(rgb[2], 0);
742 
743 	rgb[0] = 1;
744 	rgb[1] = 2;
745 	rgb[2] = 3;
746 	hextorgb("#000000", rgb);
747 	ck_assert_int_eq(rgb[0], 0);
748 	ck_assert_int_eq(rgb[1], 0);
749 	ck_assert_int_eq(rgb[2], 0);
750 
751 	rgb[0] = 1;
752 	rgb[1] = 2;
753 	rgb[2] = 3;
754 	hextorgb("FFFFFF", rgb);
755 	ck_assert_int_eq(rgb[0], 255);
756 	ck_assert_int_eq(rgb[1], 255);
757 	ck_assert_int_eq(rgb[2], 255);
758 
759 	rgb[0] = 1;
760 	rgb[1] = 2;
761 	rgb[2] = 3;
762 	hextorgb("#FFFFFF", rgb);
763 	ck_assert_int_eq(rgb[0], 255);
764 	ck_assert_int_eq(rgb[1], 255);
765 	ck_assert_int_eq(rgb[2], 255);
766 
767 	rgb[0] = 1;
768 	rgb[1] = 2;
769 	rgb[2] = 3;
770 	hextorgb("ABCABBA", rgb);
771 	ck_assert_int_eq(rgb[0], 171);
772 	ck_assert_int_eq(rgb[1], 202);
773 	ck_assert_int_eq(rgb[2], 187);
774 
775 	rgb[0] = 1;
776 	rgb[1] = 2;
777 	rgb[2] = 3;
778 	hextorgb("#ABCABBA", rgb);
779 	ck_assert_int_eq(rgb[0], 171);
780 	ck_assert_int_eq(rgb[1], 202);
781 	ck_assert_int_eq(rgb[2], 187);
782 }
783 END_TEST
784 
START_TEST(modcolor_mods_colors)785 START_TEST(modcolor_mods_colors)
786 {
787 	debug = 1;
788 	int rgb[3];
789 
790 	suppress_output();
791 
792 	rgb[0] = 10;
793 	rgb[1] = 20;
794 	rgb[2] = 30;
795 	modcolor(rgb, 10, 0);
796 	ck_assert_int_eq(rgb[0], 20);
797 	ck_assert_int_eq(rgb[1], 30);
798 	ck_assert_int_eq(rgb[2], 40);
799 
800 	rgb[0] = 10;
801 	rgb[1] = 20;
802 	rgb[2] = 30;
803 	modcolor(rgb, -10, 0);
804 	ck_assert_int_eq(rgb[0], 0);
805 	ck_assert_int_eq(rgb[1], 10);
806 	ck_assert_int_eq(rgb[2], 20);
807 
808 	rgb[0] = 10;
809 	rgb[1] = 20;
810 	rgb[2] = 30;
811 	modcolor(rgb, -20, 0);
812 	ck_assert_int_eq(rgb[0], 0);
813 	ck_assert_int_eq(rgb[1], 0);
814 	ck_assert_int_eq(rgb[2], 10);
815 
816 	rgb[0] = 10;
817 	rgb[1] = 20;
818 	rgb[2] = 30;
819 	modcolor(rgb, -30, 0);
820 	ck_assert_int_eq(rgb[0], 40);
821 	ck_assert_int_eq(rgb[1], 50);
822 	ck_assert_int_eq(rgb[2], 60);
823 
824 	rgb[0] = 10;
825 	rgb[1] = 20;
826 	rgb[2] = 30;
827 	modcolor(rgb, -30, 1);
828 	ck_assert_int_eq(rgb[0], 0);
829 	ck_assert_int_eq(rgb[1], 0);
830 	ck_assert_int_eq(rgb[2], 0);
831 
832 	rgb[0] = 10;
833 	rgb[1] = 250;
834 	rgb[2] = 30;
835 	modcolor(rgb, 30, 0);
836 	ck_assert_int_eq(rgb[0], 40);
837 	ck_assert_int_eq(rgb[1], 255);
838 	ck_assert_int_eq(rgb[2], 60);
839 
840 	rgb[0] = 10;
841 	rgb[1] = 250;
842 	rgb[2] = 30;
843 	modcolor(rgb, 30, 1);
844 	ck_assert_int_eq(rgb[0], 40);
845 	ck_assert_int_eq(rgb[1], 255);
846 	ck_assert_int_eq(rgb[2], 60);
847 
848 	rgb[0] = 10;
849 	rgb[1] = 250;
850 	rgb[2] = 251;
851 	modcolor(rgb, 30, 0);
852 	ck_assert_int_eq(rgb[0], 0);
853 	ck_assert_int_eq(rgb[1], 220);
854 	ck_assert_int_eq(rgb[2], 221);
855 
856 	rgb[0] = 10;
857 	rgb[1] = 250;
858 	rgb[2] = 251;
859 	modcolor(rgb, 30, 1);
860 	ck_assert_int_eq(rgb[0], 40);
861 	ck_assert_int_eq(rgb[1], 255);
862 	ck_assert_int_eq(rgb[2], 255);
863 
864 	rgb[0] = 10;
865 	rgb[1] = 20;
866 	rgb[2] = 251;
867 	modcolor(rgb, -30, 0);
868 	ck_assert_int_eq(rgb[0], 40);
869 	ck_assert_int_eq(rgb[1], 50);
870 	ck_assert_int_eq(rgb[2], 255);
871 }
872 END_TEST
873 
add_image_tests(Suite * s)874 void add_image_tests(Suite *s)
875 {
876 	TCase *tc_image = tcase_create("Image");
877 	tcase_add_checked_fixture(tc_image, setup, teardown);
878 	tcase_add_unchecked_fixture(tc_image, setup, teardown);
879 	tcase_set_timeout(tc_image, 10);
880 	tcase_add_test(tc_image, initimagecontent_does_not_crash);
881 	tcase_add_test(tc_image, imageinit_does_not_crash);
882 	tcase_add_test(tc_image, layoutinit_does_not_crash);
883 	tcase_add_test(tc_image, getimagevalue_zeropadding);
884 	tcase_add_test(tc_image, getimagevalue_normal);
885 	tcase_add_test(tc_image, getimagevalue_rate_1024);
886 	tcase_add_test(tc_image, getimagevalue_rate_1000);
887 	tcase_add_test(tc_image, getimagescale_zero);
888 	tcase_add_test(tc_image, getimagescale_normal);
889 	tcase_add_test(tc_image, getimagescale_rate);
890 	tcase_add_test(tc_image, getscale_zero);
891 	tcase_add_test(tc_image, getscale_nonzero_1024);
892 	tcase_add_test(tc_image, getscale_nonzero_1000);
893 	tcase_add_test(tc_image, hourly_imagescaling_normal);
894 	tcase_add_test(tc_image, hourly_imagescaling_rate_1024);
895 	tcase_add_test(tc_image, hourly_imagescaling_rate_1000);
896 	tcase_add_test(tc_image, libgd_output_comparison);
897 	tcase_add_test(tc_image, element_output_check);
898 	tcase_add_test(tc_image, hextorgb_can_convert);
899 	tcase_add_test(tc_image, modcolor_mods_colors);
900 	suite_add_tcase(s, tc_image);
901 }
902