[gs-cvs] rev 7516 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Sun Dec 17 05:56:52 PST 2006
Author: leonardo
Date: 2006-12-17 05:56:52 -0800 (Sun, 17 Dec 2006)
New Revision: 7516
Modified:
trunk/gs/src/gdevddrw.c
trunk/gs/src/gdevdsha.c
Log:
Fix (shadings) : A fixed overflow happened while computing a color (continued).
THIS IS INCOMPATIBLE CHANGE : The device virtual method
fill_linear_color_scanline now restores the semantics,
which was defined before revision 7510.
In other words, this incompatible change reverts
the recent incompatible change.
DETAILS :
Debugged with CET 12-14O.PS SpecialTestJ02Test12.
A scanline gradient could overflow because
the pixel span may be few wider than the spot span
due to pixel rounding.
To prevent the overflow, we base the color proportion
on the last pixel inside the span.
See comments in code.
We decided to remove "half color values"
(which were introduced in revision 7510)
from the device interface because
they bring an extra complexity.
EXPECTED DIFFERENCES :
Unimportant single pixel difference in shadings :
pdfwrite 72dpi :
"446-01-fixed.ps"
"483-01.ps"
"483-05-fixed.ps"
"chilis_black.pdf"
"Clarke Tate Manns Chinese.ai"
"gradmesh.ai"
"shading_prob_800.ps"
"SmoothShading.pdf"
"STEUER-RollingMesh 1(linear).ai"
"STEUER-RollingMesh 2(radial).ai"
"STEUER-RollingMesh 3(Final).ai"
pdfwrite 300dpi :
"442-01.ps"
"446-01-fixed.ps"
"464-01-fixed.ps"
"478-01.ps"
"483-01.ps"
"483-05-fixed.ps"
"Altona-Testsuite_p2_S_x3.pdf"
"Altona_Visual_bb_1v1_x3.pdf"
"Altona_Visual_sb_1v1_x3.pdf"
"chilis_black.pdf"
"Clarke Tate Manns Chinese.ai"
"gradmesh.ai"
"S2_Digitalproof-Forum_x3k.pdf"
"shading_prob_800.ps"
"SmoothShading.pdf"
"STEUER-RollingMesh 1(linear).ai"
"STEUER-RollingMesh 2(radial).ai"
"STEUER-RollingMesh 3(Final).ai"
normal 72dpi :
"446-01-fixed.ps"
"483-05-fixed.ps"
"chilis_black.pdf"
"Clarke Tate Manns Chinese.ai"
"gradmesh.ai"
"shading_prob_800.ps"
"SmoothShading.pdf"
"STEUER-RollingMesh 1(linear).ai"
"STEUER-RollingMesh 2(radial).ai"
"STEUER-RollingMesh 3(Final).ai"
normal 300dpi :
"442-01.ps"
"446-01-fixed.ps"
"464-01-fixed.ps"
"483-01.ps"
"483-05-fixed.ps"
"Altona-Testsuite_p2_S_x3.pdf"
"Altona_Visual_bb_1v1_x3.pdf"
"Altona_Visual_sb_1v1_x3.pdf"
"Clarke Tate Manns Chinese.ai"
"gradmesh.ai"
"S2_Digitalproof-Forum_x3k.pdf"
Modified: trunk/gs/src/gdevddrw.c
===================================================================
--- trunk/gs/src/gdevddrw.c 2006-12-17 00:26:30 UTC (rev 7515)
+++ trunk/gs/src/gdevddrw.c 2006-12-17 13:56:52 UTC (rev 7516)
@@ -256,14 +256,24 @@
int32_t xr = r->x - (r->xf == -r->h ? 1 : 0) - fixed_half; /* Revert the GX_FILL_TRAPEZOID shift. */
/* The pixel span boundaries : */
int32_t x0 = int2fixed(il) + fixed_half; /* Shift to the pixel center. */
- int32_t x1 = int2fixed(ir) + fixed_half; /* Shift to the pixel center. */
+ int32_t x1 = int2fixed(ir) - fixed_half; /* The center of the last pixel to paint. */
int i;
# ifdef DEBUG
if (arith_rshift_1(xr) - arith_rshift_1(xl) >= 0x3FFFFFFE) /* Can overflow ? */
return_error(gs_error_unregistered); /* Must not happen. */
# endif
+ /* We cannot compute the color of the 'ir' pixel
+ because it can overflow 'c1' due to the pixel ir center
+ may be greater that r->x .
+ Therefore we base the proportion on the pixel index ir-1 (see comment to 'x1').
+ Debugged with CET 12-14O.PS SpecialTestJ02Test12.
+ */
xg->den = fixed2int(x1 - x0);
+ if (xg->den <= 0) {
+ /* The span contains a single pixel, will construct a degenerate gradient. */
+ xg->den = 1; /* Safety (against zerodivide). */
+ }
for (i = 0; i < num_components; i++) {
/* Ignoring the ending colors fractions,
so the color gets a slightly smaller value
@@ -272,9 +282,8 @@
which drops the fraction anyway. */
int32_t cl = lg->c[i];
int32_t cr = rg->c[i];
- /* Use half color values against c1 overflow : */
- int32_t c0 = (int32_t)((cl + ((int64_t)cr - cl) * (x0 - xl) / (xr - xl)) / 2);
- int32_t c1 = (int32_t)((cl + ((int64_t)cr - cl) * (x1 - xl) / (xr - xl)) / 2);
+ int32_t c0 = (int32_t)(cl + ((int64_t)cr - cl) * (x0 - xl) / (xr - xl));
+ int32_t c1 = (int32_t)(cl + ((int64_t)cr - cl) * (x1 - xl) / (xr - xl));
xg->c[i] = c0;
xg->f[i] = 0; /* Insufficient bits to compute it better.
@@ -298,9 +307,7 @@
xg->den = 1;
for (i = 0; i < num_components; i++) {
- /* set_x_gradient_nowedge passes half color values against an overflow.
- Set half value here for compatibility. */
- xg->c[i] = (lg->den == 0 ? rg->c[i] : lg->c[i]) / 2;
+ xg->c[i] = (lg->den == 0 ? rg->c[i] : lg->c[i]);
xg->f[i] = 0; /* Compatible to set_x_gradient_nowedge. */
xg->num[i] = 0;
}
Modified: trunk/gs/src/gdevdsha.c
===================================================================
--- trunk/gs/src/gdevdsha.c 2006-12-17 00:26:30 UTC (rev 7515)
+++ trunk/gs/src/gdevdsha.c 2006-12-17 13:56:52 UTC (rev 7516)
@@ -41,15 +41,13 @@
if (j < fixed2int(fa->clip->p.y) ||
j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */
return 0;
- /* set_x_gradient_nowedge passes half color values against an overflow.
- Compensate that here with subtracting 1 from the bits shift below (2 occurances). */
for (k = 0; k < n; k++) {
int shift = cinfo->comp_shift[k];
int bits = cinfo->comp_bits[k];
c[k] = c0[k];
f[k] = c0f[k];
- ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 2 - bits)) << shift;
+ ci0 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
}
for (i = i0 + 1; i < i1; i++) {
ci1 = 0;
@@ -65,7 +63,7 @@
m += cg_den;
}
f[k] = m;
- ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 2 - bits)) << shift;
+ ci1 |= (gx_color_index)(c[k] >> (sizeof(c[k]) * 8 - 1 - bits)) << shift;
}
if (ci1 != ci0) {
si = max(bi, fixed2int(fa->clip->p.x)); /* Must be compatible to the clipping logic. */
More information about the gs-cvs
mailing list