[gs-cvs] rev 8517 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Mon Feb 4 14:18:09 PST 2008
Author: leonardo
Date: 2008-02-04 14:18:08 -0800 (Mon, 04 Feb 2008)
New Revision: 8517
Modified:
trunk/gs/src/gdevddrw.c
trunk/gs/src/gdevm24.c
trunk/gs/src/gxclread.c
trunk/gs/src/gxi12bit.c
trunk/gs/src/gxidata.c
trunk/gs/src/gxipixel.c
trunk/gs/src/lib.mak
Log:
Fix (images) : Improve coordinate precision when scaling an image.
DETAILS :
Ghostscript Bug 687345 "Image interpolation problem at a band boundary"
This is a partial fix for the bug 687345 for images with Interpolate=false.
Actually it is related to scaling raher than interpolation.
1. gx_image_enum_begin performed inaccurate coordinate computations,
which caused a different image bias for different bands
due to a wrong coordinate rounding.
The patch replaces it with a better code,
which provides same bias for all bands and for unbanded rendering.
But we're not sure that image placement is now perfect,
because the initial rounding looks strange.
We keep the initial rounding to be compatible with the old code
to minimize raster differences and easier visual analyzis.
For a while we keep the old code in #if 0 because
it may be useful for next patch.
2. image_render_frac contains optimized branches for the case when
image's axes are parallel to page's axes.
Those optimized branches convert parallelograms into rectangles,
except for the last parallelogramm in the chunk.
It caused the last parallelogram to shift in 1 pixel relatively
to the rectangles. This patch adds the optimized branch
for the last parallelogram, so that all image parts
are now placed with same rounding. It avoids rendering artifacts
with 148-05.ps and many other tests. Note that the patch does not fix
the rectangle shift from parallelograms,
so probably it still contain another bug,
which may need a separate fix.
3. While working on this patch we noted that update_strip
doesn't correctly preserve the fractional part for
dda.strip and dda.pixel . We include a track of that experiment
in the new code in #if 0 section for further development.
See comment in code.
4. Inserted visual trace commands for easier debugging.
EXPECTED DIFFERENCES :
This patch avoids difference between banded (MaxBitmap=100000)
and unbanded (MaxBitmap=100000000) rendering at 300 dpi for the following files :
035-01.ps
148-11.ps
148-16.ps
1_2001.pdf
455690.pdf
adesso4.pdf
Altona-Testsuite_p2_S_x3.pdf
Altona_Visual_bb_1v1_x3.pdf
Altona_Visual_sb_1v1_x3.pdf
bc_02a01_cal.pdf
BEST8-99-Path.fh7.pdf
Bug687724.pdf
Bug687832.pdf
Bug688308.ps
Bug688822.eps
dave.pdf
eric.pdf
file2.pdf
foo.pdf
H00216q.pdf
map.pdf
messenger.pdf
messenger16.pdf
ngnews1.pdf
Original.pdf
PixelisAd.pdf
ridt91.eps
S2_Digitalproof-Forum_x3k.pdf
SmoothShading.pdf
t1.pdf
time1.pdf
Also it causes minor differences for the following files :
"119-47.ps"
"468-01.ps"
"688645.jbig2.pdf"
"a.pdf"
"acrobat.pdf"
"ai2.pdf"
"Altona.Page_3.2002-09-27.pdf"
"Altona_Technical_1v1_x3.pdf"
"Bug687207.ps"
"Bug687840.pdf"
"Bug687889.pdf"
"Bug688308.ps"
"Bug688467.ps"
"Bug688639.ps"
"Bug689189.pdf"
"Bug689492.pdf"
"C-12-2706-0239-9-001.pdf"
"chstudy.pdf"
"D-12-2025-9478-9.pdf"
"dina4_tiffg4.pdf"
"Es001-01.pdf"
"jpx-file2.pdf"
"jpx-file3.pdf"
"jpx-flowcontrols.pdf"
"jpx-johnny1.pdf"
"little.guy.pdf"
"new_rect_nr.pdf"
"Openhuis_pdf_zw.pdf"
"sports.pdf"
"Svd.pdf"
"test.pdf"
Please note that the patch changes both banded and unbanded rendering.
In most cases the difference is a 1 pixel shift of
an image or a shift of an intersection of an image with a band.
Modified: trunk/gs/src/gdevddrw.c
===================================================================
--- trunk/gs/src/gdevddrw.c 2008-02-03 17:54:23 UTC (rev 8516)
+++ trunk/gs/src/gdevddrw.c 2008-02-04 22:18:08 UTC (rev 8517)
@@ -606,6 +606,8 @@
gs_int_rect r;
INT_RECT_FROM_PARALLELOGRAM(&r, px, py, ax, ay, bx, by);
+ vd_rect(int2fixed(r.p.x), int2fixed(r.p.y), int2fixed(r.q.x), int2fixed(r.q.y),
+ 1, (int)pdevc->colors.pure);
return gx_fill_rectangle_device_rop(r.p.x, r.p.y, r.q.x - r.p.x,
r.q.y - r.p.y, pdevc, dev, lop);
}
Modified: trunk/gs/src/gdevm24.c
===================================================================
--- trunk/gs/src/gdevm24.c 2008-02-03 17:54:23 UTC (rev 8516)
+++ trunk/gs/src/gdevm24.c 2008-02-04 22:18:08 UTC (rev 8517)
@@ -17,6 +17,7 @@
#include "gxdevice.h"
#include "gxdevmem.h" /* semi-public definitions */
#include "gdevmem.h" /* private definitions */
+#include "vdtrace.h"
#define mem_true24_strip_copy_rop mem_gray8_rgb24_strip_copy_rop
@@ -369,10 +370,14 @@
do {
if (sbyte & bit) {
- if (one != gx_no_color_index)
+ if (one != gx_no_color_index) {
put3(pptr, r1, g1, b1);
- } else
+ vd_pixel(int2fixed((pptr - mdev->line_ptrs[y]) / 3), int2fixed(y), RGB(r1, g1, b1));
+ }
+ } else {
put3(pptr, r0, g0, b0);
+ vd_pixel(int2fixed((pptr - mdev->line_ptrs[y]) / 3), int2fixed(y), RGB(r0, g0, b0));
+ }
pptr += 3;
if ((bit >>= 1) == 0)
bit = 0x80, sbyte = *sptr++;
Modified: trunk/gs/src/gxclread.c
===================================================================
--- trunk/gs/src/gxclread.c 2008-02-03 17:54:23 UTC (rev 8516)
+++ trunk/gs/src/gxclread.c 2008-02-04 22:18:08 UTC (rev 8517)
@@ -687,11 +687,14 @@
s.foreign = 1;
s.state = (stream_state *)&rs;
- vd_get_dc('s');
+ if (vd_allowed('s')) {
+ vd_get_dc('s');
+ } else if (vd_allowed('i')) {
+ vd_get_dc('i');
+ }
vd_set_shift(0, 0);
vd_set_scale(0.01);
vd_set_origin(0, 0);
- vd_erase(RGB(192, 192, 192));
code = clist_playback_band(action, crdev, &s, target, x0, y0, mem);
vd_release_dc;
# ifdef DEBUG
Modified: trunk/gs/src/gxi12bit.c
===================================================================
--- trunk/gs/src/gxi12bit.c 2008-02-03 17:54:23 UTC (rev 8516)
+++ trunk/gs/src/gxi12bit.c 2008-02-04 22:18:08 UTC (rev 8517)
@@ -30,6 +30,7 @@
#include "gxdevmem.h"
#include "gxcpath.h"
#include "gximage.h"
+#include "vdtrace.h"
/* ---------------- Unpacking procedures ---------------- */
@@ -353,6 +354,9 @@
xi += wi, wi = -wi;
code = gx_fill_rectangle_device_rop(xi, yt,
wi, iht, pdevc, dev, lop);
+ vd_set_scale(0.01);
+ vd_rect(int2fixed(xi), int2fixed(yt), int2fixed(xi + wi), int2fixed(yt + iht),
+ 1, (int)pdevc->colors.pure);
}
if (code < 0)
goto err;
@@ -371,8 +375,24 @@
ytf = dda_next(pnext.y);
}
/* Fill the final run. */
- code = (*dev_proc(dev, fill_parallelogram))
- (dev, xrun, yrun, xl - xrun, ytf - yrun, pdyx, pdyy, pdevc, lop);
+ if (posture != image_portrait) {
+ code = (*dev_proc(dev, fill_parallelogram))
+ (dev, xrun, yrun, xl - xrun, ytf - yrun, pdyx, pdyy, pdevc, lop);
+ /*vd_quad(xrun, yrun, xl, ytf, xl + pdyx, ytf + pdyy, xrun + pdyx, yrun + pdyy,
+ 1, (int)pdevc->colors.pure); */
+ } else {
+ /* Same code as above near 'fill:' : */
+ int xi = irun;
+ int wi = (irun = fixed2int_var_rounded(xl)) - xi;
+
+ if (wi < 0)
+ xi += wi, wi = -wi;
+ code = gx_fill_rectangle_device_rop(xi, yt,
+ wi, iht, pdevc, dev, lop);
+ vd_set_scale(0.01);
+ vd_rect(int2fixed(xi), int2fixed(yt), int2fixed(xi + wi), int2fixed(yt + iht),
+ 1, (int)pdevc->colors.pure);
+ }
return (code < 0 ? code : 1);
/* Save position if error, in case we resume. */
Modified: trunk/gs/src/gxidata.c
===================================================================
--- trunk/gs/src/gxidata.c 2008-02-03 17:54:23 UTC (rev 8516)
+++ trunk/gs/src/gxidata.c 2008-02-04 22:18:08 UTC (rev 8517)
@@ -278,9 +278,28 @@
static void
update_strip(gx_image_enum *penum)
{
+
+#if 1
+ /* Old code. */
dda_translate(penum->dda.strip.x, penum->cur.x - penum->prev.x);
dda_translate(penum->dda.strip.y, penum->cur.y - penum->prev.y);
penum->dda.pixel0 = penum->dda.strip;
+#else
+ /* A better precision with stromng dda_advance -
+ doesn't work becauae gx_image1_plane_data
+ doesn't call it at each step. */
+ gx_dda_fixed_point temp;
+
+ temp.x.state = penum->dda.strip.x.state;
+ temp.y.state = penum->dda.strip.y.state;
+ temp.x.step = penum->dda.row.x.step;
+ temp.y.step = penum->dda.row.y.step;
+ dda_next(temp.x);
+ dda_next(temp.y);
+ penum->dda.strip.x.state = temp.x.state;
+ penum->dda.strip.y.state = temp.y.state;
+ penum->dda.pixel0 = penum->dda.strip;
+#endif
}
/*
Modified: trunk/gs/src/gxipixel.c
===================================================================
--- trunk/gs/src/gxipixel.c 2008-02-03 17:54:23 UTC (rev 8516)
+++ trunk/gs/src/gxipixel.c 2008-02-04 22:18:08 UTC (rev 8517)
@@ -218,6 +218,7 @@
mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
/* following works for 1, 2, 4, 8, 12, 16 */
index_bps = (bps < 8 ? bps >> 1 : (bps >> 2) + 1);
+#if 0 /* replaced due to inaccurate precision, bug 687345 , text -r300 455690-1.pdf . */
mtx = float2fixed(mat.tx);
mty = float2fixed(mat.ty);
row_extent.x = float2fixed(width * mat.xx + mat.tx) - mtx;
@@ -248,6 +249,54 @@
float2fixed(rh * mat.yx + mat.tx) - mtx);
y_extent.y = float2fixed(rh * mat.yy + mat.ty) - mty;
}
+#else
+ /*
+ * Compute extents with distance transformation.
+ */
+ if (mat.tx > 0)
+ mtx = float2fixed(mat.tx);
+ else { /* Use positive values to ensure round down. */
+ int f = (int)-mat.tx + 1;
+
+ mtx = float2fixed(mat.tx + f) - int2fixed(f);
+ }
+ if (mat.ty > 0)
+ mty = float2fixed(mat.ty);
+ else { /* Use positive values to ensure round down. */
+ int f = (int)-mat.ty + 1;
+
+ mty = float2fixed(mat.ty + f) - int2fixed(f);
+ }
+
+ row_extent.x = float2fixed_rounded(width * mat.xx);
+ row_extent.y =
+ (is_fzero(mat.xy) ? fixed_0 :
+ float2fixed_rounded(width * mat.xy));
+ col_extent.x =
+ (is_fzero(mat.yx) ? fixed_0 :
+ float2fixed_rounded(height * mat.yx));
+ col_extent.y = float2fixed_rounded(height * mat.yy);
+ gx_image_enum_common_init((gx_image_enum_common_t *)penum,
+ (const gs_data_image_t *)pim,
+ &image1_enum_procs, dev,
+ (masked ? 1 : (penum->alpha ? cs_num_components(pcs)+1 : cs_num_components(pcs))),
+ format);
+ if (penum->rect.w == width && penum->rect.h == height) {
+ x_extent = row_extent;
+ y_extent = col_extent;
+ } else {
+ int rw = penum->rect.w, rh = penum->rect.h;
+
+ x_extent.x = float2fixed_rounded(rw * mat.xx);
+ x_extent.y =
+ (is_fzero(mat.xy) ? fixed_0 :
+ float2fixed_rounded(rw * mat.xy));
+ y_extent.x =
+ (is_fzero(mat.yx) ? fixed_0 :
+ float2fixed_rounded(rh * mat.yx));
+ y_extent.y = float2fixed_rounded(rh * mat.yy);
+ }
+#endif
if (masked) { /* This is imagemask. */
if (bps != 1 || pcs != NULL || penum->alpha || decode[0] == decode[1]) {
gs_free_object(mem, penum, "gx_default_begin_image");
Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak 2008-02-03 17:54:23 UTC (rev 8516)
+++ trunk/gs/src/lib.mak 2008-02-04 22:18:08 UTC (rev 8517)
@@ -942,7 +942,7 @@
$(GLCC) $(GLO_)gdevm16.$(OBJ) $(C_) $(GLSRC)gdevm16.c
$(GLOBJ)gdevm24.$(OBJ) : $(GLSRC)gdevm24.c $(GX) $(memory__h)\
- $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h)
+ $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(vdtrace_h)
$(GLCC) $(GLO_)gdevm24.$(OBJ) $(C_) $(GLSRC)gdevm24.c
$(GLOBJ)gdevm32.$(OBJ) : $(GLSRC)gdevm32.c $(GX) $(memory__h)\
@@ -2282,7 +2282,7 @@
$(gsccolor_h) $(gspaint_h)\
$(gxarith_h) $(gxcmap_h) $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h)\
$(gxdevmem_h) $(gxfixed_h) $(gxfrac_h) $(gximage_h) $(gxistate_h)\
- $(gxmatrix_h)
+ $(gxmatrix_h) $(vdtrace_h)
$(GLCC) $(GLO_)gxi12bit.$(OBJ) $(C_) $(GLSRC)gxi12bit.c
no16bit_=$(GLOBJ)gxino16b.$(OBJ)
More information about the gs-cvs
mailing list