image_translate_tests.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. /*
  2. * SpanDSP - a series of DSP components for telephony
  3. *
  4. * image_translate_tests.c - Tests for the image translation routines.
  5. *
  6. * Written by Steve Underwood <steveu@coppice.org>
  7. *
  8. * Copyright (C) 2009 Steve Underwood
  9. *
  10. * All rights reserved.
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License version 2, as
  14. * published by the Free Software Foundation.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24. */
  25. /*! \file */
  26. /*! \page image_translate_tests_page Image translation tests
  27. \section image_translate_tests_page_sec_1 What does it do?
  28. */
  29. #if defined(HAVE_CONFIG_H)
  30. #include "config.h"
  31. #endif
  32. #include <inttypes.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include <string.h>
  37. #include <assert.h>
  38. #include <math.h>
  39. #include <errno.h>
  40. #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
  41. #include "spandsp.h"
  42. #define INPUT_TIFF_FILE_NAME "../test-data/local/lenna-colour.tif"
  43. typedef struct
  44. {
  45. const uint8_t *image;
  46. int width;
  47. int length;
  48. int current_row;
  49. int bytes_per_pixel;
  50. } image_descriptor_t;
  51. static void display_row(int row, int width, uint8_t buf[])
  52. {
  53. int i;
  54. int test_pixel;
  55. printf("%3d: ", row);
  56. for (i = 0; i < width; i++)
  57. {
  58. test_pixel = (buf[i >> 3] >> (7 - (i & 7))) & 0x01;
  59. printf("%c", (test_pixel) ? ' ' : '@');
  60. }
  61. printf("\n");
  62. }
  63. /*- End of function --------------------------------------------------------*/
  64. static void create_undithered_50_by_50(image_descriptor_t *im, uint8_t buf[], int bytes_per_pixel)
  65. {
  66. unsigned int i;
  67. unsigned int j;
  68. uint8_t *image8;
  69. uint16_t *image16;
  70. int samples_per_pixel;
  71. im->image = (const uint8_t *) buf;
  72. im->width = 50;
  73. im->length = 50;
  74. im->bytes_per_pixel = bytes_per_pixel;
  75. im->current_row = 0;
  76. switch (bytes_per_pixel)
  77. {
  78. case 1:
  79. samples_per_pixel = 1;
  80. image8 = buf;
  81. for (i = 0; i < im->length; i++)
  82. {
  83. for (j = 0; j < im->width; j++)
  84. image8[im->width*i + j] = ((i + j)*655) >> 8;
  85. }
  86. break;
  87. case 2:
  88. samples_per_pixel = 1;
  89. image16 = (uint16_t *) buf;
  90. for (i = 0; i < im->length; i++)
  91. {
  92. for (j = 0; j < im->width; j++)
  93. image16[im->width*i + j] = (i + j)*655;
  94. }
  95. break;
  96. case 3:
  97. samples_per_pixel = 3;
  98. image8 = buf;
  99. for (i = 0; i < im->length; i++)
  100. {
  101. for (j = 0; j < im->width; j++)
  102. {
  103. #if 0
  104. image8[samples_per_pixel*(im->width*i + j) + 0] = ((i + j)*655) >> 8;
  105. image8[samples_per_pixel*(im->width*i + j) + 1] = ((i + j)*655) >> 8;
  106. image8[samples_per_pixel*(im->width*i + j) + 2] = ((i + j)*655) >> 8;
  107. #else
  108. image8[samples_per_pixel*(im->width*i + j) + 0] = saturateu8((((i + j)*655U)*36532U) >> 23);
  109. image8[samples_per_pixel*(im->width*i + j) + 1] = saturateu8((((i + j)*655U)*37216U) >> 24);
  110. image8[samples_per_pixel*(im->width*i + j) + 2] = saturateu8((((i + j)*655U)*47900U) >> 22);
  111. #endif
  112. }
  113. }
  114. break;
  115. case 4:
  116. samples_per_pixel = 4;
  117. image8 = buf;
  118. for (i = 0; i < im->length; i++)
  119. {
  120. for (j = 0; j < im->width; j++)
  121. {
  122. #if 0
  123. image8[samples_per_pixel*(im->width*i + j) + 0] = ((i + j)*655) >> 8;
  124. image8[samples_per_pixel*(im->width*i + j) + 1] = ((i + j)*655) >> 8;
  125. image8[samples_per_pixel*(im->width*i + j) + 2] = ((i + j)*655) >> 8;
  126. image8[samples_per_pixel*(im->width*i + j) + 3] = 0;
  127. #else
  128. image8[samples_per_pixel*(im->width*i + j) + 0] = saturateu8((((i + j)*655U)*36532U) >> 23);
  129. image8[samples_per_pixel*(im->width*i + j) + 1] = saturateu8((((i + j)*655U)*37216U) >> 24);
  130. image8[samples_per_pixel*(im->width*i + j) + 2] = saturateu8((((i + j)*655U)*47900U) >> 22);
  131. image8[samples_per_pixel*(im->width*i + j) + 3] = 0;
  132. #endif
  133. }
  134. }
  135. break;
  136. case 6:
  137. samples_per_pixel = 3;
  138. image16 = (uint16_t *) buf;
  139. for (i = 0; i < im->length; i++)
  140. {
  141. for (j = 0; j < im->width; j++)
  142. {
  143. #if 0
  144. image16[samples_per_pixel*(im->width*i + j) + 0] = (i + j)*655;
  145. image16[samples_per_pixel*(im->width*i + j) + 1] = (i + j)*655;
  146. image16[samples_per_pixel*(im->width*i + j) + 2] = (i + j)*655;
  147. #else
  148. image16[samples_per_pixel*(im->width*i + j) + 0] = saturateu16((((i + j)*655U)*36532U) >> 15);
  149. image16[samples_per_pixel*(im->width*i + j) + 1] = saturateu16((((i + j)*655U)*37216U) >> 16);
  150. image16[samples_per_pixel*(im->width*i + j) + 2] = saturateu16((((i + j)*655U)*47900U) >> 14);
  151. #endif
  152. }
  153. }
  154. break;
  155. case 8:
  156. samples_per_pixel = 4;
  157. image16 = (uint16_t *) buf;
  158. for (i = 0; i < im->length; i++)
  159. {
  160. for (j = 0; j < im->width; j++)
  161. {
  162. #if 0
  163. image16[samples_per_pixel*(im->width*i + j) + 0] = (i + j)*655;
  164. image16[samples_per_pixel*(im->width*i + j) + 1] = (i + j)*655;
  165. image16[samples_per_pixel*(im->width*i + j) + 2] = (i + j)*655;
  166. image16[samples_per_pixel*(im->width*i + j) + 3] = 0;
  167. #else
  168. image16[samples_per_pixel*(im->width*i + j) + 0] = saturateu16((((i + j)*655U)*36532U) >> 15);
  169. image16[samples_per_pixel*(im->width*i + j) + 1] = saturateu16((((i + j)*655U)*37216U) >> 16);
  170. image16[samples_per_pixel*(im->width*i + j) + 2] = saturateu16((((i + j)*655U)*47900U) >> 14);
  171. image16[samples_per_pixel*(im->width*i + j) + 3] = 0;
  172. #endif
  173. }
  174. }
  175. break;
  176. }
  177. }
  178. /*- End of function --------------------------------------------------------*/
  179. static int test_dithered_50_by_50(int row, int width, uint8_t buf[])
  180. {
  181. static const char *image[50] =
  182. {
  183. " 0: @ @ @ @ @ @ @ @ ",
  184. " 1: @ @ @ @ @ @ @ @ @ @ @ @ @ @",
  185. " 2: @ @ @ @ @ @ @ @ @ @ @ @ @",
  186. " 3: @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
  187. " 4: @ @ @ @ @ @ @ @ @ @ @ @ @ @",
  188. " 5: @ @ @ @ @ @ @ @ @ @ @ @ @ ",
  189. " 6: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@",
  190. " 7: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
  191. " 8: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ",
  192. " 9: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @",
  193. " 10: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @@",
  194. " 11: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ ",
  195. " 12: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @ @ @",
  196. " 13: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @",
  197. " 14: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @ @@",
  198. " 15: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @ @@ ",
  199. " 16: @ @ @ @ @ @ @ @ @ @ @@ @ @@@ @@",
  200. " 17: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @",
  201. " 18: @ @ @ @ @ @ @ @ @ @ @ @ @@ @@ @@ @@@ ",
  202. " 19: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @ @",
  203. " 20: @ @ @ @ @ @ @ @ @ @ @ @ @@ @@ @@@ @@@@@",
  204. " 21: @ @ @ @ @ @ @ @ @ @@ @ @ @ @ @ @ @ @@ @ @",
  205. " 22: @ @ @ @ @ @ @ @ @ @ @ @@ @@ @@@ @ @@ @@",
  206. " 23: @ @ @ @ @ @ @ @ @ @@ @ @ @ @ @ @ @@@ @@ @",
  207. " 24: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @@ @@@ @ @ @@ @@",
  208. " 25: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@@@@ @@@@",
  209. " 26: @ @ @ @ @ @ @ @ @ @ @ @ @@ @@ @@@ @ @ @@@ @ @",
  210. " 27: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@@ @@ @@@@@",
  211. " 28: @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @@ @ @ @@ @@ @ @",
  212. " 29: @ @ @ @ @ @ @ @ @ @ @ @@ @@ @@ @@@@@ @@@ @@@@",
  213. " 30: @ @ @ @ @ @ @ @ @ @ @@ @@ @ @ @@ @ @@@ @@@ @@",
  214. " 31: @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @@@ @ @@ @@@ @@@@",
  215. " 32: @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @@@@@ @@ @@@ @@",
  216. " 33: @ @ @ @ @ @ @ @ @ @ @ @@ @@@ @@ @ @ @ @@@@@ @@@@",
  217. " 34: @ @ @ @ @ @ @ @ @ @@ @ @ @ @@ @@@@@@@ @ @@@@ @@",
  218. " 35: @ @ @ @ @ @ @ @ @ @@ @@ @@ @@ @ @ @@@@@@ @@@@",
  219. " 36: @ @ @ @ @ @ @ @ @ @ @ @@ @@ @@ @@@ @@ @ @@@@@@ @",
  220. " 37: @ @ @ @ @ @ @ @ @@ @@ @ @ @@ @@ @ @@@@@@@ @@ @@@",
  221. " 38: @ @ @ @ @ @ @ @ @ @ @ @@@ @@ @@ @@@@ @ @@@@@@@@@@",
  222. " 39: @ @ @ @ @ @ @ @@ @@ @@ @@ @@@@ @@@@ @@ @@ @@@",
  223. " 40: @ @ @ @ @@ @ @ @@ @ @ @ @ @@ @@ @ @@ @@@@@@@@@@@@",
  224. " 41: @ @ @ @ @ @ @ @@ @ @@@ @@@ @@@ @@@@@@@@@ @@ @@ @@",
  225. " 42: @ @ @ @ @@ @ @ @ @@ @ @@ @@ @@@@ @ @ @@@@@@@@@@@@",
  226. " 43: @ @ @ @ @ @ @@ @@ @ @@ @@ @@@ @ @@@@@@@ @@ @@@@@@",
  227. " 44: @ @ @ @ @ @ @ @ @@ @@ @@ @@ @@@@@ @@ @@@@@@@@ @@@",
  228. " 45: @ @ @ @ @ @ @@ @@ @@ @@ @@ @@@ @ @@@@@@@@ @@@@@@@@",
  229. " 46: @ @ @ @ @ @ @@ @ @ @@ @@ @@ @@@@@ @ @@ @@@@@@@@@@",
  230. " 47: @ @ @ @ @ @@ @ @ @@@@ @@@@ @@@@@ @@@@@@@@@@@ @@@@@",
  231. " 48: @ @ @ @@ @ @@ @@ @ @@ @ @@@ @ @@@@@ @@@@@@@@@@@@@",
  232. " 49: @ @ @ @ @ @@ @@ @@ @@ @@@@ @@@@@@@ @@@@@@ @@@@@@@@"
  233. };
  234. int i;
  235. int match;
  236. int ref_pixel;
  237. int test_pixel;
  238. match = 0;
  239. for (i = 0; i < width; i++)
  240. {
  241. ref_pixel = (image[row][i + 5] == ' ');
  242. test_pixel = (buf[i >> 3] >> (7 - (i & 7))) & 0x01;
  243. if (ref_pixel != test_pixel)
  244. match = -1;
  245. }
  246. return match;
  247. }
  248. /*- End of function --------------------------------------------------------*/
  249. static int row_read(void *user_data, uint8_t buf[], size_t len)
  250. {
  251. image_descriptor_t *im;
  252. im = (image_descriptor_t *) user_data;
  253. if (im->current_row >= im->length)
  254. return 0;
  255. memcpy(buf, &im->image[im->current_row*im->width*im->bytes_per_pixel], len);
  256. im->current_row++;
  257. return len;
  258. }
  259. /*- End of function --------------------------------------------------------*/
  260. static void get_bilevel_image(image_translate_state_t *s, int compare)
  261. {
  262. int i;
  263. int len;
  264. uint8_t row_buf[s->output_length*s->output_width/8];
  265. for (i = 0; i < s->output_length; i++)
  266. {
  267. if ((len = image_translate_row(s, row_buf, (s->output_width + 7)/8)) != (s->output_width + 7)/8)
  268. {
  269. printf("Image finished early - %d %d\n", len, (s->output_width + 7)/8);
  270. exit(2);
  271. }
  272. display_row(i, s->output_width, row_buf);
  273. if (compare)
  274. {
  275. if (test_dithered_50_by_50(i, s->output_width, row_buf))
  276. {
  277. printf("Dithered image mismatch at row %d\n", i);
  278. //exit(2);
  279. }
  280. }
  281. }
  282. if ((len = image_translate_row(s, row_buf, (s->output_width + 7)/8)) != 0)
  283. {
  284. printf("Image finished late - %d %d\n", len, (s->output_width + 7)/8);
  285. exit(2);
  286. }
  287. }
  288. /*- End of function --------------------------------------------------------*/
  289. static void get_gray8_image(image_translate_state_t *s, int compare)
  290. {
  291. unsigned int i;
  292. unsigned int j;
  293. int len;
  294. uint8_t row_buf[s->output_length*s->output_width];
  295. for (i = 0; i < s->output_length; i++)
  296. {
  297. if ((len = image_translate_row(s, row_buf, s->output_width)) != s->output_width)
  298. {
  299. printf("Image finished early - %d %d\n", len, s->output_width);
  300. exit(2);
  301. }
  302. if (compare)
  303. {
  304. for (j = 0; j < 50; j++)
  305. {
  306. if (row_buf[j] != (((i + j)*655) >> 8))
  307. {
  308. printf("Image mismatch - %dx%d - %d %d\n", j, i, ((i + j)*655) >> 8, row_buf[j]);
  309. //exit(2);
  310. }
  311. }
  312. }
  313. }
  314. if ((len = image_translate_row(s, row_buf, s->output_width)) != 0)
  315. {
  316. printf("Image finished late - %d %d\n", len, s->output_width);
  317. exit(2);
  318. }
  319. }
  320. /*- End of function --------------------------------------------------------*/
  321. static void get_gray16_image(image_translate_state_t *s, int compare)
  322. {
  323. unsigned int i;
  324. unsigned int j;
  325. int len;
  326. uint16_t row_buf[s->output_length*s->output_width];
  327. for (i = 0; i < s->output_length; i++)
  328. {
  329. if ((len = image_translate_row(s, (uint8_t *) row_buf, 2*s->output_width)) != 2*s->output_width)
  330. {
  331. printf("Image finished early - %d %d\n", len, 2*s->output_width);
  332. exit(2);
  333. }
  334. if (compare)
  335. {
  336. for (j = 0; j < s->output_width; j++)
  337. {
  338. if (row_buf[j] != (i + j)*655)
  339. {
  340. printf("Image mismatch - %dx%d - %d %d\n", j, i, (i + j)*655, row_buf[j]);
  341. //exit(2);
  342. }
  343. }
  344. }
  345. }
  346. if ((len = image_translate_row(s, (uint8_t *) row_buf, 2*s->output_width)) != 0)
  347. {
  348. printf("Image finished late - %d %d\n", len, 2*s->output_width);
  349. exit(2);
  350. }
  351. }
  352. /*- End of function --------------------------------------------------------*/
  353. static void get_colour8_image(image_translate_state_t *s, int compare)
  354. {
  355. unsigned int i;
  356. unsigned int j;
  357. int samples_per_pixel;
  358. int len;
  359. int r;
  360. int g;
  361. int b;
  362. uint8_t row_buf[3*s->output_length*s->output_width];
  363. samples_per_pixel = 3;
  364. for (i = 0; i < s->output_length; i++)
  365. {
  366. if ((len = image_translate_row(s, row_buf, samples_per_pixel*s->output_width)) != samples_per_pixel*s->output_width)
  367. {
  368. printf("Image finished early - %d %d\n", len, samples_per_pixel*s->output_width);
  369. exit(2);
  370. }
  371. if (compare)
  372. {
  373. for (j = 0; j < s->output_width; j++)
  374. {
  375. #if 0
  376. r = ((i + j)*655) >> 8;
  377. g = ((i + j)*655) >> 8;
  378. b = ((i + j)*655) >> 8;
  379. #else
  380. r = saturateu8((((i + j)*655U)*36532U) >> 23);
  381. g = saturateu8((((i + j)*655U)*37216U) >> 24);
  382. b = saturateu8((((i + j)*655U)*47900U) >> 22);
  383. #endif
  384. if (row_buf[samples_per_pixel*j + 0] != r
  385. ||
  386. row_buf[samples_per_pixel*j + 1] != g
  387. ||
  388. row_buf[samples_per_pixel*j + 2] != b)
  389. {
  390. printf("Image mismatch - %dx%d - (%d %d %d) (%d %d %d)\n",
  391. j, i,
  392. r, g, b,
  393. row_buf[samples_per_pixel*j + 0], row_buf[samples_per_pixel*j + 1], row_buf[samples_per_pixel*j + 2]);
  394. //exit(2);
  395. }
  396. }
  397. }
  398. }
  399. if ((len = image_translate_row(s, row_buf, samples_per_pixel*s->output_width)) != 0)
  400. {
  401. printf("Image finished late - %d %d\n", len, samples_per_pixel*s->output_width);
  402. exit(2);
  403. }
  404. }
  405. /*- End of function --------------------------------------------------------*/
  406. static void get_colour16_image(image_translate_state_t *s, int compare)
  407. {
  408. unsigned int i;
  409. unsigned int j;
  410. int samples_per_pixel;
  411. int len;
  412. int r;
  413. int g;
  414. int b;
  415. uint16_t row_buf[3*s->output_length*s->output_width];
  416. samples_per_pixel = 3;
  417. for (i = 0; i < s->output_length; i++)
  418. {
  419. if ((len = image_translate_row(s, (uint8_t *) row_buf, 2*samples_per_pixel*s->output_width)) != 2*samples_per_pixel*s->output_width)
  420. {
  421. printf("Image finished early - %d %d\n", len, 2*samples_per_pixel*s->output_width);
  422. exit(2);
  423. }
  424. if (compare)
  425. {
  426. for (j = 0; j < s->output_width; j++)
  427. {
  428. #if 0
  429. r = (i + j)*655;
  430. g = (i + j)*655;
  431. b = (i + j)*655;
  432. #else
  433. r = saturateu16((((i + j)*655U)*36532U) >> 15);
  434. g = saturateu16((((i + j)*655U)*37216U) >> 16);
  435. b = saturateu16((((i + j)*655U)*47900U) >> 14);
  436. #endif
  437. if (row_buf[samples_per_pixel*j + 0] != r
  438. ||
  439. row_buf[samples_per_pixel*j + 1] != g
  440. ||
  441. row_buf[samples_per_pixel*j + 2] != b)
  442. {
  443. printf("Image mismatch - %dx%d - (%d %d %d) (%d %d %d)\n",
  444. j, i,
  445. r, g, b,
  446. row_buf[samples_per_pixel*j + 0], row_buf[samples_per_pixel*j + 1], row_buf[samples_per_pixel*j + 2]);
  447. //exit(2);
  448. }
  449. }
  450. }
  451. }
  452. if ((len = image_translate_row(s, (uint8_t *) row_buf, 2*samples_per_pixel*s->output_width)) != 0)
  453. {
  454. printf("Image finished late - %d %d\n", len, 2*samples_per_pixel*s->output_width);
  455. exit(2);
  456. }
  457. }
  458. /*- End of function --------------------------------------------------------*/
  459. static void translate_tests_gray8(void)
  460. {
  461. image_translate_state_t *s;
  462. uint8_t image[50*50];
  463. image_descriptor_t im;
  464. printf("Dithering from a 8 bit per sample gray scale to bi-level\n");
  465. create_undithered_50_by_50(&im, image, 1);
  466. s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, row_read, &im);
  467. get_bilevel_image(s, true);
  468. printf("Scrunching from a 8 bit per sample gray scale to 8 bit per sample gray scale\n");
  469. create_undithered_50_by_50(&im, image, 1);
  470. s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, row_read, &im);
  471. get_gray8_image(s, true);
  472. printf("Scrunching from a 8 bit per sample gray scale to 16 bit per sample gray scale\n");
  473. create_undithered_50_by_50(&im, image, 1);
  474. s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, row_read, &im);
  475. get_gray16_image(s, true);
  476. printf("Scrunching from a 8 bit per sample gray scale to 3x8 bit per sample colour\n");
  477. create_undithered_50_by_50(&im, image, 1);
  478. s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, row_read, &im);
  479. get_colour8_image(s, true);
  480. printf("Scrunching from a 8 bit per sample gray scale to 3x16 bit per sample colour\n");
  481. create_undithered_50_by_50(&im, image, 1);
  482. s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, row_read, &im);
  483. get_colour16_image(s, true);
  484. image_translate_free(s);
  485. }
  486. /*- End of function --------------------------------------------------------*/
  487. static void translate_tests_gray16(void)
  488. {
  489. image_translate_state_t *s;
  490. uint16_t image[50*50];
  491. image_descriptor_t im;
  492. printf("Dithering from a 16 bit per sample gray scale to bi-level\n");
  493. create_undithered_50_by_50(&im, (uint8_t *) image, 2);
  494. s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, -1, -1, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, row_read, &im);
  495. get_bilevel_image(s, true);
  496. printf("Scrunching from a 16 bit per sample gray scale to 8 bit per sample gray scale\n");
  497. create_undithered_50_by_50(&im, (uint8_t *) image, 2);
  498. s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, row_read, &im);
  499. get_gray8_image(s, true);
  500. printf("Scrunching from a 16 bit per sample gray scale to 16 bit per sample gray scale\n");
  501. create_undithered_50_by_50(&im, (uint8_t *) image, 2);
  502. s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, row_read, &im);
  503. get_gray16_image(s, true);
  504. printf("Scrunching from a 16 bit per sample gray scale to 3x8 bit per sample colour\n");
  505. create_undithered_50_by_50(&im, (uint8_t *) image, 2);
  506. s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, row_read, &im);
  507. get_colour8_image(s, true);
  508. printf("Scrunching from a 16 bit per sample gray scale to 3x16 bit per sample colour\n");
  509. create_undithered_50_by_50(&im, (uint8_t *) image, 2);
  510. s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, row_read, &im);
  511. get_colour16_image(s, true);
  512. image_translate_free(s);
  513. }
  514. /*- End of function --------------------------------------------------------*/
  515. static void translate_tests_colour8(void)
  516. {
  517. image_translate_state_t *s;
  518. uint8_t image[3*50*50];
  519. image_descriptor_t im;
  520. printf("Dithering from a 3x8 bit per sample colour to bi-level\n");
  521. create_undithered_50_by_50(&im, image, 3);
  522. s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, -1, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
  523. get_bilevel_image(s, true);
  524. printf("Scrunching from a 3x8 bit per sample colour to 8 bit per sample gray scale\n");
  525. create_undithered_50_by_50(&im, image, 3);
  526. s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
  527. get_gray8_image(s, true);
  528. printf("Scrunching from a 3x8 bit per sample colour to 16 bit per sample gray scale\n");
  529. create_undithered_50_by_50(&im, image, 3);
  530. s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
  531. get_gray16_image(s, true);
  532. printf("Scrunching from a 3x8 bit per sample colour to 3x8 bit per sample colour\n");
  533. create_undithered_50_by_50(&im, image, 3);
  534. s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
  535. get_colour8_image(s, true);
  536. printf("Scrunching from a 3x8 bit per sample colour to 3x16 bit per sample colour\n");
  537. create_undithered_50_by_50(&im, image, 3);
  538. s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
  539. get_colour16_image(s, true);
  540. image_translate_free(s);
  541. }
  542. /*- End of function --------------------------------------------------------*/
  543. static void translate_tests_colour16(void)
  544. {
  545. image_translate_state_t *s;
  546. uint16_t image[3*50*50];
  547. image_descriptor_t im;
  548. printf("Dithering from a 3x16 bit per sample colour to bi-level\n");
  549. create_undithered_50_by_50(&im, (uint8_t *) image, 6);
  550. s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, -1, -1, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, row_read, &im);
  551. get_bilevel_image(s, true);
  552. printf("Scrunching from a 3x16 bit per sample colour to 8 bit per sample gray scale\n");
  553. create_undithered_50_by_50(&im, (uint8_t *) image, 6);
  554. s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, row_read, &im);
  555. get_gray8_image(s, true);
  556. printf("Scrunching from a 3x16 bit per sample colour to 16 bit per sample gray scale\n");
  557. create_undithered_50_by_50(&im, (uint8_t *) image, 6);
  558. s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, row_read, &im);
  559. get_gray16_image(s, true);
  560. printf("Scrunching from a 3x16 bit per sample colour to 3x8 bit per sample colour\n");
  561. create_undithered_50_by_50(&im, (uint8_t *) image, 6);
  562. s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, row_read, &im);
  563. get_colour8_image(s, true);
  564. printf("Scrunching from a 3x16 bit per sample colour to 3x16 bit per sample colour\n");
  565. create_undithered_50_by_50(&im, (uint8_t *) image, 6);
  566. s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, row_read, &im);
  567. get_colour16_image(s, true);
  568. image_translate_free(s);
  569. }
  570. /*- End of function --------------------------------------------------------*/
  571. static void grow_tests_colour8(void)
  572. {
  573. image_translate_state_t *s;
  574. uint8_t image[3*50*50];
  575. image_descriptor_t im;
  576. printf("Image growth tests\n");
  577. create_undithered_50_by_50(&im, image, 3);
  578. s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, 200, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
  579. get_bilevel_image(s, false);
  580. image_translate_free(s);
  581. }
  582. /*- End of function --------------------------------------------------------*/
  583. static int row_read2(void *user_data, uint8_t buf[], size_t len)
  584. {
  585. image_translate_state_t *s;
  586. s = (image_translate_state_t *) user_data;
  587. image_translate_row(s, buf, len);
  588. return len;
  589. }
  590. /*- End of function --------------------------------------------------------*/
  591. static void lenna_tests(int output_width, int output_length_scaling, const char *file)
  592. {
  593. TIFF *in_file;
  594. TIFF *out_file;
  595. int image_width;
  596. int image_length;
  597. int output_length;
  598. int len;
  599. int total;
  600. int i;
  601. int n;
  602. uint8_t *image;
  603. uint8_t *image2;
  604. int16_t bits_per_sample;
  605. int16_t samples_per_pixel;
  606. uint16_t res_unit;
  607. image_translate_state_t *s;
  608. image_translate_state_t *s2;
  609. image_descriptor_t im;
  610. float x_resolution;
  611. float y_resolution;
  612. if (output_length_scaling >= 0)
  613. printf("Dithering Lenna from colour to bi-level test\n");
  614. else
  615. printf("Processing Lenna test\n");
  616. if ((in_file = TIFFOpen(INPUT_TIFF_FILE_NAME, "r")) == NULL)
  617. return;
  618. image_width = 0;
  619. TIFFGetField(in_file, TIFFTAG_IMAGEWIDTH, &image_width);
  620. if (image_width <= 0)
  621. return;
  622. image_length = 0;
  623. TIFFGetField(in_file, TIFFTAG_IMAGELENGTH, &image_length);
  624. if (image_length <= 0)
  625. return;
  626. x_resolution = 200.0;
  627. TIFFGetField(in_file, TIFFTAG_XRESOLUTION, &x_resolution);
  628. y_resolution = 200.0;
  629. TIFFGetField(in_file, TIFFTAG_YRESOLUTION, &y_resolution);
  630. res_unit = RESUNIT_INCH;
  631. TIFFGetField(in_file, TIFFTAG_RESOLUTIONUNIT, &res_unit);
  632. bits_per_sample = 0;
  633. TIFFGetField(in_file, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
  634. samples_per_pixel = 0;
  635. TIFFGetField(in_file, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
  636. printf("Original image is %d x %d, %.2f x %.2f resolution, %d bits per sample, %d samples per pixel\n", image_width, image_length, x_resolution, y_resolution, bits_per_sample, samples_per_pixel);
  637. if ((image = malloc(image_width*image_length*samples_per_pixel)) == NULL)
  638. return;
  639. for (total = 0, i = 0; i < 1000; i++)
  640. {
  641. len = TIFFReadEncodedStrip(in_file, i, &image[total], image_width*image_length*samples_per_pixel - total);
  642. if (len <= 0)
  643. break;
  644. total += len;
  645. if (total == image_width*image_length*samples_per_pixel)
  646. {
  647. printf("Done\n");
  648. break;
  649. }
  650. }
  651. printf("Input image size %d %d\n", total, image_width*image_length*samples_per_pixel);
  652. TIFFClose(in_file);
  653. if (output_length_scaling > 0)
  654. output_length = (double) image_length*output_length_scaling*output_width/image_width;
  655. else
  656. output_length = -1;
  657. im.image = image;
  658. im.width = image_width;
  659. im.length = image_length;
  660. im.current_row = 0;
  661. im.bytes_per_pixel = samples_per_pixel;
  662. s2 = NULL;
  663. switch (output_length_scaling)
  664. {
  665. case -2:
  666. s = image_translate_init(NULL, T4_IMAGE_TYPE_GRAY_8BIT, output_width, output_length, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, row_read, &im);
  667. output_width = image_translate_get_output_width(s);
  668. output_length = image_translate_get_output_length(s);
  669. s2 = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, output_width, output_length, row_read2, s);
  670. output_width = image_translate_get_output_width(s2);
  671. output_length = image_translate_get_output_length(s2);
  672. break;
  673. case -1:
  674. s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, output_width, output_length, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, row_read, &im);
  675. output_width = image_translate_get_output_width(s);
  676. output_length = image_translate_get_output_length(s);
  677. break;
  678. default:
  679. s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, output_width, output_length, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, row_read, &im);
  680. output_width = image_translate_get_output_width(s);
  681. output_length = image_translate_get_output_length(s);
  682. break;
  683. }
  684. if ((out_file = TIFFOpen(file, "w")) == NULL)
  685. return;
  686. TIFFSetField(out_file, TIFFTAG_IMAGEWIDTH, output_width);
  687. TIFFSetField(out_file, TIFFTAG_IMAGELENGTH, output_length);
  688. TIFFSetField(out_file, TIFFTAG_RESOLUTIONUNIT, res_unit);
  689. switch (output_length_scaling)
  690. {
  691. case -2:
  692. case -1:
  693. TIFFSetField(out_file, TIFFTAG_BITSPERSAMPLE, 8);
  694. TIFFSetField(out_file, TIFFTAG_SAMPLESPERPIXEL, 3);
  695. TIFFSetField(out_file, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
  696. break;
  697. default:
  698. TIFFSetField(out_file, TIFFTAG_BITSPERSAMPLE, 1);
  699. TIFFSetField(out_file, TIFFTAG_SAMPLESPERPIXEL, 1);
  700. TIFFSetField(out_file, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
  701. break;
  702. }
  703. if (output_length_scaling > 0)
  704. y_resolution *= output_length_scaling;
  705. TIFFSetField(out_file, TIFFTAG_XRESOLUTION, x_resolution);
  706. TIFFSetField(out_file, TIFFTAG_YRESOLUTION, y_resolution);
  707. TIFFSetField(out_file, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
  708. TIFFSetField(out_file, TIFFTAG_ROWSPERSTRIP, -1);
  709. TIFFSetField(out_file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  710. TIFFSetField(out_file, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB);
  711. TIFFSetField(out_file, TIFFTAG_PAGENUMBER, 0, 1);
  712. printf("Input %d x %d, output %d x %d\n", image_width, image_length, output_width, output_length);
  713. switch (output_length_scaling)
  714. {
  715. case -2:
  716. if ((image2 = malloc(output_width*output_length*3)) == NULL)
  717. return;
  718. memset(image2, 0, output_width*output_length*3);
  719. n = 0;
  720. for (i = 0; i < output_length; i++)
  721. n += image_translate_row(s2, &image2[n], output_width*3);
  722. TIFFWriteEncodedStrip(out_file, 0, image2, n);
  723. break;
  724. case -1:
  725. if ((image2 = malloc(output_width*output_length*3)) == NULL)
  726. return;
  727. memset(image2, 0, output_width*output_length*3);
  728. n = 0;
  729. for (i = 0; i < output_length; i++)
  730. n += image_translate_row(s, &image2[n], output_width*3);
  731. TIFFWriteEncodedStrip(out_file, 0, image2, n);
  732. break;
  733. default:
  734. if ((image2 = malloc(output_width*output_length/8)) == NULL)
  735. return;
  736. memset(image2, 0, output_width*output_length/8);
  737. n = 0;
  738. for (i = 0; i < output_length; i++)
  739. n += image_translate_row(s, &image2[n], output_width/8);
  740. TIFFWriteEncodedStrip(out_file, 0, image2, n);
  741. break;
  742. }
  743. TIFFWriteDirectory(out_file);
  744. TIFFClose(out_file);
  745. image_translate_free(s);
  746. free(image);
  747. free(image2);
  748. }
  749. /*- End of function --------------------------------------------------------*/
  750. int main(int argc, char **argv)
  751. {
  752. #if 1
  753. translate_tests_gray16();
  754. translate_tests_gray8();
  755. translate_tests_colour16();
  756. translate_tests_colour8();
  757. #endif
  758. #if 1
  759. grow_tests_colour8();
  760. #endif
  761. #if 1
  762. lenna_tests(0, 0, "lenna-bw.tif");
  763. lenna_tests(200, 0, "lenna-bw-200.tif");
  764. lenna_tests(1728, 0, "lenna-bw-1728.tif");
  765. lenna_tests(1728, 2, "lenna-bw-1728-superfine.tif");
  766. lenna_tests(1728, -1, "lenna-colour-1728.tif");
  767. lenna_tests(1728, -2, "lenna-gray-1728.tif");
  768. #endif
  769. printf("Tests passed.\n");
  770. return 0;
  771. }
  772. /*- End of function --------------------------------------------------------*/
  773. /*- End of file ------------------------------------------------------------*/