diff options
author | Robin Watts <robin.watts@artifex.com> | 2018-01-05 17:04:59 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2018-01-06 11:49:42 +0000 |
commit | 47d4d0779563983ab79362acbf3522758ce7a09c (patch) | |
tree | 2ae1f9b6f307acf44a36f2cea6821455f07624a7 /base/gximono.c | |
parent | d356025602f3f9f9a1e656bd14430cd95c059548 (diff) | |
download | ghostpdl-47d4d0779563983ab79362acbf3522758ce7a09c.tar.gz |
Optimise some image_render_mono cases.
Split a case within image_render_mono into separate portrait
and landscape cases. Use fill rectangle rather than fill_trap
to save time, and avoid halftoning where possible.
This saves us about 15% runtime in 1000pages.pcl.
Diffstat (limited to 'base/gximono.c')
-rw-r--r-- | base/gximono.c | 126 |
1 files changed, 106 insertions, 20 deletions
diff --git a/base/gximono.c b/base/gximono.c index be9d1cffd..77b5d42fc 100644 --- a/base/gximono.c +++ b/base/gximono.c @@ -522,45 +522,131 @@ image_render_mono(gx_image_enum * penum, const byte * buffer, int data_x, } - } else if (penum->posture == image_portrait || - penum->posture == image_landscape - ) { - + } else if (penum->posture == image_portrait) { /************************************** - * Slow case, not masked, orthogonal. * + * Slow case, not masked, portrait. * **************************************/ + dev_proc_fill_rectangle((*fill_proc)) = + dev_proc(dev, fill_rectangle); + int iy = fixed2int_pixround(yrun); + int ih = fixed2int_pixround(yrun + pdyy) - iy; + if (ih < 0) + iy += ih, ih = -ih; /* In this case, we can fill runs quickly. */ /****** DOESN'T DO ADJUSTMENT ******/ if (stop <= psrc) goto last; for (;;) { - if (*psrc != run) { - if (run != htrun) { - htrun = run; + byte c = *psrc++; + if (c != run) { + int ix = fixed2int_pixround(xrun); + int iw = fixed2int_pixround(xl) - ix; + if (iw < 0) + ix += iw, iw = -iw; + switch (run) + { + case 0: + if (!color_is_pure(penum->icolor0)) + goto ht_port; + code = (*fill_proc) (dev, ix, iy, iw, ih, + penum->icolor0->colors.pure); + break; + case 0xff: + if (!color_is_pure(penum->icolor1)) + goto ht_port; + code = (*fill_proc) (dev, ix, iy, iw, ih, + penum->icolor1->colors.pure); + break; + default: + ht_port: + if (run != htrun) { + htrun = run; #if USE_SET_GRAY_FUNCTION - code = image_set_gray(run,masked,mask_base,mask_limit,&pdevc, - &cc,pcs,pgs,dev,gs_color_select_source,penum); - if (code < 0) - goto err; + code = image_set_gray(run,masked,mask_base,mask_limit,&pdevc, + &cc,pcs,pgs,dev,gs_color_select_source,penum); + if (code < 0) + goto err; #else - IMAGE_SET_GRAY(run); + IMAGE_SET_GRAY(run); #endif + } + code = gx_fill_rectangle_device_rop(ix, iy, iw, ih, + pdevc, dev, lop); } - code = (*fill_pgram)(dev, xrun, yrun, xl - xrun, - ytf - yrun, pdyx, pdyy, - pdevc, lop); if (code < 0) goto err; - yrun = ytf; xrun = xl; rsrc = psrc; - if (psrc >= stop) + if (psrc > stop) break; - run = *psrc; + run = c; } - psrc++; dda_next(next.x); + if (psrc >= endp) + break; + } + } else if (penum->posture == image_landscape) { + + /************************************** + * Slow case, not masked, landscape. * + **************************************/ + dev_proc_fill_rectangle((*fill_proc)) = + dev_proc(dev, fill_rectangle); + int ix = fixed2int_pixround(xrun); + int iw = fixed2int_pixround(xrun + pdyx) - ix; + if (iw < 0) + ix += iw, iw = -iw; + + /* In this case, we can fill runs quickly. */ + /****** DOESN'T DO ADJUSTMENT ******/ + if (stop <= psrc) + goto last; + for (;;) { + byte c = *psrc++; + if (c != run) { + int iy = fixed2int_pixround(yrun); + int ih = fixed2int_pixround(ytf) - iy; + if (ih < 0) + iy += ih, ih = -ih; + switch (run) + { + case 0: + if (!color_is_pure(penum->icolor0)) + goto ht_land; + code = (*fill_proc) (dev, ix, iy, iw, ih, + penum->icolor0->colors.pure); + break; + case 0xff: + if (!color_is_pure(penum->icolor1)) + goto ht_land; + code = (*fill_proc) (dev, ix, iy, iw, ih, + penum->icolor1->colors.pure); + break; + default: + ht_land: + if (run != htrun) { + htrun = run; +#if USE_SET_GRAY_FUNCTION + code = image_set_gray(run,masked,mask_base,mask_limit,&pdevc, + &cc,pcs,pgs,dev,gs_color_select_source,penum); + if (code < 0) + goto err; +#else + IMAGE_SET_GRAY(run); +#endif + } + code = gx_fill_rectangle_device_rop(ix, iy, iw, ih, + pdevc, dev, lop); + } + if (code < 0) + goto err; + yrun = ytf; + rsrc = psrc; + if (psrc > stop) + break; + run = c; + } dda_next(next.y); if (psrc >= endp) break; |