gdevm40.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. /* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises, 2001 Artifex Software. 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: gdevm40.c,v 1.3 2005/06/20 08:59:23 igor Exp $ */
  14. /* 40-bit-per-pixel "memory" (stored bitmap) device */
  15. #include "memory_.h"
  16. #include "gx.h"
  17. #include "gxdevice.h"
  18. #include "gxdevmem.h" /* semi-public definitions */
  19. #include "gdevmem.h" /* private definitions */
  20. /* Define debugging statistics. */
  21. #ifdef DEBUG
  22. struct stats_mem40_s {
  23. long
  24. fill, fwide, fgray[101], fsetc, fcolor[101], fnarrow[5],
  25. fprevc[257];
  26. double ftotal;
  27. } stats_mem40;
  28. static int prev_count = 0;
  29. static gx_color_index prev_colors[256];
  30. # define INCR(v) (++(stats_mem40.v))
  31. #else
  32. # define INCR(v) DO_NOTHING
  33. #endif
  34. /* ================ Standard (byte-oriented) device ================ */
  35. #undef chunk
  36. #define chunk byte
  37. #define PIXEL_SIZE 5
  38. /* Procedures */
  39. declare_mem_procs(mem_true40_copy_mono, mem_true40_copy_color, mem_true40_fill_rectangle);
  40. /* The device descriptor. */
  41. const gx_device_memory mem_true40_device =
  42. mem_full_alpha_device("image40", 40, 0, mem_open,
  43. gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb,
  44. mem_true40_copy_mono, mem_true40_copy_color, mem_true40_fill_rectangle,
  45. gx_default_map_cmyk_color, gx_default_copy_alpha,
  46. gx_default_strip_tile_rectangle, mem_default_strip_copy_rop,
  47. mem_get_bits_rectangle);
  48. /* Convert x coordinate to byte offset in scan line. */
  49. #undef x_to_byte
  50. #define x_to_byte(x) ((x) * PIXEL_SIZE)
  51. /* Unpack a color into its bytes. */
  52. #define declare_unpack_color(a, b, c, d, e, color)\
  53. byte a = (byte)(color >> 32);\
  54. byte b = (byte)((uint)color >> 24);\
  55. byte c = (byte)((uint)color >> 16);\
  56. byte d = (byte)((uint)color >> 8);\
  57. byte e = (byte)color
  58. /* Put a 40-bit color into the bitmap. */
  59. #define put5(ptr, a, b, c, d, e)\
  60. (ptr)[0] = a, (ptr)[1] = b, (ptr)[2] = c, (ptr)[3] = d, (ptr)[4] = e
  61. /* Put 4 bytes of color into the bitmap. */
  62. #define putw(ptr, wxyz)\
  63. *(bits32 *)(ptr) = (wxyz)
  64. /* Load the 5-word 40-bit-color cache. */
  65. /* Free variables: [m]dev, abcd, bcde, cdea, deab, earc. */
  66. #if arch_is_big_endian
  67. # define set_color40_cache(color, a, b, c, d, e)\
  68. mdev->color40.abcd = abcd = (color) >> 8, \
  69. mdev->color40.bcde = bcde = (abcd << 8) | (e),\
  70. mdev->color40.cdea = cdea = (bcde << 8) | (a),\
  71. mdev->color40.deab = deab = (cdea << 8) | (b),\
  72. mdev->color40.eabc = eabc = (deab << 8) | (c),\
  73. mdev->color40.abcde = (color)
  74. #else
  75. # define set_color40_cache(color, a, b, c, d, e)\
  76. mdev->color40.abcd = abcd =\
  77. ((bits32)(d) << 24) | ((bits32)(c) << 16) |\
  78. ((bits16)(b) << 8) | (a),\
  79. mdev->color40.eabc = eabc = (abcd << 8) | (e),\
  80. mdev->color40.deab = deab = (eabc << 8) | (d),\
  81. mdev->color40.cdea = cdea = (deab << 8) | (c),\
  82. mdev->color40.bcde = bcde = (cdea << 8) | (b),\
  83. mdev->color40.abcde = (color)
  84. #endif
  85. /* Fill a rectangle with a color. */
  86. private int
  87. mem_true40_fill_rectangle(gx_device * dev,
  88. int x, int y, int w, int h, gx_color_index color)
  89. {
  90. gx_device_memory * const mdev = (gx_device_memory *)dev;
  91. declare_unpack_color(a, b, c, d, e, color);
  92. declare_scan_ptr(dest);
  93. /*
  94. * In order to avoid testing w > 0 and h > 0 twice, we defer
  95. * executing setup_rect, and use fit_fill_xywh instead of
  96. * fit_fill.
  97. */
  98. fit_fill_xywh(dev, x, y, w, h);
  99. INCR(fill);
  100. #ifdef DEBUG
  101. stats_mem40.ftotal += w;
  102. #endif
  103. if (w >= 5) {
  104. if (h <= 0)
  105. return 0;
  106. INCR(fwide);
  107. setup_rect(dest);
  108. if (a == b && b == c && c == d && d == e) {
  109. int bcnt = w * PIXEL_SIZE;
  110. INCR(fgray[min(w, 100)]);
  111. while (h-- > 0) {
  112. memset(dest, a, bcnt);
  113. inc_ptr(dest, draster);
  114. }
  115. } else {
  116. int x3 = -x & 3, ww = w - x3; /* we know ww >= 2 */
  117. bits32 abcd, bcde, cdea, deab, eabc;
  118. if (mdev->color40.abcde == color) {
  119. abcd = mdev->color40.abcd;
  120. bcde = mdev->color40.bcde;
  121. cdea = mdev->color40.cdea;
  122. deab = mdev->color40.deab;
  123. eabc = mdev->color40.eabc;
  124. } else {
  125. INCR(fsetc);
  126. set_color40_cache(color, a, b, c, d, e);
  127. }
  128. #ifdef DEBUG
  129. {
  130. int ci;
  131. for (ci = 0; ci < prev_count; ++ci)
  132. if (prev_colors[ci] == color)
  133. break;
  134. INCR(fprevc[ci]);
  135. if (ci == prev_count) {
  136. if (ci < countof(prev_colors))
  137. ++prev_count;
  138. else
  139. --ci;
  140. }
  141. if (ci) {
  142. memmove(&prev_colors[1], &prev_colors[0],
  143. ci * sizeof(prev_colors[0]));
  144. prev_colors[0] = color;
  145. }
  146. }
  147. #endif
  148. INCR(fcolor[min(w, 100)]);
  149. while (h-- > 0) {
  150. register byte *pptr = dest;
  151. int w1 = ww;
  152. switch (x3) {
  153. case 1:
  154. pptr[0] = a;
  155. putw(pptr + 1, bcde);
  156. pptr += PIXEL_SIZE;
  157. break;
  158. case 2:
  159. pptr[0] = a;
  160. pptr[1] = b;
  161. putw(pptr + 2, cdea);
  162. putw(pptr + 6, bcde);
  163. pptr += 2 * PIXEL_SIZE;
  164. break;
  165. case 3:
  166. pptr[0] = a;
  167. pptr[1] = b;
  168. pptr[2] = c;
  169. putw(pptr + 3, deab);
  170. putw(pptr + 7, cdea);
  171. putw(pptr + 11, bcde);
  172. pptr += 3 * PIXEL_SIZE;
  173. break;
  174. case 0:
  175. ;
  176. }
  177. while (w1 >= 4) {
  178. putw(pptr, abcd);
  179. putw(pptr + 4, eabc);
  180. putw(pptr + 8, deab);
  181. putw(pptr + 12, cdea);
  182. putw(pptr + 16, bcde);
  183. pptr += 4 * PIXEL_SIZE;
  184. w1 -= 4;
  185. }
  186. switch (w1) {
  187. case 1:
  188. putw(pptr, abcd);
  189. pptr[4] = e;
  190. break;
  191. case 2:
  192. putw(pptr, abcd);
  193. putw(pptr + 4, eabc);
  194. pptr[8] = d;
  195. pptr[9] = e;
  196. break;
  197. case 3:
  198. putw(pptr, abcd);
  199. putw(pptr + 4, eabc);
  200. putw(pptr + 8, deab);
  201. pptr[12] = c;
  202. pptr[13] = d;
  203. pptr[14] = e;
  204. break;
  205. case 0:
  206. ;
  207. }
  208. inc_ptr(dest, draster);
  209. }
  210. }
  211. } else if (h > 0) { /* w < 5 */
  212. INCR(fnarrow[max(w, 0)]);
  213. setup_rect(dest);
  214. switch (w) {
  215. case 4:
  216. do {
  217. dest[15] = dest[10] = dest[5] = dest[0] = a;
  218. dest[16] = dest[11] = dest[6] = dest[1] = b;
  219. dest[17] = dest[12] = dest[7] = dest[2] = c;
  220. dest[18] = dest[13] = dest[8] = dest[3] = d;
  221. dest[19] = dest[14] = dest[9] = dest[4] = e;
  222. inc_ptr(dest, draster);
  223. }
  224. while (--h);
  225. break;
  226. case 3:
  227. do {
  228. dest[10] = dest[5] = dest[0] = a;
  229. dest[11] = dest[6] = dest[1] = b;
  230. dest[12] = dest[7] = dest[2] = c;
  231. dest[13] = dest[8] = dest[3] = d;
  232. dest[14] = dest[9] = dest[4] = e;
  233. inc_ptr(dest, draster);
  234. }
  235. while (--h);
  236. break;
  237. case 2:
  238. do {
  239. dest[5] = dest[0] = a;
  240. dest[6] = dest[1] = b;
  241. dest[7] = dest[2] = c;
  242. dest[8] = dest[3] = d;
  243. dest[9] = dest[4] = e;
  244. inc_ptr(dest, draster);
  245. }
  246. while (--h);
  247. break;
  248. case 1:
  249. do {
  250. dest[0] = a; dest[1] = b; dest[2] = c; dest[3] = d; dest[4] = e;
  251. inc_ptr(dest, draster);
  252. }
  253. while (--h);
  254. break;
  255. case 0:
  256. default:
  257. ;
  258. }
  259. }
  260. return 0;
  261. }
  262. /* Copy a monochrome bitmap. */
  263. private int
  264. mem_true40_copy_mono(gx_device * dev,
  265. const byte * base, int sourcex, int sraster, gx_bitmap_id id,
  266. int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
  267. {
  268. gx_device_memory * const mdev = (gx_device_memory *)dev;
  269. const byte *line;
  270. int sbit;
  271. int first_bit;
  272. declare_scan_ptr(dest);
  273. fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
  274. setup_rect(dest);
  275. line = base + (sourcex >> 3);
  276. sbit = sourcex & 7;
  277. first_bit = 0x80 >> sbit;
  278. if (zero != gx_no_color_index) { /* Loop for halftones or inverted masks */
  279. /* (never used). */
  280. declare_unpack_color(a0, b0, c0, d0, e0, zero);
  281. declare_unpack_color(a1, b1, c1, d1, e1, one);
  282. while (h-- > 0) {
  283. register byte *pptr = dest;
  284. const byte *sptr = line;
  285. register int sbyte = *sptr++;
  286. register int bit = first_bit;
  287. int count = w;
  288. do {
  289. if (sbyte & bit) {
  290. if (one != gx_no_color_index)
  291. put5(pptr, a1, b1, c1, d1, e1);
  292. } else
  293. put5(pptr, a0, b0, c0, d0, e0);
  294. pptr += PIXEL_SIZE;
  295. if ((bit >>= 1) == 0)
  296. bit = 0x80, sbyte = *sptr++;
  297. }
  298. while (--count > 0);
  299. line += sraster;
  300. inc_ptr(dest, draster);
  301. }
  302. } else if (one != gx_no_color_index) { /* Loop for character and pattern masks. */
  303. /* This is used heavily. */
  304. declare_unpack_color(a1, b1, c1, d1, e1, one);
  305. int first_mask = first_bit << 1;
  306. int first_count, first_skip;
  307. if (sbit + w > 8)
  308. first_mask -= 1,
  309. first_count = 8 - sbit;
  310. else
  311. first_mask -= first_mask >> w,
  312. first_count = w;
  313. first_skip = first_count * PIXEL_SIZE;
  314. while (h-- > 0) {
  315. register byte *pptr = dest;
  316. const byte *sptr = line;
  317. register int sbyte = *sptr++ & first_mask;
  318. int count = w - first_count;
  319. if (sbyte) {
  320. register int bit = first_bit;
  321. do {
  322. if (sbyte & bit)
  323. put5(pptr, a1, b1, c1, d1, e1);
  324. pptr += PIXEL_SIZE;
  325. }
  326. while ((bit >>= 1) & first_mask);
  327. } else
  328. pptr += first_skip;
  329. while (count >= 8) {
  330. sbyte = *sptr++;
  331. if (sbyte & 0xf0) {
  332. if (sbyte & 0x80)
  333. put5(pptr, a1, b1, c1, d1, e1);
  334. if (sbyte & 0x40)
  335. put5(pptr + 5, a1, b1, c1, d1, e1);
  336. if (sbyte & 0x20)
  337. put5(pptr + 10, a1, b1, c1, d1, e1);
  338. if (sbyte & 0x10)
  339. put5(pptr + 15, a1, b1, c1, d1, e1);
  340. }
  341. if (sbyte & 0xf) {
  342. if (sbyte & 8)
  343. put5(pptr + 20, a1, b1, c1, d1, e1);
  344. if (sbyte & 4)
  345. put5(pptr + 25, a1, b1, c1, d1, e1);
  346. if (sbyte & 2)
  347. put5(pptr + 30, a1, b1, c1, d1, e1);
  348. if (sbyte & 1)
  349. put5(pptr + 35, a1, b1, c1, d1, e1);
  350. }
  351. pptr += 8 * PIXEL_SIZE;
  352. count -= 8;
  353. }
  354. if (count > 0) {
  355. register int bit = 0x80;
  356. sbyte = *sptr++;
  357. do {
  358. if (sbyte & bit)
  359. put5(pptr, a1, b1, c1, d1, e1);
  360. pptr += PIXEL_SIZE;
  361. bit >>= 1;
  362. }
  363. while (--count > 0);
  364. }
  365. line += sraster;
  366. inc_ptr(dest, draster);
  367. }
  368. }
  369. return 0;
  370. }
  371. /* Copy a color bitmap. */
  372. private int
  373. mem_true40_copy_color(gx_device * dev,
  374. const byte * base, int sourcex, int sraster, gx_bitmap_id id,
  375. int x, int y, int w, int h)
  376. {
  377. gx_device_memory * const mdev = (gx_device_memory *)dev;
  378. fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
  379. mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
  380. return 0;
  381. }
  382. /* ================ "Word"-oriented device ================ */
  383. /* Note that on a big-endian machine, this is the same as the */
  384. /* standard byte-oriented-device. */
  385. #if !arch_is_big_endian
  386. /* Procedures */
  387. declare_mem_procs(mem40_word_copy_mono, mem40_word_copy_color, mem40_word_fill_rectangle);
  388. /* Here is the device descriptor. */
  389. const gx_device_memory mem_true40_word_device =
  390. mem_full_device("image40w", 40, 0, mem_open,
  391. gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb,
  392. mem40_word_copy_mono, mem40_word_copy_color, mem40_word_fill_rectangle,
  393. gx_default_map_cmyk_color, gx_default_strip_tile_rectangle,
  394. gx_no_strip_copy_rop, mem_word_get_bits_rectangle);
  395. /* Fill a rectangle with a color. */
  396. private int
  397. mem40_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
  398. gx_color_index color)
  399. {
  400. gx_device_memory * const mdev = (gx_device_memory *)dev;
  401. byte *base;
  402. uint raster;
  403. fit_fill(dev, x, y, w, h);
  404. base = scan_line_base(mdev, y);
  405. raster = mdev->raster;
  406. mem_swap_byte_rect(base, raster, x * 40, w * 40, h, true);
  407. mem_true40_fill_rectangle(dev, x, y, w, h, color);
  408. mem_swap_byte_rect(base, raster, x * 40, w * 40, h, false);
  409. return 0;
  410. }
  411. /* Copy a bitmap. */
  412. private int
  413. mem40_word_copy_mono(gx_device * dev,
  414. const byte * base, int sourcex, int sraster, gx_bitmap_id id,
  415. int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
  416. {
  417. gx_device_memory * const mdev = (gx_device_memory *)dev;
  418. byte *row;
  419. uint raster;
  420. bool store;
  421. fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
  422. row = scan_line_base(mdev, y);
  423. raster = mdev->raster;
  424. store = (zero != gx_no_color_index && one != gx_no_color_index);
  425. mem_swap_byte_rect(row, raster, x * 40, w * 40, h, store);
  426. mem_true40_copy_mono(dev, base, sourcex, sraster, id,
  427. x, y, w, h, zero, one);
  428. mem_swap_byte_rect(row, raster, x * 40, w * 40, h, false);
  429. return 0;
  430. }
  431. /* Copy a color bitmap. */
  432. private int
  433. mem40_word_copy_color(gx_device * dev,
  434. const byte * base, int sourcex, int sraster, gx_bitmap_id id,
  435. int x, int y, int w, int h)
  436. {
  437. gx_device_memory * const mdev = (gx_device_memory *)dev;
  438. byte *row;
  439. uint raster;
  440. fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
  441. row = scan_line_base(mdev, y);
  442. raster = mdev->raster;
  443. mem_swap_byte_rect(row, raster, x * 40, w * 40, h, true);
  444. bytes_copy_rectangle(row + x * PIXEL_SIZE, raster, base + sourcex * PIXEL_SIZE,
  445. sraster, w * PIXEL_SIZE, h);
  446. mem_swap_byte_rect(row, raster, x * 40, w * 40, h, false);
  447. return 0;
  448. }
  449. #endif /* !arch_is_big_endian */