changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/cmd/gs/src/gdevm64.c

changeset 7191: 753613b3b8c4
parent: eaccc3e8d226
author: cinap_lenrek@felloff.net
date: Fri, 03 May 2019 21:10:01 +0200
permissions: -rw-r--r--
description: gs: avoid stupid shifts by casting to uint64_t
1 /* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises, 2001 Artifex Software. All rights reserved.
2 
3  This software is provided AS-IS with no warranty, either express or
4  implied.
5 
6  This software is distributed under license and may not be copied,
7  modified or distributed except as expressly authorized under the terms
8  of the license contained in the file LICENSE in this distribution.
9 
10  For more information about licensing, please refer to
11  http://www.ghostscript.com/licensing/. For information on
12  commercial licensing, go to http://www.artifex.com/licensing/ or
13  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14  San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /*$Id: gdevm64.c,v 1.4 2005/06/20 08:59:23 igor Exp $ */
18 /* 64-bit-per-pixel "memory" (stored bitmap) device */
19 #include "memory_.h"
20 #include "gx.h"
21 #include "gxdevice.h"
22 #include "gxdevmem.h" /* semi-public definitions */
23 #include "gdevmem.h" /* private definitions */
24 
25 /* Define debugging statistics. */
26 #ifdef DEBUG
27 struct stats_mem64_s {
28  long
29  fill, fwide, fgray[101], fsetc, fcolor[101], fnarrow[5],
30  fprevc[257];
31  double ftotal;
32 } stats_mem64;
33 static int prev_count = 0;
34 static gx_color_index prev_colors[256];
35 # define INCR(v) (++(stats_mem64.v))
36 #else
37 # define INCR(v) DO_NOTHING
38 #endif
39 
40 
41 /* ================ Standard (byte-oriented) device ================ */
42 
43 #undef chunk
44 #define chunk byte
45 #define PIXEL_SIZE 2
46 
47 /* Procedures */
48 declare_mem_procs(mem_true64_copy_mono, mem_true64_copy_color, mem_true64_fill_rectangle);
49 
50 /* The device descriptor. */
51 const gx_device_memory mem_true64_device =
52 mem_full_alpha_device("image64", 64, 0, mem_open,
53  gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb,
54  mem_true64_copy_mono, mem_true64_copy_color, mem_true64_fill_rectangle,
55  gx_default_map_cmyk_color, gx_default_copy_alpha,
56  gx_default_strip_tile_rectangle, mem_default_strip_copy_rop,
57  mem_get_bits_rectangle);
58 
59 /* Convert x coordinate to byte offset in scan line. */
60 #undef x_to_byte
61 #define x_to_byte(x) ((x) << 3)
62 
63 /* Put a 64-bit color into the bitmap. */
64 #define put8(ptr, abcd, efgh)\
65  (ptr)[0] = abcd, (ptr)[1] = efgh
66 /* Free variables: [m]dev, abcd, degh. */
67 #if arch_is_big_endian
68 /* Unpack a color into 32 bit chunks. */
69 # define declare_unpack_color(abcd, efgh, color)\
70  bits32 abcd = (bits32)((uint64_t)(color) >> 32);\
71  bits32 efgh = (bits32)(color)
72 #else
73 /* Unpack a color into 32 bit chunks. */
74 # define declare_unpack_color(abcd, efgh, color)\
75  bits32 abcd = (bits32)((0x000000ff & ((uint64_t)(color) >> 56)) |\
76  (0x0000ff00 & ((uint64_t)(color) >> 40)) |\
77  (0x00ff0000 & ((color) >> 24)) |\
78  (0xff000000 & ((color) >> 8)));\
79  bits32 efgh = (bits32)((0x000000ff & ((color) >> 24)) |\
80  (0x0000ff00 & ((color) >> 8)) |\
81  (0x00ff0000 & ((color) << 8)) |\
82  (0xff000000 & ((color) << 24)))
83 #endif
84 #define dest32 ((bits32 *)dest)
85 
86 /* Fill a rectangle with a color. */
87 private int
88 mem_true64_fill_rectangle(gx_device * dev,
89  int x, int y, int w, int h, gx_color_index color)
90 {
91  gx_device_memory * const mdev = (gx_device_memory *)dev;
92  declare_scan_ptr(dest);
93  declare_unpack_color(abcd, efgh, color);
94 
95  /*
96  * In order to avoid testing w > 0 and h > 0 twice, we defer
97  * executing setup_rect, and use fit_fill_xywh instead of
98  * fit_fill.
99  */
100  fit_fill_xywh(dev, x, y, w, h);
101  INCR(fill);
102 #ifdef DEBUG
103  stats_mem64.ftotal += w;
104 #endif
105  if (h <= 0)
106  return 0;
107  if (w >= 5) {
108  INCR(fwide);
109  setup_rect(dest);
110 #ifdef DEBUG
111  {
112  int ci;
113  for (ci = 0; ci < prev_count; ++ci)
114  if (prev_colors[ci] == color)
115  break;
116  INCR(fprevc[ci]);
117  if (ci == prev_count) {
118  if (ci < countof(prev_colors))
119  ++prev_count;
120  else
121  --ci;
122  }
123  if (ci) {
124  memmove(&prev_colors[1], &prev_colors[0],
125  ci * sizeof(prev_colors[0]));
126  prev_colors[0] = color;
127  }
128  }
129 #endif
130  INCR(fcolor[min(w, 100)]);
131  while (h-- > 0) {
132  register bits32 *pptr = dest32;
133  int w1 = w;
134 
135  while (w1 >= 4) {
136  put8(pptr, abcd, efgh);
137  put8(pptr + 2, abcd, efgh);
138  put8(pptr + 4, abcd, efgh);
139  put8(pptr + 6, abcd, efgh);
140  pptr += 4 * PIXEL_SIZE;
141  w1 -= 4;
142  }
143  switch (w1) {
144  case 1:
145  put8(pptr, abcd, efgh);
146  break;
147  case 2:
148  put8(pptr, abcd, efgh);
149  put8(pptr + 2, abcd, efgh);
150  break;
151  case 3:
152  put8(pptr, abcd, efgh);
153  put8(pptr + 2, abcd, efgh);
154  put8(pptr + 4, abcd, efgh);
155  break;
156  case 0:
157  ;
158  }
159  inc_ptr(dest, draster);
160  }
161  } else { /* w < 5 */
162  INCR(fnarrow[max(w, 0)]);
163  setup_rect(dest);
164  switch (w) {
165  case 4:
166  do {
167  put8(dest32, abcd, efgh);
168  put8(dest32 + 2, abcd, efgh);
169  put8(dest32 + 4, abcd, efgh);
170  put8(dest32 + 6, abcd, efgh);
171  inc_ptr(dest, draster);
172  }
173  while (--h);
174  break;
175  case 3:
176  do {
177  put8(dest32, abcd, efgh);
178  put8(dest32 + 2, abcd, efgh);
179  put8(dest32 + 4, abcd, efgh);
180  inc_ptr(dest, draster);
181  }
182  while (--h);
183  break;
184  case 2:
185  do {
186  put8(dest32, abcd, efgh);
187  put8(dest32 + 2, abcd, efgh);
188  inc_ptr(dest, draster);
189  }
190  while (--h);
191  break;
192  case 1:
193  do {
194  put8(dest32, abcd, efgh);
195  inc_ptr(dest, draster);
196  }
197  while (--h);
198  break;
199  case 0:
200  default:
201  ;
202  }
203  }
204  return 0;
205 }
206 
207 /* Copy a monochrome bitmap. */
208 private int
209 mem_true64_copy_mono(gx_device * dev,
210  const byte * base, int sourcex, int sraster, gx_bitmap_id id,
211  int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
212 {
213  gx_device_memory * const mdev = (gx_device_memory *)dev;
214  const byte *line;
215  int sbit;
216  int first_bit;
217 
218  declare_scan_ptr(dest);
219 
220  fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
221  setup_rect(dest);
222  line = base + (sourcex >> 3);
223  sbit = sourcex & 7;
224  first_bit = 0x80 >> sbit;
225  if (zero != gx_no_color_index) { /* Loop for halftones or inverted masks */
226  /* (never used). */
227  declare_unpack_color(abcd0, efgh0, zero);
228  declare_unpack_color(abcd1, efgh1, one);
229  while (h-- > 0) {
230  register bits32 *pptr = dest32;
231  const byte *sptr = line;
232  register int sbyte = *sptr++;
233  register int bit = first_bit;
234  int count = w;
235 
236  do {
237  if (sbyte & bit) {
238  if (one != gx_no_color_index)
239  put8(pptr, abcd1, efgh1);
240  } else
241  put8(pptr, abcd0, efgh0);
242  pptr += PIXEL_SIZE;
243  if ((bit >>= 1) == 0)
244  bit = 0x80, sbyte = *sptr++;
245  }
246  while (--count > 0);
247  line += sraster;
248  inc_ptr(dest, draster);
249  }
250  } else if (one != gx_no_color_index) { /* Loop for character and pattern masks. */
251  /* This is used heavily. */
252  declare_unpack_color(abcd1, efgh1, one);
253  int first_mask = first_bit << 1;
254  int first_count, first_skip;
255 
256  if (sbit + w > 8)
257  first_mask -= 1,
258  first_count = 8 - sbit;
259  else
260  first_mask -= first_mask >> w,
261  first_count = w;
262  first_skip = first_count * PIXEL_SIZE;
263  while (h-- > 0) {
264  register bits32 *pptr = dest32;
265  const byte *sptr = line;
266  register int sbyte = *sptr++ & first_mask;
267  int count = w - first_count;
268 
269  if (sbyte) {
270  register int bit = first_bit;
271 
272  do {
273  if (sbyte & bit)
274  put8(pptr, abcd1, efgh1);
275  pptr += PIXEL_SIZE;
276  }
277  while ((bit >>= 1) & first_mask);
278  } else
279  pptr += first_skip;
280  while (count >= 8) {
281  sbyte = *sptr++;
282  if (sbyte & 0xf0) {
283  if (sbyte & 0x80)
284  put8(pptr, abcd1, efgh1);
285  if (sbyte & 0x40)
286  put8(pptr + 2, abcd1, efgh1);
287  if (sbyte & 0x20)
288  put8(pptr + 4, abcd1, efgh1);
289  if (sbyte & 0x10)
290  put8(pptr + 6, abcd1, efgh1);
291  }
292  if (sbyte & 0xf) {
293  if (sbyte & 8)
294  put8(pptr + 8, abcd1, efgh1);
295  if (sbyte & 4)
296  put8(pptr + 10, abcd1, efgh1);
297  if (sbyte & 2)
298  put8(pptr + 12, abcd1, efgh1);
299  if (sbyte & 1)
300  put8(pptr + 14, abcd1, efgh1);
301  }
302  pptr += 8 * PIXEL_SIZE;
303  count -= 8;
304  }
305  if (count > 0) {
306  register int bit = 0x80;
307 
308  sbyte = *sptr++;
309  do {
310  if (sbyte & bit)
311  put8(pptr, abcd1, efgh1);
312  pptr += PIXEL_SIZE;
313  bit >>= 1;
314  }
315  while (--count > 0);
316  }
317  line += sraster;
318  inc_ptr(dest, draster);
319  }
320  }
321  return 0;
322 }
323 
324 /* Copy a color bitmap. */
325 private int
326 mem_true64_copy_color(gx_device * dev,
327  const byte * base, int sourcex, int sraster, gx_bitmap_id id,
328  int x, int y, int w, int h)
329 {
330  gx_device_memory * const mdev = (gx_device_memory *)dev;
331 
332  fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
333  mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
334  return 0;
335 }
336 
337 /* ================ "Word"-oriented device ================ */
338 
339 /* Note that on a big-endian machine, this is the same as the */
340 /* standard byte-oriented-device. */
341 
342 #if !arch_is_big_endian
343 
344 /* Procedures */
345 declare_mem_procs(mem64_word_copy_mono, mem64_word_copy_color, mem64_word_fill_rectangle);
346 
347 /* Here is the device descriptor. */
348 const gx_device_memory mem_true64_word_device =
349 mem_full_device("image64w", 64, 0, mem_open,
350  gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb,
351  mem64_word_copy_mono, mem64_word_copy_color, mem64_word_fill_rectangle,
352  gx_default_map_cmyk_color, gx_default_strip_tile_rectangle,
353  gx_no_strip_copy_rop, mem_word_get_bits_rectangle);
354 
355 /* Fill a rectangle with a color. */
356 private int
357 mem64_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
358  gx_color_index color)
359 {
360  gx_device_memory * const mdev = (gx_device_memory *)dev;
361  byte *base;
362  uint raster;
363 
364  fit_fill(dev, x, y, w, h);
365  base = scan_line_base(mdev, y);
366  raster = mdev->raster;
367  mem_swap_byte_rect(base, raster, x * 64, w * 64, h, true);
368  mem_true64_fill_rectangle(dev, x, y, w, h, color);
369  mem_swap_byte_rect(base, raster, x * 64, w * 64, h, false);
370  return 0;
371 }
372 
373 /* Copy a bitmap. */
374 private int
375 mem64_word_copy_mono(gx_device * dev,
376  const byte * base, int sourcex, int sraster, gx_bitmap_id id,
377  int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
378 {
379  gx_device_memory * const mdev = (gx_device_memory *)dev;
380  byte *row;
381  uint raster;
382  bool store;
383 
384  fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
385  row = scan_line_base(mdev, y);
386  raster = mdev->raster;
387  store = (zero != gx_no_color_index && one != gx_no_color_index);
388  mem_swap_byte_rect(row, raster, x * 64, w * 64, h, store);
389  mem_true64_copy_mono(dev, base, sourcex, sraster, id,
390  x, y, w, h, zero, one);
391  mem_swap_byte_rect(row, raster, x * 64, w * 64, h, false);
392  return 0;
393 }
394 
395 /* Copy a color bitmap. */
396 private int
397 mem64_word_copy_color(gx_device * dev,
398  const byte * base, int sourcex, int sraster, gx_bitmap_id id,
399  int x, int y, int w, int h)
400 {
401  gx_device_memory * const mdev = (gx_device_memory *)dev;
402  byte *row;
403  uint raster;
404 
405  fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
406  row = scan_line_base(mdev, y);
407  raster = mdev->raster;
408  mem_swap_byte_rect(row, raster, x * 64, w * 64, h, true);
409  bytes_copy_rectangle(row + x * PIXEL_SIZE, raster, base + sourcex * PIXEL_SIZE,
410  sraster, w * PIXEL_SIZE, h);
411  mem_swap_byte_rect(row, raster, x * 64, w * 64, h, false);
412  return 0;
413 }
414 
415 #endif /* !arch_is_big_endian */