/tools/test.c

https://github.com/UprootLabs/poly-flif · C · 312 lines · 266 code · 40 blank · 6 comment · 57 complexity · 5f0677c9434cc6deb9f144901446a40a MD5 · raw file

  1. #include <flif.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #pragma pack(push,1)
  5. typedef struct RGBA
  6. {
  7. uint8_t r,g,b,a;
  8. } RGBA;
  9. #pragma pack(pop)
  10. void fill_dummy_image(FLIF_IMAGE* image)
  11. {
  12. uint32_t w = flif_image_get_width(image);
  13. uint32_t h = flif_image_get_height(image);
  14. RGBA* row = (RGBA*)malloc(w * sizeof(RGBA));
  15. if(row)
  16. {
  17. uint32_t y;
  18. for(y = 0; y < h; ++y)
  19. {
  20. uint32_t x;
  21. for(x = 0; x < w; ++x)
  22. {
  23. row[x].r = (x+y) % 255;
  24. row[x].g = (x) % 255;
  25. row[x].b = (y) % 255;
  26. row[x].a = 255;
  27. }
  28. flif_image_write_row_RGBA8(image, y, row, w * sizeof(RGBA));
  29. }
  30. free(row);
  31. }
  32. }
  33. int compare_images(FLIF_IMAGE* image1, FLIF_IMAGE* image2)
  34. {
  35. int result = 0;
  36. uint32_t w1 = flif_image_get_width(image1);
  37. uint32_t h1 = flif_image_get_height(image1);
  38. uint32_t w2 = flif_image_get_width(image2);
  39. uint32_t h2 = flif_image_get_height(image2);
  40. if(w1 != w2 || h1 != h2)
  41. {
  42. printf("Error: Images have different width/height\n");
  43. result = 1;
  44. }
  45. RGBA* row1 = (RGBA*)malloc(w1 * sizeof(RGBA));
  46. if(row1 == 0)
  47. {
  48. printf("Error: Out of memory\n");
  49. result = 1;
  50. }
  51. else
  52. {
  53. RGBA* row2 = (RGBA*)malloc(w1 * sizeof(RGBA));
  54. if(row2 == 0)
  55. {
  56. printf("Error: Out of memory\n");
  57. result = 1;
  58. }
  59. else
  60. {
  61. int difference = 0;
  62. uint32_t y;
  63. for(y = 0; y < h1; ++y)
  64. {
  65. flif_image_read_row_RGBA8(image1, y, row1, w1 * sizeof(RGBA));
  66. flif_image_read_row_RGBA8(image2, y, row2, w2 * sizeof(RGBA));
  67. uint32_t x;
  68. for(x = 0; x < w1; ++x)
  69. {
  70. if( row1[x].r != row2[x].r ||
  71. row1[x].g != row2[x].g ||
  72. row1[x].b != row2[x].b ||
  73. row1[x].a != row2[x].a)
  74. {
  75. // stop flooding the log if the image has many differences
  76. if(difference < 20)
  77. {
  78. printf("Error: Color difference at %u,%u: %02X%02X%02X%02X -> %02X%02X%02X%02X\n", x, y, row1[x].r, row1[x].g, row1[x].b, row1[x].a, row2[x].r, row2[x].g, row2[x].b, row2[x].a);
  79. result = 1;
  80. }
  81. difference++;
  82. }
  83. }
  84. }
  85. free(row2);
  86. }
  87. free(row1);
  88. }
  89. return result;
  90. }
  91. int compare_file_and_blob(const void* blob, size_t blob_size, const char* filename)
  92. {
  93. int result = 0;
  94. FILE* f = fopen(filename, "rb");
  95. if(f)
  96. {
  97. const uint8_t* blob_ptr = (const uint8_t*)blob;
  98. fseek(f, 0, SEEK_END);
  99. long int file_size = ftell(f);
  100. fseek(f, 0, SEEK_SET);
  101. if(file_size != blob_size)
  102. {
  103. printf("Error: flif file size: %ld <---> flif blob size: %zu\n", file_size, blob_size);
  104. result = 1;
  105. }
  106. else
  107. {
  108. size_t i;
  109. for(i = 0; i < blob_size; ++i)
  110. {
  111. int c = fgetc(f);
  112. if(c == EOF)
  113. {
  114. printf("IO error: premature EOF at %zu\n", i);
  115. result = 1;
  116. break;
  117. }
  118. if(c != *(blob_ptr + i))
  119. {
  120. printf("Error: file and blob do not match at %zu\n", i);
  121. result = 1;
  122. break;
  123. }
  124. }
  125. }
  126. fclose(f);
  127. }
  128. return result;
  129. }
  130. int main(int argc, char** argv)
  131. {
  132. if (argc < 2)
  133. {
  134. printf("first argument must be a file path for the test image");
  135. return 1;
  136. }
  137. int result = 0;
  138. const size_t WIDTH = 256;
  139. const size_t HEIGHT = 256;
  140. const char* dummy_file = argv[1];
  141. FLIF_IMAGE* im = flif_create_image(WIDTH, HEIGHT);
  142. if(im == 0)
  143. {
  144. printf("Error: flif_create_image failed\n");
  145. result = 1;
  146. }
  147. else
  148. {
  149. fill_dummy_image(im);
  150. void* blob = 0;
  151. size_t blob_size = 0;
  152. FLIF_ENCODER* e = flif_create_encoder();
  153. if(e)
  154. {
  155. flif_encoder_set_interlaced(e, 1);
  156. flif_encoder_set_learn_repeat(e, 3);
  157. flif_encoder_set_auto_color_buckets(e, 1);
  158. flif_encoder_set_palette_size(e, 512);
  159. flif_encoder_set_lookback(e, 1);
  160. flif_encoder_add_image(e, im);
  161. if(!flif_encoder_encode_file(e, dummy_file))
  162. {
  163. printf("Error: encoding file failed\n");
  164. result = 1;
  165. }
  166. flif_destroy_encoder(e);
  167. e = 0;
  168. }
  169. e = flif_create_encoder();
  170. if(e)
  171. {
  172. flif_encoder_set_interlaced(e, 1);
  173. flif_encoder_set_learn_repeat(e, 3);
  174. flif_encoder_set_auto_color_buckets(e, 1);
  175. flif_encoder_set_palette_size(e, 512);
  176. flif_encoder_set_lookback(e, 1);
  177. flif_encoder_add_image(e, im);
  178. if(!flif_encoder_encode_memory(e, &blob, &blob_size))
  179. {
  180. printf("Error: encoding blob failed\n");
  181. result = 1;
  182. }
  183. // TODO: uncommenting this causes subsequent test to fail???
  184. /*if(!compare_file_and_blob(blob, blob_size, dummy_file))
  185. {
  186. result = 1;
  187. }*/
  188. flif_destroy_encoder(e);
  189. e = 0;
  190. }
  191. FLIF_DECODER* d = flif_create_decoder();
  192. if(d)
  193. {
  194. flif_decoder_set_quality(d, 100);
  195. flif_decoder_set_scale(d, 1);
  196. {
  197. if(!flif_decoder_decode_file(d, dummy_file))
  198. {
  199. printf("Error: decoding file failed\n");
  200. result = 1;
  201. }
  202. FLIF_IMAGE* decoded = flif_decoder_get_image(d, 0);
  203. if(decoded == 0)
  204. {
  205. printf("Error: No decoded image found\n");
  206. result = 1;
  207. }
  208. else if(compare_images(im, decoded) != 0)
  209. {
  210. result = 1;
  211. }
  212. }
  213. {
  214. if(!flif_decoder_decode_memory(d, blob, blob_size))
  215. {
  216. printf("Error: decoding memory failed\n");
  217. result = 1;
  218. }
  219. FLIF_IMAGE* decoded = flif_decoder_get_image(d, 0);
  220. if(decoded == 0)
  221. {
  222. printf("Error: No decoded image found\n");
  223. result = 1;
  224. }
  225. else if(compare_images(im, decoded) != 0)
  226. {
  227. result = 1;
  228. }
  229. }
  230. flif_destroy_decoder(d);
  231. d = 0;
  232. }
  233. FLIF_INFO* info = flif_read_info_from_memory(blob, blob_size);
  234. if(info)
  235. {
  236. int w = flif_info_get_width(info);
  237. int h = flif_info_get_height(info);
  238. int channels = flif_info_get_nb_channels(info);
  239. int depth = flif_info_get_depth(info);
  240. int n = flif_info_num_images(info);
  241. if(w != WIDTH ||
  242. h != HEIGHT ||
  243. channels != 4 ||
  244. depth != 8 ||
  245. n != 1)
  246. {
  247. printf("Error: info should be %zux%zu, %d channels, %d bit, %d images.\n"
  248. " Instead it is %dx%d, %d channels, %d bit, %d images.\n",
  249. WIDTH, HEIGHT, 4, 8, 1,
  250. w, h, channels, depth, n);
  251. result = 1;
  252. }
  253. flif_destroy_info(info);
  254. info = 0;
  255. }
  256. else
  257. {
  258. printf("Error: flif_read_info_from_memory failed\n");
  259. result = 1;
  260. }
  261. flif_destroy_image(im);
  262. im = 0;
  263. if(blob)
  264. {
  265. flif_free_memory(blob);
  266. blob = 0;
  267. }
  268. }
  269. if (result) printf("interface test has FAILED.\n");
  270. else printf("interface test has succeeded.\n");
  271. return result;
  272. }