gxidata.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /* Copyright (C) 1995, 2000 Aladdin Enterprises. All rights reserved.
  2. This file is part of AFPL Ghostscript.
  3. AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
  4. distributor accepts any responsibility for the consequences of using it, or
  5. for whether it serves any particular purpose or works at all, unless he or
  6. she says so in writing. Refer to the Aladdin Free Public License (the
  7. "License") for full details.
  8. Every copy of AFPL Ghostscript must include a copy of the License, normally
  9. in a plain ASCII text file named PUBLIC. The License grants you the right
  10. to copy, modify and redistribute AFPL Ghostscript, but only under certain
  11. conditions described in the License. Among other things, the License
  12. requires that the copyright notice and this notice be preserved on all
  13. copies.
  14. */
  15. /*$Id: gxidata.c,v 1.4 2000/09/19 19:00:37 lpd Exp $ */
  16. /* Generic image enumeration and cleanup */
  17. #include "gx.h"
  18. #include "memory_.h"
  19. #include "gserrors.h"
  20. #include "gxdevice.h"
  21. #include "gxcpath.h"
  22. #include "gximage.h"
  23. /* Forward declarations */
  24. private void update_strip(P1(gx_image_enum *penum));
  25. private void repack_bit_planes(P7(const gx_image_plane_t *src_planes,
  26. const ulong *offsets, int num_planes,
  27. byte *buffer, int width,
  28. const sample_lookup_t * ptab, int spread));
  29. private gx_device *setup_image_device(P1(const gx_image_enum *penum));
  30. /* Process the next piece of an ImageType 1 image. */
  31. int
  32. gx_image1_plane_data(gx_image_enum_common_t * info,
  33. const gx_image_plane_t * planes, int height,
  34. int *rows_used)
  35. {
  36. gx_image_enum *penum = (gx_image_enum *) info;
  37. gx_device *dev;
  38. const int y = penum->y;
  39. int y_end = min(y + height, penum->rect.h);
  40. int width_spp = penum->rect.w * penum->spp;
  41. int num_planes = penum->num_planes;
  42. #define BCOUNT(plane) /* bytes per data row */\
  43. (((penum->rect.w + (plane).data_x) * penum->spp * penum->bps / num_planes\
  44. + 7) >> 3)
  45. fixed adjust = penum->adjust;
  46. ulong offsets[gs_image_max_planes];
  47. int ignore_data_x;
  48. bool bit_planar = penum->num_planes > penum->spp;
  49. int code;
  50. if (height == 0) {
  51. *rows_used = 0;
  52. return 0;
  53. }
  54. dev = setup_image_device(penum);
  55. /* Now render complete rows. */
  56. if (penum->used.y) {
  57. /*
  58. * Processing was interrupted by an error. Skip over rows
  59. * already processed.
  60. */
  61. int px;
  62. for (px = 0; px < num_planes; ++px)
  63. offsets[px] = planes[px].raster * penum->used.y;
  64. penum->used.y = 0;
  65. } else
  66. memset(offsets, 0, num_planes * sizeof(offsets[0]));
  67. for (; penum->y < y_end; penum->y++) {
  68. int px;
  69. const byte *buffer;
  70. int sourcex;
  71. int x_used = penum->used.x;
  72. if (bit_planar) {
  73. /* Repack the bit planes into byte-wide samples. */
  74. buffer = penum->buffer;
  75. sourcex = 0;
  76. for (px = 0; px < num_planes; px += penum->bps)
  77. repack_bit_planes(planes, offsets, penum->bps, penum->buffer,
  78. penum->rect.w, &penum->map[0].table,
  79. penum->spread);
  80. for (px = 0; px < num_planes; ++px)
  81. offsets[px] += planes[px].raster;
  82. } else {
  83. /*
  84. * Normally, we unpack the data into the buffer, but if
  85. * there is only one plane and we don't need to expand the
  86. * input samples, we may use the data directly.
  87. */
  88. sourcex = planes[0].data_x;
  89. buffer =
  90. (*penum->unpack)(penum->buffer, &sourcex,
  91. planes[0].data + offsets[0],
  92. planes[0].data_x, BCOUNT(planes[0]),
  93. &penum->map[0].table, penum->spread);
  94. offsets[0] += planes[0].raster;
  95. for (px = 1; px < num_planes; ++px) {
  96. (*penum->unpack)(penum->buffer + (px << penum->log2_xbytes),
  97. &ignore_data_x,
  98. planes[px].data + offsets[px],
  99. planes[px].data_x, BCOUNT(planes[px]),
  100. &penum->map[px].table, penum->spread);
  101. offsets[px] += planes[px].raster;
  102. }
  103. }
  104. #ifdef DEBUG
  105. if (gs_debug_c('b'))
  106. dprintf1("[b]image1 y=%d\n", y);
  107. if (gs_debug_c('B')) {
  108. int i, n = width_spp;
  109. if (penum->bps > 8)
  110. n *= 2;
  111. else if (penum->bps == 1 && penum->unpack_bps == 8)
  112. n = (n + 7) / 8;
  113. dlputs("[B]row:");
  114. for (i = 0; i < n; i++)
  115. dprintf1(" %02x", buffer[i]);
  116. dputs("\n");
  117. }
  118. #endif
  119. penum->cur.x = dda_current(penum->dda.row.x);
  120. dda_next(penum->dda.row.x);
  121. penum->cur.y = dda_current(penum->dda.row.y);
  122. dda_next(penum->dda.row.y);
  123. if (!penum->interpolate)
  124. switch (penum->posture) {
  125. case image_portrait:
  126. { /* Precompute integer y and height, */
  127. /* and check for clipping. */
  128. fixed yc = penum->cur.y,
  129. yn = dda_current(penum->dda.row.y);
  130. if (yn < yc) {
  131. fixed temp = yn;
  132. yn = yc;
  133. yc = temp;
  134. }
  135. yc -= adjust;
  136. if (yc >= penum->clip_outer.q.y)
  137. goto mt;
  138. yn += adjust;
  139. if (yn <= penum->clip_outer.p.y)
  140. goto mt;
  141. penum->yci = fixed2int_pixround(yc);
  142. penum->hci = fixed2int_pixround(yn) - penum->yci;
  143. if (penum->hci == 0)
  144. goto mt;
  145. if_debug2('b', "[b]yci=%d, hci=%d\n",
  146. penum->yci, penum->hci);
  147. }
  148. break;
  149. case image_landscape:
  150. { /* Check for no pixel centers in x. */
  151. fixed xc = penum->cur.x,
  152. xn = dda_current(penum->dda.row.x);
  153. if (xn < xc) {
  154. fixed temp = xn;
  155. xn = xc;
  156. xc = temp;
  157. }
  158. xc -= adjust;
  159. if (xc >= penum->clip_outer.q.x)
  160. goto mt;
  161. xn += adjust;
  162. if (xn <= penum->clip_outer.p.x)
  163. goto mt;
  164. penum->xci = fixed2int_pixround(xc);
  165. penum->wci = fixed2int_pixround(xn) - penum->xci;
  166. if (penum->wci == 0)
  167. goto mt;
  168. if_debug2('b', "[b]xci=%d, wci=%d\n",
  169. penum->xci, penum->wci);
  170. }
  171. break;
  172. case image_skewed:
  173. ;
  174. }
  175. update_strip(penum);
  176. if (x_used) {
  177. /*
  178. * Processing was interrupted by an error. Skip over pixels
  179. * already processed.
  180. */
  181. dda_advance(penum->dda.pixel0.x, x_used);
  182. dda_advance(penum->dda.pixel0.y, x_used);
  183. penum->used.x = 0;
  184. }
  185. if_debug2('b', "[b]pixel0 x=%g, y=%g\n",
  186. fixed2float(dda_current(penum->dda.pixel0.x)),
  187. fixed2float(dda_current(penum->dda.pixel0.y)));
  188. code = (*penum->render)(penum, buffer, sourcex + x_used,
  189. width_spp - x_used * penum->spp, 1, dev);
  190. if (code < 0) {
  191. /* Error or interrupt, restore original state. */
  192. penum->used.x += x_used;
  193. if (!penum->used.y) {
  194. dda_previous(penum->dda.row.x);
  195. dda_previous(penum->dda.row.y);
  196. dda_translate(penum->dda.strip.x,
  197. penum->prev.x - penum->cur.x);
  198. dda_translate(penum->dda.strip.y,
  199. penum->prev.y - penum->cur.y);
  200. }
  201. goto out;
  202. }
  203. penum->prev = penum->cur;
  204. mt:;
  205. }
  206. if (penum->y < penum->rect.h) {
  207. code = 0;
  208. } else {
  209. /* End of input data. Render any left-over buffered data. */
  210. code = gx_image1_flush(info);
  211. if (code >= 0)
  212. code = 1;
  213. }
  214. out:
  215. /* Note that caller must call end_image */
  216. /* for both error and normal termination. */
  217. *rows_used = penum->y - y;
  218. return code;
  219. }
  220. /* Flush any buffered data. */
  221. int
  222. gx_image1_flush(gx_image_enum_common_t * info)
  223. {
  224. gx_image_enum *penum = (gx_image_enum *)info;
  225. int width_spp = penum->rect.w * penum->spp;
  226. fixed adjust = penum->adjust;
  227. penum->cur.x = dda_current(penum->dda.row.x);
  228. penum->cur.y = dda_current(penum->dda.row.y);
  229. switch (penum->posture) {
  230. case image_portrait:
  231. {
  232. fixed yc = penum->cur.y;
  233. penum->yci = fixed2int_rounded(yc - adjust);
  234. penum->hci = fixed2int_rounded(yc + adjust) - penum->yci;
  235. }
  236. break;
  237. case image_landscape:
  238. {
  239. fixed xc = penum->cur.x;
  240. penum->xci = fixed2int_rounded(xc - adjust);
  241. penum->wci = fixed2int_rounded(xc + adjust) - penum->xci;
  242. }
  243. break;
  244. case image_skewed: /* pacify compilers */
  245. ;
  246. }
  247. update_strip(penum);
  248. penum->prev = penum->cur;
  249. return (*penum->render)(penum, NULL, 0, width_spp, 0,
  250. setup_image_device(penum));
  251. }
  252. /* Update the strip DDA when moving to a new row. */
  253. private void
  254. update_strip(gx_image_enum *penum)
  255. {
  256. dda_translate(penum->dda.strip.x, penum->cur.x - penum->prev.x);
  257. dda_translate(penum->dda.strip.y, penum->cur.y - penum->prev.y);
  258. penum->dda.pixel0 = penum->dda.strip;
  259. }
  260. /*
  261. * Repack 1 to 8 individual bit planes into 8-bit samples.
  262. * buffer is aligned, and includes padding to an 8-byte boundary.
  263. * This procedure repacks one row, so the only relevant members of
  264. * src_planes are data and data_x (not raster).
  265. */
  266. private void
  267. repack_bit_planes(const gx_image_plane_t *src_planes, const ulong *offsets,
  268. int num_planes, byte *buffer, int width,
  269. const sample_lookup_t * ptab, int spread)
  270. {
  271. gx_image_plane_t planes[8];
  272. byte *zeros = 0;
  273. byte *dest = buffer;
  274. int any_data_x = 0;
  275. bool direct = (spread == 1 && ptab->lookup8[0] == 0 &&
  276. ptab->lookup8[255] == 255);
  277. int pi, x;
  278. gx_image_plane_t *pp;
  279. /*
  280. * Set up the row pointers, taking data_x and null planes into account.
  281. * If there are any null rows, we need to create a block of zeros in
  282. * order to avoid tests in the loop.
  283. */
  284. for (pi = 0, pp = planes; pi < num_planes; ++pi, ++pp)
  285. if (src_planes[pi].data == 0) {
  286. if (!zeros) {
  287. zeros = buffer + width - ((width + 7) >> 3);
  288. }
  289. pp->data = zeros;
  290. pp->data_x = 0;
  291. } else {
  292. int dx = src_planes[pi].data_x;
  293. pp->data = src_planes[pi].data + (dx >> 3) + offsets[pi];
  294. any_data_x |= (pp->data_x = dx & 7);
  295. }
  296. if (zeros)
  297. memset(zeros, 0, buffer + width - zeros);
  298. /*
  299. * Now process the data, in blocks of one input byte column
  300. * (8 output bytes).
  301. */
  302. for (x = 0; x < width; x += 8) {
  303. bits32 w0 = 0, w1 = 0;
  304. #if arch_is_big_endian
  305. static const bits32 expand[16] = {
  306. 0x00000000, 0x00000001, 0x00000100, 0x00000101,
  307. 0x00010000, 0x00010001, 0x00010100, 0x00010101,
  308. 0x01000000, 0x01000001, 0x01000100, 0x01000101,
  309. 0x01010000, 0x01010001, 0x01010100, 0x01010101
  310. };
  311. #else
  312. static const bits32 expand[16] = {
  313. 0x00000000, 0x01000000, 0x00010000, 0x01010000,
  314. 0x00000100, 0x01000100, 0x00010100, 0x01010100,
  315. 0x00000001, 0x01000001, 0x00010001, 0x01010001,
  316. 0x00000101, 0x01000101, 0x00010101, 0x01010101
  317. };
  318. #endif
  319. if (any_data_x) {
  320. for (pi = 0, pp = planes; pi < num_planes; ++pi, ++pp) {
  321. uint b = *(pp->data++);
  322. int dx = pp->data_x;
  323. if (dx) {
  324. b <<= dx;
  325. if (x + 8 - dx < width)
  326. b += *pp->data >> (8 - dx);
  327. }
  328. w0 = (w0 << 1) | expand[b >> 4];
  329. w1 = (w1 << 1) | expand[b & 0xf];
  330. }
  331. } else {
  332. for (pi = 0, pp = planes; pi < num_planes; ++pi, ++pp) {
  333. uint b = *(pp->data++);
  334. w0 = (w0 << 1) | expand[b >> 4];
  335. w1 = (w1 << 1) | expand[b & 0xf];
  336. }
  337. }
  338. /*
  339. * We optimize spread == 1 and identity ptab together, although
  340. * we could subdivide these 2 cases into 4 if we wanted.
  341. */
  342. if (direct) {
  343. ((bits32 *)dest)[0] = w0;
  344. ((bits32 *)dest)[1] = w1;
  345. dest += 8;
  346. } else {
  347. #define MAP_BYTE(v) (ptab->lookup8[(byte)(v)])
  348. dest[0] = MAP_BYTE(w0 >> 24); dest += spread;
  349. dest[1] = MAP_BYTE(w0 >> 16); dest += spread;
  350. dest[2] = MAP_BYTE(w0 >> 8); dest += spread;
  351. dest[3] = MAP_BYTE(w0); dest += spread;
  352. dest[4] = MAP_BYTE(w1 >> 24); dest += spread;
  353. dest[5] = MAP_BYTE(w1 >> 16); dest += spread;
  354. dest[6] = MAP_BYTE(w1 >> 8); dest += spread;
  355. dest[7] = MAP_BYTE(w1); dest += spread;
  356. #undef MAP_BYTE
  357. }
  358. }
  359. }
  360. /* Set up the device for drawing an image. */
  361. private gx_device *
  362. setup_image_device(const gx_image_enum *penum)
  363. {
  364. gx_device *dev = penum->dev;
  365. if (penum->clip_dev) {
  366. gx_device_clip *cdev = penum->clip_dev;
  367. gx_device_set_target((gx_device_forward *)cdev, dev);
  368. dev = (gx_device *) cdev;
  369. }
  370. if (penum->rop_dev) {
  371. gx_device_rop_texture *rtdev = penum->rop_dev;
  372. gx_device_set_target((gx_device_forward *)rtdev, dev);
  373. dev = (gx_device *) rtdev;
  374. }
  375. return dev;
  376. }
  377. /* Clean up by releasing the buffers. */
  378. /* Currently we ignore draw_last. */
  379. int
  380. gx_image1_end_image(gx_image_enum_common_t * info, bool draw_last)
  381. {
  382. gx_image_enum *penum = (gx_image_enum *) info;
  383. gs_memory_t *mem = penum->memory;
  384. stream_image_scale_state *scaler = penum->scaler;
  385. if_debug2('b', "[b]%send_image, y=%d\n",
  386. (penum->y < penum->rect.h ? "premature " : ""), penum->y);
  387. if (draw_last) {
  388. int code = gx_image_flush(info);
  389. if (code < 0)
  390. return code;
  391. }
  392. gs_free_object(mem, penum->rop_dev, "image RasterOp");
  393. gs_free_object(mem, penum->clip_dev, "image clipper");
  394. if (scaler != 0) {
  395. (*scaler->template->release) ((stream_state *) scaler);
  396. gs_free_object(mem, scaler, "image scaler state");
  397. }
  398. gs_free_object(mem, penum->line, "image line");
  399. gs_free_object(mem, penum->buffer, "image buffer");
  400. gs_free_object(mem, penum, "gx_default_end_image");
  401. return 0;
  402. }