gxhtbit.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /* Copyright (C) 1999, 2000 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: gxhtbit.c,v 1.5 2002/02/21 22:24:53 giles Exp $ */
  14. /* Halftone bit updating for imaging library */
  15. #include "memory_.h"
  16. #include "gx.h"
  17. #include "gserrors.h"
  18. #include "gsbitops.h"
  19. #include "gscdefs.h"
  20. #include "gxbitmap.h"
  21. #include "gxhttile.h"
  22. #include "gxtmap.h"
  23. #include "gxdht.h"
  24. #include "gxdhtres.h"
  25. extern_gx_device_halftone_list();
  26. /*
  27. * Construct a standard-representation order from a threshold array.
  28. */
  29. private int
  30. construct_ht_order_default(gx_ht_order *porder, const byte *thresholds)
  31. {
  32. gx_ht_bit *bits = (gx_ht_bit *)porder->bit_data;
  33. uint i;
  34. for (i = 0; i < porder->num_bits; i++)
  35. bits[i].mask = max(1, thresholds[i]);
  36. gx_ht_complete_threshold_order(porder);
  37. return 0;
  38. }
  39. /*
  40. * Construct a short-representation order from a threshold array.
  41. * Uses porder->width, num_levels, num_bits, levels, bit_data;
  42. * sets porder->levels[], bit_data[].
  43. */
  44. private int
  45. construct_ht_order_short(gx_ht_order *porder, const byte *thresholds)
  46. {
  47. uint size = porder->num_bits;
  48. uint i;
  49. ushort *bits = (ushort *)porder->bit_data;
  50. uint *levels = porder->levels;
  51. uint num_levels = porder->num_levels;
  52. memset(levels, 0, num_levels * sizeof(*levels));
  53. /* Count the number of threshold elements with each value. */
  54. for (i = 0; i < size; i++) {
  55. uint value = max(1, thresholds[i]);
  56. if (value + 1 < num_levels)
  57. levels[value + 1]++;
  58. }
  59. for (i = 2; i < num_levels; ++i)
  60. levels[i] += levels[i - 1];
  61. /* Now construct the actual order. */
  62. {
  63. uint width = porder->width;
  64. uint padding = bitmap_raster(width) * 8 - width;
  65. for (i = 0; i < size; i++) {
  66. uint value = max(1, thresholds[i]);
  67. /* Adjust the bit index to account for padding. */
  68. bits[levels[value]++] = i + (i / width * padding);
  69. }
  70. }
  71. /* Check whether this is a predefined halftone. */
  72. {
  73. const gx_dht_proc *phtrp = gx_device_halftone_list;
  74. for (; *phtrp; ++phtrp) {
  75. const gx_device_halftone_resource_t *const *pphtr = (*phtrp)();
  76. const gx_device_halftone_resource_t *phtr;
  77. while ((phtr = *pphtr++) != 0) {
  78. if (phtr->Width == porder->width &&
  79. phtr->Height == porder->height &&
  80. phtr->elt_size == sizeof(ushort) &&
  81. !memcmp(phtr->levels, levels, num_levels * sizeof(*levels)) &&
  82. !memcmp(phtr->bit_data, porder->bit_data,
  83. size * phtr->elt_size)
  84. ) {
  85. /*
  86. * This is a predefined halftone. Free the levels and
  87. * bit_data arrays, replacing them with the built-in ones.
  88. */
  89. if (porder->data_memory) {
  90. gs_free_object(porder->data_memory, porder->bit_data,
  91. "construct_ht_order_short(bit_data)");
  92. gs_free_object(porder->data_memory, porder->levels,
  93. "construct_ht_order_short(levels)");
  94. }
  95. porder->data_memory = 0;
  96. porder->levels = (uint *)phtr->levels; /* actually const */
  97. porder->bit_data = (void *)phtr->bit_data; /* actually const */
  98. goto out;
  99. }
  100. }
  101. }
  102. }
  103. out:
  104. return 0;
  105. }
  106. /* Return the bit coordinate using the standard representation. */
  107. private int
  108. ht_bit_index_default(const gx_ht_order *porder, uint index, gs_int_point *ppt)
  109. {
  110. const gx_ht_bit *phtb = &((const gx_ht_bit *)porder->bit_data)[index];
  111. uint offset = phtb->offset;
  112. int bit = 0;
  113. while (!(((const byte *)&phtb->mask)[bit >> 3] & (0x80 >> (bit & 7))))
  114. ++bit;
  115. ppt->x = (offset % porder->raster * 8) + bit;
  116. ppt->y = offset / porder->raster;
  117. return 0;
  118. }
  119. /* Return the bit coordinate using the short representation. */
  120. private int
  121. ht_bit_index_short(const gx_ht_order *porder, uint index, gs_int_point *ppt)
  122. {
  123. uint bit_index = ((const ushort *)porder->bit_data)[index];
  124. uint bit_raster = porder->raster * 8;
  125. ppt->x = bit_index % bit_raster;
  126. ppt->y = bit_index / bit_raster;
  127. return 0;
  128. }
  129. /* Update a halftone tile using the default order representation. */
  130. private int
  131. render_ht_default(gx_ht_tile *pbt, int level, const gx_ht_order *porder)
  132. {
  133. int old_level = pbt->level;
  134. register const gx_ht_bit *p =
  135. (const gx_ht_bit *)porder->bit_data + old_level;
  136. register byte *data = pbt->tiles.data;
  137. /*
  138. * Invert bits between the two levels. Note that we can use the same
  139. * loop to turn bits either on or off, using xor. The Borland compiler
  140. * generates truly dreadful code if we don't use a temporary, and it
  141. * doesn't hurt better compilers, so we always use one.
  142. */
  143. #define INVERT_DATA(i)\
  144. BEGIN\
  145. ht_mask_t *dp = (ht_mask_t *)&data[p[i].offset];\
  146. *dp ^= p[i].mask;\
  147. END
  148. #ifdef DEBUG
  149. # define INVERT(i)\
  150. BEGIN\
  151. if_debug3('H', "[H]invert level=%d offset=%u mask=0x%x\n",\
  152. (int)(p + i - (const gx_ht_bit *)porder->bit_data),\
  153. p[i].offset, p[i].mask);\
  154. INVERT_DATA(i);\
  155. END
  156. #else
  157. # define INVERT(i) INVERT_DATA(i)
  158. #endif
  159. sw:switch (level - old_level) {
  160. default:
  161. if (level > old_level) {
  162. INVERT(0); INVERT(1); INVERT(2); INVERT(3);
  163. p += 4; old_level += 4;
  164. } else {
  165. INVERT(-1); INVERT(-2); INVERT(-3); INVERT(-4);
  166. p -= 4; old_level -= 4;
  167. }
  168. goto sw;
  169. case 7: INVERT(6);
  170. case 6: INVERT(5);
  171. case 5: INVERT(4);
  172. case 4: INVERT(3);
  173. case 3: INVERT(2);
  174. case 2: INVERT(1);
  175. case 1: INVERT(0);
  176. case 0: break; /* Shouldn't happen! */
  177. case -7: INVERT(-7);
  178. case -6: INVERT(-6);
  179. case -5: INVERT(-5);
  180. case -4: INVERT(-4);
  181. case -3: INVERT(-3);
  182. case -2: INVERT(-2);
  183. case -1: INVERT(-1);
  184. }
  185. #undef INVERT_DATA
  186. #undef INVERT
  187. return 0;
  188. }
  189. /* Update a halftone tile using the short representation. */
  190. private int
  191. render_ht_short(gx_ht_tile *pbt, int level, const gx_ht_order *porder)
  192. {
  193. int old_level = pbt->level;
  194. register const ushort *p = (const ushort *)porder->bit_data + old_level;
  195. register byte *data = pbt->tiles.data;
  196. /* Invert bits between the two levels. */
  197. #define INVERT_DATA(i)\
  198. BEGIN\
  199. uint bit_index = p[i];\
  200. byte *dp = &data[bit_index >> 3];\
  201. *dp ^= 0x80 >> (bit_index & 7);\
  202. END
  203. #ifdef DEBUG
  204. # define INVERT(i)\
  205. BEGIN\
  206. if_debug3('H', "[H]invert level=%d offset=%u mask=0x%x\n",\
  207. (int)(p + i - (const ushort *)porder->bit_data),\
  208. p[i] >> 3, 0x80 >> (p[i] & 7));\
  209. INVERT_DATA(i);\
  210. END
  211. #else
  212. # define INVERT(i) INVERT_DATA(i)
  213. #endif
  214. sw:switch (level - old_level) {
  215. default:
  216. if (level > old_level) {
  217. INVERT(0); INVERT(1); INVERT(2); INVERT(3);
  218. p += 4; old_level += 4;
  219. } else {
  220. INVERT(-1); INVERT(-2); INVERT(-3); INVERT(-4);
  221. p -= 4; old_level -= 4;
  222. }
  223. goto sw;
  224. case 7: INVERT(6);
  225. case 6: INVERT(5);
  226. case 5: INVERT(4);
  227. case 4: INVERT(3);
  228. case 3: INVERT(2);
  229. case 2: INVERT(1);
  230. case 1: INVERT(0);
  231. case 0: break; /* Shouldn't happen! */
  232. case -7: INVERT(-7);
  233. case -6: INVERT(-6);
  234. case -5: INVERT(-5);
  235. case -4: INVERT(-4);
  236. case -3: INVERT(-3);
  237. case -2: INVERT(-2);
  238. case -1: INVERT(-1);
  239. }
  240. #undef INVERT_DATA
  241. #undef INVERT
  242. return 0;
  243. }
  244. /* Define the procedure vectors for the order data implementations. */
  245. const gx_ht_order_procs_t ht_order_procs_table[2] = {
  246. { sizeof(gx_ht_bit), construct_ht_order_default, ht_bit_index_default,
  247. render_ht_default },
  248. { sizeof(ushort), construct_ht_order_short, ht_bit_index_short,
  249. render_ht_short }
  250. };