summaryrefslogtreecommitdiff
path: root/base/gxiscale.c
diff options
context:
space:
mode:
Diffstat (limited to 'base/gxiscale.c')
-rw-r--r--base/gxiscale.c660
1 files changed, 461 insertions, 199 deletions
diff --git a/base/gxiscale.c b/base/gxiscale.c
index 35480962a..ff0e627a9 100644
--- a/base/gxiscale.c
+++ b/base/gxiscale.c
@@ -186,11 +186,18 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
int num_des_comps;
cmm_dev_profile_t *dev_profile;
int code;
- gx_color_polarity_t pol;
+ gx_color_polarity_t pol = GX_CINFO_POLARITY_UNKNOWN;
int mask_col_high_level = 0;
+ int interpolate_control = penum->dev->interpolate_control;
+ int abs_interp_limit = max(1, any_abs(interpolate_control));
+ int limited_WidthOut, limited_HeightOut;
- if (penum->interpolate == interp_off)
+ if (interpolate_control < 0)
+ penum->interpolate = interp_on; /* not the same as "interp_force" -- threshold still used */
+ if (interpolate_control == interp_off || penum->interpolate == interp_off) {
+ penum->interpolate = interp_off;
return 0;
+ }
if (penum->masked && (mask_col_high_level = mask_suitable_for_interpolation(penum)) < 0) {
penum->interpolate = interp_off;
return 0;
@@ -221,18 +228,26 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
penum->y_extent.x == INT_MIN || penum->y_extent.x == INT_MAX ||
penum->y_extent.y == INT_MIN || penum->y_extent.y == INT_MAX)
{
- /* A calculation has overflowed. Bale */
+ /* A calculation has overflowed. Bail */
return 0;
}
+
if (penum->masked) {
+ abs_interp_limit = 1; /* ignore this for masked images for now */
use_icc = false;
num_des_comps = 1;
+ if (pcs)
+ pol = cs_polarity(pcs);
+ else
+ pol = GX_CINFO_POLARITY_ADDITIVE;
} else {
- if ( pcs->cmm_icc_profile_data != NULL ) {
+ if (pcs == NULL)
+ return 0; /* can't handle this */
+ if (pcs->cmm_icc_profile_data != NULL) {
use_icc = true;
}
- if ( pcs->type->index == gs_color_space_index_Indexed) {
- if ( pcs->base_space->cmm_icc_profile_data != NULL) {
+ if (pcs->type->index == gs_color_space_index_Indexed) {
+ if (pcs->base_space->cmm_icc_profile_data != NULL) {
use_icc = true;
}
}
@@ -250,7 +265,6 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
num_des_comps = gsicc_get_device_profile_comps(dev_profile);
if (num_des_comps != penum->dev->color_info.num_components ||
dev_profile->usefastcolor == true) {
-
use_icc = false;
}
/* If the device has some unique color mapping procs due to its color space,
@@ -284,6 +298,7 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
return 0;
}
#endif
+ iss.abs_interp_limit = abs_interp_limit;
if (penum->masked) {
iss.BitsPerComponentOut = 8;
iss.MaxValueOut = 0xff;
@@ -315,10 +330,6 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
dw / penum->Width))
- fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.x *
dw / penum->Width));
- iss.PatchHeightOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.y + penum->rrect.h) *
- dh / penum->Height))
- - fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.y *
- dh / penum->Height));
iss.LeftMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)iss.LeftMarginIn *
dw / penum->Width));
} else {
@@ -338,15 +349,10 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
dh / penum->Width))
- fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.x *
dh / penum->Width));
- iss.PatchHeightOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.y + penum->rrect.h) *
- dw / penum->Height))
- - fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.y *
- dw / penum->Height));
iss.LeftMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)iss.LeftMarginIn *
dh / penum->Width));
}
iss.PatchWidthOut = any_abs(iss.PatchWidthOut);
- iss.PatchHeightOut = any_abs(iss.PatchHeightOut);
if (iss.LeftMarginOut + iss.PatchWidthOut >= iss.WidthOut) {
iss.LeftMarginOut = iss.WidthOut - iss.PatchWidthOut;
if (iss.LeftMarginOut < 0) {
@@ -361,6 +367,8 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
iss.HeightIn = penum->rect.h;
iss.WidthOut = any_abs(iss.WidthOut);
iss.HeightOut = any_abs(iss.HeightOut);
+ limited_WidthOut = (iss.WidthOut + abs_interp_limit - 1)/abs_interp_limit;
+ limited_HeightOut = (iss.HeightOut + abs_interp_limit - 1)/abs_interp_limit;
if ((penum->posture == image_portrait ? penum->dst_width : penum->dst_height) < 0)
iss.LeftMarginOut = iss.WidthOut - iss.LeftMarginOut - iss.PatchWidthOut;
/* For interpolator cores that don't set Active, have us always active */
@@ -384,6 +392,39 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
iss.spp_decode = cs_num_components(pcs);
}
}
+ /* Set up the filter template. May be changed for "Special" downscaling */
+#ifdef USE_MITCHELL_FILTER
+ templat = &s_IScale_template;
+#else
+ templat = &s_IIEncode_template;
+#endif
+
+ if ((iss.WidthOut < iss.WidthIn) &&
+ (iss.HeightOut < iss.HeightIn) && /* downsampling */
+ (pol != GX_CINFO_POLARITY_UNKNOWN) &&
+ (dev_proc(penum->dev, dev_spec_op)(penum->dev, gxdso_interpolate_antidropout, NULL, 0) > 0)) {
+ /* Special case handling for when we are downsampling to a dithered
+ * device. The point of this non-linear downsampling is to preserve
+ * dark pixels from the source image to avoid dropout. The color
+ * polarity is used for this. */
+ templat = &s_ISpecialDownScale_template;
+ } else {
+ /* No interpolation unless we exceed the device selected minimum */
+ int threshold = dev_proc(penum->dev, dev_spec_op)(penum->dev, gxdso_interpolate_threshold, NULL, 0);
+
+ if ((iss.WidthOut == iss.WidthIn && iss.HeightOut == iss.HeightIn) ||
+ ((penum->interpolate != interp_force) &&
+ (threshold > 0) &&
+ (iss.WidthOut < iss.WidthIn * threshold) &&
+ (iss.HeightOut < iss.HeightIn * threshold))) {
+ penum->interpolate = interp_off;
+ return 0; /* don't interpolate if not scaled up enough */
+ }
+ }
+ /* The SpecialDownScale filter needs polarity, either ADDITIVE or SUBTRACTIVE */
+ /* UNKNOWN case (such as for palette colors) has been handled above */
+ iss.ColorPolarityAdditive = (pol == GX_CINFO_POLARITY_ADDITIVE);
+
if (iss.HeightOut > iss.EntireHeightIn && use_icc) {
iss.early_cm = true;
iss.spp_interp = num_des_comps;
@@ -436,43 +477,13 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
align_bitmap_mod);
/* Size to allocate space to store the input as frac type */
}
-#ifdef USE_MITCHELL_FILTER
- templat = &s_IScale_template;
-#else
- templat = &s_IIEncode_template;
-#endif
- if (!pcs)
- pol = GX_CINFO_POLARITY_ADDITIVE;
- else
- pol = cs_polarity(pcs);
- if ((iss.WidthOut < iss.WidthIn) &&
- (iss.HeightOut < iss.HeightIn) && /* downsampling */
- (pol != GX_CINFO_POLARITY_UNKNOWN) &&
- (dev_proc(penum->dev, dev_spec_op)(penum->dev, gxdso_interpolate_antidropout, NULL, 0) > 0)) {
- /* Special case handling for when we are downsampling (to a dithered
- * device. The point of this non-linear downsampling is to preserve
- * dark pixels from the source image to avoid dropout. The color
- * polarity is used for this. */
- templat = &s_ISpecialDownScale_template;
- } else {
- int threshold = dev_proc(penum->dev, dev_spec_op)(penum->dev, gxdso_interpolate_threshold, NULL, 0);
- if ((iss.WidthOut == iss.WidthIn && iss.HeightOut == iss.HeightIn) ||
- ((penum->interpolate != interp_force) &&
- (threshold > 0) &&
- (iss.WidthOut < iss.WidthIn * threshold) &&
- (iss.HeightOut < iss.HeightIn * threshold))) {
- penum->interpolate = interp_off;
- return 0; /* no interpolation / downsampling */
- }
- }
- /* The SpecialDownScale filter needs polarity, either ADDITIVE or SUBTRACTIVE */
- /* UNKNOWN case (such as for palette colors) has been handled above */
- iss.ColorPolarityAdditive = (pol == GX_CINFO_POLARITY_ADDITIVE);
- /* Allocate a buffer for one source/destination line. */
+ /* Allocate a buffer for one source/destination line. */
+ /* NB: The out_size is for full device res, regardless of abs_interp_limit */
+ /* since we will expand into that area in the x-loop */
{
- uint out_size =
- iss.WidthOut * max(iss.spp_interp * (iss.BitsPerComponentOut / 8),
- ARCH_SIZEOF_COLOR_INDEX);
+ uint out_size = iss.WidthOut * max(iss.spp_interp * ((iss.BitsPerComponentOut) / 8),
+ ARCH_SIZEOF_COLOR_INDEX);
+
/* Allocate based upon frac size (as BitsPerComponentOut=16) output scan
line input plus output. The outsize may have an adjustment for
word boundary on it. Need to account for that now */
@@ -519,6 +530,12 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
(fixed)((int64_t)x0 *
penum->dst_height / penum->Width));
}
+ /* If the InterpolationControl specifies interpolation to less than full device res */
+ /* Set up a scaling DDA to control scaling back to desired image size. */
+ if (abs_interp_limit > 1) {
+ dda_init(pss->params.scale_dda.x, 0, iss.WidthOut, limited_WidthOut);
+ dda_init(pss->params.scale_dda.y, 0, iss.HeightOut, limited_HeightOut);
+ }
if_debug0m('b', penum->memory, "[b]render=interpolate\n");
if (penum->masked) {
if (!mask_col_high_level) {
@@ -662,8 +679,6 @@ initial_decode(gx_image_enum * penum, const byte * buffer, int data_x, int h,
p -= spp_decode, q += spp_decode, ++i)
memcpy(q, p, spp_decode);
stream_r->ptr = out - 1;
- out += round_up(pss->params.WidthIn *
- spp_decode, align_bitmap_mod);
}
} else {
/* We need to do some decoding. Data will remain in 8 bits
@@ -691,8 +706,6 @@ initial_decode(gx_image_enum * penum, const byte * buffer, int data_x, int h,
}
pdata += dpd;
}
- out += round_up(pss->params.WidthIn * spp_decode,
- align_bitmap_mod);
}
} else {
/* indexed 8 bit color values, possibly a device indep. or
@@ -753,12 +766,6 @@ initial_decode(gx_image_enum * penum, const byte * buffer, int data_x, int h,
pdata += dpd; /* Can't have just ++
since we could be going backwards */
}
- /* We need to set the output to the end of the input buffer
- moving it to the next desired word boundary. This must
- be accounted for in the memory allocation of
- gs_image_class_0_interpolate */
- out += round_up(pss->params.WidthIn * spp_decode,
- align_bitmap_mod);
}
} else {
/* More than 8-bits/color values */
@@ -811,8 +818,6 @@ initial_decode(gx_image_enum * penum, const byte * buffer, int data_x, int h,
}
}
}
- out += round_up(pss->params.WidthIn * spp_decode * sizeof(frac),
- align_bitmap_mod);
if_debug0m('B', penum->memory, "\n");
} else {
/* indexed and more than 8bps. Need to get to the base space */
@@ -842,12 +847,6 @@ initial_decode(gx_image_enum * penum, const byte * buffer, int data_x, int h,
gs_cspace_indexed_lookup_frac(pcs, decode_value,psrc);
pdata += dpd;
}
- /* We need to set the output to the end of the input buffer
- moving it to the next desired word boundary. This must
- be accounted for in the memory allocation of
- gs_image_class_0_interpolate */
- out += round_up(pss->params.WidthIn * spp_decode,
- align_bitmap_mod);
} /* end of else on indexed */
} /* end of else on more than 8 bps */
stream_r->limit = stream_r->ptr + row_size;
@@ -863,7 +862,7 @@ static int handle_colors(gx_image_enum *penum, const frac *psrc, int spp_decode,
const gs_color_space *pconcs;
const gs_gstate *pgs = penum->pgs;
const gs_color_space *pcs = penum->pcs;
- bool device_color;
+ bool device_color = false;
bool is_index_space;
int code = 0;
cmm_dev_profile_t *dev_profile;
@@ -958,6 +957,34 @@ static int handle_colors(gx_image_enum *penum, const frac *psrc, int spp_decode,
return code;
}
+/* returns the expanded width using the dda.x */
+static int
+interpolate_scaled_expanded_width(int delta_x, stream_image_scale_state *pss)
+{
+ gx_dda_fixed_point tmp_dda = pss->params.scale_dda;
+ int start_x = dda_current(tmp_dda.x);
+
+ do {
+ dda_next(tmp_dda.x);
+ } while (--delta_x > 0);
+
+ return dda_current(tmp_dda.x) - start_x;
+}
+
+/* returns the expanded height using the dda.y */
+static int
+interpolate_scaled_expanded_height(int delta_y, stream_image_scale_state *pss)
+{
+ gx_dda_fixed_point tmp_dda = pss->params.scale_dda;
+ int start_y = dda_current(tmp_dda.y);
+
+ do {
+ dda_next(tmp_dda.y);
+ } while (--delta_y > 0);
+
+ return dda_current(tmp_dda.y) - start_y;
+}
+
static int
image_render_interpolate(gx_image_enum * penum, const byte * buffer,
int data_x, uint iw, int h, gx_device * dev)
@@ -970,6 +997,8 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
stream_cursor_write stream_w;
byte *out = penum->line;
bool islab = false;
+ int abs_interp_limit = pss->params.abs_interp_limit;
+ int limited_PatchWidthOut = (pss->params.PatchWidthOut + abs_interp_limit - 1) / abs_interp_limit;
if (!penum->masked && pcs->cmm_icc_profile_data != NULL) {
islab = pcs->cmm_icc_profile_data->islab;
@@ -978,12 +1007,13 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
initial_decode(penum, buffer, data_x, h, &stream_r, false);
/*
* Process input and/or collect output. By construction, the pixels are
- * 1-for-1 with the device, but the Y coordinate might be inverted.
+ * 1-for-1 with the device if the abs(interpolate_control) is 1 but the
+ * Y coordinate might be inverted.
*/
{
int xo = penum->xyi.x;
int yo = penum->xyi.y;
- int width = pss->params.WidthOut;
+ int width = (pss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit;
int sizeofPixelOut = pss->params.BitsPerComponentOut / 8;
int dy;
int bpp = dev->color_info.depth;
@@ -999,12 +1029,14 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
const frac *psrc;
gx_device_color devc;
int status, code;
-
byte *l_dptr = out;
int l_dbit = 0;
- byte l_dbyte = ((l_dbit) ? (byte)(*(l_dptr) & (0xff00 >> (l_dbit))) : 0);
+ byte l_dbyte = 0;
int l_xprev = (xo);
- stream_w.limit = out + width *
+ int scaled_x_prev = 0;
+ gx_dda_fixed save_x_dda = pss->params.scale_dda.x;
+
+ stream_w.limit = out + pss->params.WidthOut *
max(spp_decode * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1;
stream_w.ptr = stream_w.limit - width * spp_decode * sizeofPixelOut;
psrc = (const frac *)(stream_w.ptr + 1);
@@ -1018,47 +1050,69 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
if (status < 0 && status != EOFC)
return_error(gs_error_ioerror);
if (stream_w.ptr == stream_w.limit) {
- int xe = xo + pss->params.PatchWidthOut;
+ int xe = xo + limited_PatchWidthOut;
+ int scaled_w = 0; /* accumulate scaled up width */
/* Are we active? (i.e. in the render rectangle) */
if (!pss->params.Active)
goto inactive;
if_debug1m('B', penum->memory, "[B]Interpolated row %d:\n[B]",
penum->line_xy);
- psrc += pss->params.LeftMarginOut * spp_decode;
+ psrc += ((pss->params.LeftMarginOut + abs_interp_limit - 1) / abs_interp_limit) * spp_decode;
for (x = xo; x < xe;) {
code = handle_colors(penum, psrc, spp_decode, &devc, islab, dev);
if (code < 0)
return code;
if (color_is_pure(&devc)) {
- /* Just pack colors into a scan line. */
gx_color_index color = devc.colors.pure;
+ int expand = 1;
+
+ if (abs_interp_limit > 1) {
+ expand = interpolate_scaled_expanded_width(1, pss);
+ }
+ /* Just pack colors into a scan line. */
/* Skip runs quickly for the common cases. */
switch (spp_decode) {
case 1:
do {
- if (sizeof(color) > 4) {
- if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
- else {
- if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
+ scaled_w += expand;
+ while (expand-- > 0) {
+ if (sizeof(color) > 4) {
+ if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ else {
+ if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ };
x++, psrc += 1;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.x);
+ expand = interpolate_scaled_expanded_width(1, pss);
+ } else
+ expand = 1;
} while (x < xe && psrc[-1] == psrc[0]);
break;
case 3:
do {
- if (sizeof(color) > 4) {
- if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
- else {
- if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
+ scaled_w += expand;
+ while (expand-- > 0) {
+ if (sizeof(color) > 4) {
+ if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ else {
+ if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ };
x++, psrc += 3;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.x);
+ expand = interpolate_scaled_expanded_width(1, pss);
+ } else
+ expand = 1;
} while (x < xe &&
psrc[-3] == psrc[0] &&
psrc[-2] == psrc[1] &&
@@ -1066,6 +1120,32 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
break;
case 4:
do {
+ scaled_w += expand;
+ while (expand-- > 0) {
+ if (sizeof(color) > 4) {
+ if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ else {
+ if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ };
+ x++, psrc += 4;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.x);
+ expand = interpolate_scaled_expanded_width(1, pss);
+ } else
+ expand = 1;
+ } while (x < xe &&
+ psrc[-4] == psrc[0] &&
+ psrc[-3] == psrc[1] &&
+ psrc[-2] == psrc[2] &&
+ psrc[-1] == psrc[3]);
+ break;
+ default: /* no run length check for these spp cases */
+ scaled_w += expand;
+ while (expand-- > 0) {
if (sizeof(color) > 4) {
if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
return_error(gs_error_rangecheck);
@@ -1074,35 +1154,42 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
return_error(gs_error_rangecheck);
}
- x++, psrc += 4;
- } while (x < xe &&
- psrc[-4] == psrc[0] &&
- psrc[-3] == psrc[1] &&
- psrc[-2] == psrc[2] &&
- psrc[-1] == psrc[3]);
- break;
- default:
- if (sizeof(color) > 4) {
- if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
- else {
- if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
+ };
x++, psrc += spp_decode;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.x);
+ expand = interpolate_scaled_expanded_width(1, pss);
+ } else
+ expand = 1;
}
} else {
- int rcode, i, rep = 0;
+ int rcode, rep = 0;
/* do _COPY in case any pure colors were accumulated above */
if ( x > l_xprev ) {
sample_store_flush(l_dptr, l_dbit, l_dbyte);
- code = (*dev_proc(dev, copy_color))
- (dev, out, l_xprev - xo, raster,
- gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1);
- if (code < 0)
- return code;
+ if (abs_interp_limit <= 1) {
+ code = (*dev_proc(dev, copy_color))
+ (dev, out, l_xprev - xo, raster,
+ gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1);
+ if (code < 0)
+ return code;
+ } else {
+ /* scale up in X and Y */
+ int scaled_x = xo + scaled_x_prev;
+ int scaled_y = yo + (dy * dda_current(pss->params.scale_dda.y));
+ int scaled_h = interpolate_scaled_expanded_height(1, pss);
+
+ for (; scaled_h > 0; --scaled_h) {
+ code = (*dev_proc(dev, copy_color))
+ (dev, out, scaled_x_prev, raster,
+ gx_no_bitmap_id, scaled_x, scaled_y, scaled_w, 1);
+ if (code < 0)
+ return code;
+ scaled_y += dy;
+ }
+ scaled_x_prev = dda_current(pss->params.scale_dda.x);
+ }
}
/* as above, see if we can accumulate any runs */
switch (spp_decode) {
@@ -1134,27 +1221,62 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
psrc += spp_decode;
break;
}
- rcode = gx_fill_rectangle_device_rop(x, ry, rep, 1, &devc, dev, lop);
- if (rcode < 0)
- return rcode;
- for (i = 0; i < rep; i++) {
- sample_store_skip_next(&l_dptr, &l_dbit, bpp, &l_dbyte);
+ if (abs_interp_limit <= 1) {
+ scaled_w = rep;
+ rcode = gx_fill_rectangle_device_rop(x, ry, rep, 1, &devc, dev, lop);
+ if (rcode < 0)
+ return rcode;
+ } else {
+ int scaled_x = xo + scaled_x_prev;
+ int scaled_y = yo + (dy *dda_current(pss->params.scale_dda.y));
+ int scaled_h = interpolate_scaled_expanded_height(1, pss);
+
+ scaled_w = interpolate_scaled_expanded_width(rep, pss);
+ rcode = gx_fill_rectangle_device_rop(scaled_x, scaled_y, scaled_w, scaled_h,
+ &devc, dev, lop);
+ if (rcode < 0)
+ return rcode;
+ dda_advance(pss->params.scale_dda.x, rep);
+ scaled_x_prev = dda_current(pss->params.scale_dda.x);
}
+ while (scaled_w-- > 0)
+ sample_store_skip_next(&l_dptr, &l_dbit, bpp, &l_dbyte);
+ scaled_w = 0;
l_xprev = x + rep;
x += rep;
}
- }
+ } /* End on x loop */
if ( x > l_xprev ) {
sample_store_flush(l_dptr, l_dbit, l_dbyte);
- code = (*dev_proc(dev, copy_color))
- (dev, out, l_xprev - xo, raster,
- gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1);
- if (code < 0)
- return code;
+ if (abs_interp_limit <= 1) {
+ code = (*dev_proc(dev, copy_color))
+ (dev, out, l_xprev - xo, raster,
+ gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1);
+ if (code < 0)
+ return code;
+ } else {
+ /* scale up in X and Y */
+ int scaled_x = xo + scaled_x_prev;
+ int scaled_y = yo + (dy * dda_current(pss->params.scale_dda.y));
+ int scaled_h = interpolate_scaled_expanded_height(1, pss);
+
+ for (; scaled_h > 0; --scaled_h) {
+ code = (*dev_proc(dev, copy_color))
+ (dev, out, scaled_x_prev, raster,
+ gx_no_bitmap_id, scaled_x, scaled_y, scaled_w, 1);
+ if (code < 0)
+ return code;
+ scaled_y += dy;
+ }
+ }
}
/*if_debug1m('w', dev->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */
inactive:
penum->line_xy++;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.y);
+ pss->params.scale_dda.x = save_x_dda; /* reset X to start of line */
+ }
if_debug0m('B', dev->memory, "\n");
}
if ((status == 0 && stream_r.ptr == stream_r.limit) || status == EOFC)
@@ -1338,6 +1460,8 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer,
byte *out = penum->line;
stream_cursor_read stream_r;
stream_cursor_write stream_w;
+ int abs_interp_limit = pss->params.abs_interp_limit;
+ int limited_PatchWidthOut = (pss->params.PatchWidthOut + abs_interp_limit - 1) / abs_interp_limit;
if (penum->icc_link == NULL) {
return gs_rethrow(-1, "ICC Link not created during gs_image_class_0_interpolate");
@@ -1351,7 +1475,7 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer,
{
int xo = penum->xyi.x;
int yo = penum->xyi.y;
- int width = pss->params.WidthOut;
+ int width = (pss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit;
int width_in = pss->params.WidthIn;
int sizeofPixelOut = pss->params.BitsPerComponentOut / 8;
int dy;
@@ -1411,10 +1535,10 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer,
/* Set up the buffer descriptors. */
gsicc_init_buffer(&input_buff_desc, spp_decode, 2,
false, false, false, 0, width * spp_decode,
- 1, pss->params.PatchWidthOut);
+ 1, limited_PatchWidthOut);
gsicc_init_buffer(&output_buff_desc, spp_cm, 2,
false, false, false, 0, width * spp_cm,
- 1, pss->params.PatchWidthOut);
+ 1, limited_PatchWidthOut);
}
}
for (;;) {
@@ -1423,13 +1547,15 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer,
const unsigned short *pinterp;
gx_device_color devc;
int status;
-
byte *l_dptr = out;
int l_dbit = 0;
- byte l_dbyte = ((l_dbit) ? (byte)(*(l_dptr) & (0xff00 >> (l_dbit))) : 0);
+ byte l_dbyte = 0;
int l_xprev = (xo);
- stream_w.limit = out + width *
- max(spp_interp * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1;
+ int scaled_x_prev = 0;
+ gx_dda_fixed save_x_dda = pss->params.scale_dda.x;
+
+ stream_w.limit = out + pss->params.WidthOut *
+ max(spp_decode * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1;
stream_w.ptr = stream_w.limit - width * spp_interp * sizeofPixelOut;
pinterp = (const unsigned short *)(stream_w.ptr + 1);
/* This is where the rescale takes place; this will consume the
@@ -1442,7 +1568,8 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer,
if (status < 0 && status != EOFC)
return_error(gs_error_ioerror);
if (stream_w.ptr == stream_w.limit) {
- int xe = xo + pss->params.PatchWidthOut;
+ int xe = xo + limited_PatchWidthOut;
+ int scaled_w = 0; /* accumulate scaled up width */
/* Are we active? (i.e. in the render rectangle) */
if (!pss->params.Active)
@@ -1454,12 +1581,12 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer,
if (penum->icc_link->is_identity || pss->params.early_cm) {
/* Fastest case. No CM needed */
p_cm_interp = (unsigned short *) pinterp;
- p_cm_interp += pss->params.LeftMarginOut * spp_cm;
+ p_cm_interp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_cm;
} else {
/* Transform */
- pinterp += pss->params.LeftMarginOut * spp_decode;
+ pinterp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_decode;
p_cm_interp = (unsigned short *) p_cm_buff;
- p_cm_interp += pss->params.LeftMarginOut * spp_cm;
+ p_cm_interp += ((pss->params.LeftMarginOut + abs_interp_limit - 1) / abs_interp_limit) * spp_cm;
(penum->icc_link->procs.map_buffer)(dev, penum->icc_link,
&input_buff_desc,
&output_buff_desc,
@@ -1479,40 +1606,86 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer,
/* Get the device color */
get_device_color(penum, p_cm_interp, &devc, &color, dev);
if (color_is_pure(&devc)) {
- /* Just pack colors into a scan line. */
gx_color_index color = devc.colors.pure;
+ int expand = 1;
+
+ if (abs_interp_limit > 1) {
+ expand = interpolate_scaled_expanded_width(1, pss);
+ }
+ /* Just pack colors into a scan line. */
/* Skip runs quickly for the common cases. */
switch (spp_cm) {
case 1:
do {
- if (sizeof(color) > 4) {
- if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
- else {
- if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
+ scaled_w += expand;
+ while (expand-- > 0) {
+ if (sizeof(color) > 4) {
+ if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ else {
+ if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ };
x++, p_cm_interp += 1;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.x);
+ expand = interpolate_scaled_expanded_width(1, pss);
+ } else
+ expand = 1;
} while (x < xe && p_cm_interp[-1] == p_cm_interp[0]);
break;
case 3:
do {
- if (sizeof(color) > 4) {
- if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
- else {
- if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
+ scaled_w += expand;
+ while (expand-- > 0) {
+ if (sizeof(color) > 4) {
+ if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ else {
+ if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ };
x++, p_cm_interp += 3;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.x);
+ expand = interpolate_scaled_expanded_width(1, pss);
+ } else
+ expand = 1;
} while (x < xe && p_cm_interp[-3] == p_cm_interp[0] &&
p_cm_interp[-2] == p_cm_interp[1] &&
p_cm_interp[-1] == p_cm_interp[2]);
break;
case 4:
do {
+ scaled_w += expand;
+ while (expand-- > 0) {
+ if (sizeof(color) > 4) {
+ if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ else {
+ if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
+ return_error(gs_error_rangecheck);
+ }
+ };
+ x++, p_cm_interp += 4;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.x);
+ expand = interpolate_scaled_expanded_width(1, pss);
+ } else
+ expand = 1;
+ } while (x < xe && p_cm_interp[-4] == p_cm_interp[0] &&
+ p_cm_interp[-3] == p_cm_interp[1] &&
+ p_cm_interp[-2] == p_cm_interp[2] &&
+ p_cm_interp[-1] == p_cm_interp[3]);
+ break;
+ default:
+ scaled_w += expand;
+ while (expand-- > 0) {
if (sizeof(color) > 4) {
if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
return_error(gs_error_rangecheck);
@@ -1521,34 +1694,42 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer,
if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
return_error(gs_error_rangecheck);
}
- x++, p_cm_interp += 4;
- } while (x < xe && p_cm_interp[-4] == p_cm_interp[0] &&
- p_cm_interp[-3] == p_cm_interp[1] &&
- p_cm_interp[-2] == p_cm_interp[2] &&
- p_cm_interp[-1] == p_cm_interp[3]);
- break;
- default:
- if (sizeof(color) > 4) {
- if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
- else {
- if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0)
- return_error(gs_error_rangecheck);
- }
+ };
x++, p_cm_interp += spp_cm;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.x);
+ expand = interpolate_scaled_expanded_width(1, pss);
+ } else
+ expand = 1;
}
} else {
- int rcode, i, rep = 0;
+ int rcode, rep = 0;
/* do _COPY in case any pure colors were accumulated above*/
if ( x > l_xprev ) {
sample_store_flush(l_dptr, l_dbit, l_dbyte);
- code = (*dev_proc(dev, copy_color))
- (dev, out, l_xprev - xo, raster,
- gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1);
- if (code < 0)
- return code;
+ if (abs_interp_limit <= 1) {
+ code = (*dev_proc(dev, copy_color))
+ (dev, out, l_xprev - xo, raster,
+ gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1);
+ if (code < 0)
+ return code;
+ } else {
+ /* scale up in X and Y */
+ int scaled_x = xo + scaled_x_prev;
+ int scaled_y = yo + (dy * dda_current(pss->params.scale_dda.y));
+ int scaled_h = interpolate_scaled_expanded_height(1, pss);
+
+ for (; scaled_h > 0; --scaled_h) {
+ code = (*dev_proc(dev, copy_color))
+ (dev, out, scaled_x_prev, raster,
+ gx_no_bitmap_id, scaled_x, scaled_y, scaled_w, 1);
+ if (code < 0)
+ return code;
+ scaled_y += dy;
+ }
+ scaled_x_prev = dda_current(pss->params.scale_dda.x);
+ }
}
/* as above, see if we can accumulate any runs */
switch (spp_cm) {
@@ -1576,27 +1757,62 @@ image_render_interpolate_icc(gx_image_enum * penum, const byte * buffer,
rep = 1, p_cm_interp += spp_cm;
break;
}
- rcode = gx_fill_rectangle_device_rop(x, ry, rep, 1, &devc, dev, lop);
- if (rcode < 0)
- return rcode;
- for (i = 0; i < rep; i++) {
- sample_store_skip_next(&l_dptr, &l_dbit, bpp, &l_dbyte);
+ if (abs_interp_limit <= 1) {
+ scaled_w = rep;
+ rcode = gx_fill_rectangle_device_rop(x, ry, rep, 1, &devc, dev, lop);
+ if (rcode < 0)
+ return rcode;
+ } else {
+ int scaled_x = xo + scaled_x_prev;
+ int scaled_y = yo + (dy *dda_current(pss->params.scale_dda.y));
+ int scaled_h = interpolate_scaled_expanded_height(1, pss);
+
+ scaled_w = interpolate_scaled_expanded_width(rep, pss);
+ rcode = gx_fill_rectangle_device_rop(scaled_x, scaled_y, scaled_w, scaled_h,
+ &devc, dev, lop);
+ if (rcode < 0)
+ return rcode;
+ dda_advance(pss->params.scale_dda.x, rep);
+ scaled_x_prev = dda_current(pss->params.scale_dda.x);
}
+ while (scaled_w-- > 0)
+ sample_store_skip_next(&l_dptr, &l_dbit, bpp, &l_dbyte);
+ scaled_w = 0;
l_xprev = x + rep;
x += rep;
}
} /* End on x loop */
if ( x > l_xprev ) {
sample_store_flush(l_dptr, l_dbit, l_dbyte);
- code = (*dev_proc(dev, copy_color))
- (dev, out, l_xprev - xo, raster,
- gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1);
- if (code < 0)
- return code;
+ if (abs_interp_limit <= 1) {
+ code = (*dev_proc(dev, copy_color))
+ (dev, out, l_xprev - xo, raster,
+ gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1);
+ if (code < 0)
+ return code;
+ } else {
+ /* scale up in X and Y */
+ int scaled_x = xo + scaled_x_prev;
+ int scaled_y = yo + (dy *dda_current(pss->params.scale_dda.y));
+ int scaled_h = interpolate_scaled_expanded_height(1, pss);
+
+ for (; scaled_h > 0; --scaled_h) {
+ code = (*dev_proc(dev, copy_color))
+ (dev, out, scaled_x_prev, raster,
+ gx_no_bitmap_id, scaled_x, scaled_y, scaled_w, 1);
+ if (code < 0)
+ return code;
+ scaled_y += dy;
+ }
+ }
}
/*if_debug1m('w', penum->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */
inactive:
penum->line_xy++;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.y);
+ pss->params.scale_dda.x = save_x_dda; /* reset X to start of line */
+ }
if_debug0m('B', penum->memory, "\n");
}
if ((status == 0 && stream_r.ptr == stream_r.limit) || status == EOFC)
@@ -1625,6 +1841,7 @@ image_render_interpolate_landscape(gx_image_enum * penum,
stream_cursor_write stream_w;
byte *out = penum->line;
bool islab = false;
+ int abs_interp_limit = pss->params.abs_interp_limit;
if (pcs->cmm_icc_profile_data != NULL) {
islab = pcs->cmm_icc_profile_data->islab;
@@ -1638,7 +1855,7 @@ image_render_interpolate_landscape(gx_image_enum * penum,
{
int xo = penum->xyi.y;
int yo = penum->xyi.x;
- int width = pss->params.WidthOut;
+ int width = (pss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit;
int sizeofPixelOut = pss->params.BitsPerComponentOut / 8;
int dy;
@@ -1652,7 +1869,12 @@ image_render_interpolate_landscape(gx_image_enum * penum,
const frac *psrc;
gx_device_color devc;
int status, code;
+ int scaled_w = 0;
+ gx_dda_fixed save_x_dda;
+ if (abs_interp_limit > 1) {
+ save_x_dda = pss->params.scale_dda.x;
+ }
stream_w.limit = out + width *
max(spp_decode * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1;
stream_w.ptr = stream_w.limit - width * spp_decode * sizeofPixelOut;
@@ -1667,14 +1889,14 @@ image_render_interpolate_landscape(gx_image_enum * penum,
if (status < 0 && status != EOFC)
return_error(gs_error_ioerror);
if (stream_w.ptr == stream_w.limit) {
- int xe = xo + pss->params.PatchWidthOut;
+ int xe = xo + (pss->params.PatchWidthOut + abs_interp_limit - 1) / abs_interp_limit;
/* Are we active? (i.e. in the render rectangle) */
if (!pss->params.Active)
goto inactive;
if_debug1m('B', penum->memory, "[B]Interpolated (rotated) row %d:\n[B]",
penum->line_xy);
- psrc += pss->params.LeftMarginOut * spp_decode;
+ psrc += (pss->params.LeftMarginOut / abs_interp_limit) * spp_decode;
for (x = xo; x < xe;) {
code = handle_colors(penum, psrc, spp_decode, &devc, islab, dev);
if (code < 0)
@@ -1715,15 +1937,32 @@ image_render_interpolate_landscape(gx_image_enum * penum,
psrc += spp_decode;
break;
}
- rcode = gx_fill_rectangle_device_rop(ry, x, 1, rep, &devc, dev, lop);
- if (rcode < 0)
- return rcode;
+ if (abs_interp_limit <= 1) {
+ rcode = gx_fill_rectangle_device_rop(ry, x, 1, rep, &devc, dev, lop);
+ if (rcode < 0)
+ return rcode;
+ } else {
+ int scaled_x = xo + dda_current(pss->params.scale_dda.x);
+ int scaled_y = yo + (dy *dda_current(pss->params.scale_dda.y));
+ int scaled_h = interpolate_scaled_expanded_height(1, pss);
+
+ scaled_w = interpolate_scaled_expanded_width(rep, pss);
+ rcode = gx_fill_rectangle_device_rop(scaled_y, scaled_x, scaled_h, scaled_w,
+ &devc, dev, lop);
+ if (rcode < 0)
+ return rcode;
+ dda_advance(pss->params.scale_dda.x, rep);
+ }
x += rep;
}
}
/*if_debug1m('w', dev->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */
inactive:
penum->line_xy++;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.y);
+ pss->params.scale_dda.x = save_x_dda; /* reset X to start of line */
+ }
if_debug0m('B', dev->memory, "\n");
}
if ((status == 0 && stream_r.ptr == stream_r.limit) || status == EOFC)
@@ -1903,6 +2142,7 @@ image_render_interpolate_landscape_icc(gx_image_enum * penum,
byte *out = penum->line;
stream_cursor_read stream_r;
stream_cursor_write stream_w;
+ int abs_interp_limit = pss->params.abs_interp_limit;
if (penum->icc_link == NULL) {
return gs_rethrow(-1, "ICC Link not created during gs_image_class_0_interpolate");
@@ -1916,7 +2156,7 @@ image_render_interpolate_landscape_icc(gx_image_enum * penum,
{
int xo = penum->xyi.y;
int yo = penum->xyi.x;
- int width = pss->params.WidthOut;
+ int width = (pss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit;
int width_in = pss->params.WidthIn;
int sizeofPixelOut = pss->params.BitsPerComponentOut / 8;
int dy;
@@ -1988,7 +2228,12 @@ image_render_interpolate_landscape_icc(gx_image_enum * penum,
const unsigned short *pinterp;
gx_device_color devc;
int status;
+ int scaled_w = 0;
+ gx_dda_fixed save_x_dda;
+ if (abs_interp_limit > 1) {
+ save_x_dda = pss->params.scale_dda.x;
+ }
stream_w.limit = out + width *
max(spp_interp * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1;
stream_w.ptr = stream_w.limit - width * spp_interp * sizeofPixelOut;
@@ -2003,7 +2248,7 @@ image_render_interpolate_landscape_icc(gx_image_enum * penum,
if (status < 0 && status != EOFC)
return_error(gs_error_ioerror);
if (stream_w.ptr == stream_w.limit) {
- int xe = xo + pss->params.PatchWidthOut;
+ int xe = xo + (pss->params.PatchWidthOut + abs_interp_limit - 1) / abs_interp_limit;
/* Are we active? (i.e. in the render rectangle) */
if (!pss->params.Active)
@@ -2024,7 +2269,7 @@ image_render_interpolate_landscape_icc(gx_image_enum * penum,
(void*) pinterp,
(void*) p_cm_interp);
}
- p_cm_interp += pss->params.LeftMarginOut * spp_cm;
+ p_cm_interp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_cm;
for (x = xo; x < xe;) {
#ifdef DEBUG
if (gs_debug_c('B')) {
@@ -2069,15 +2314,32 @@ image_render_interpolate_landscape_icc(gx_image_enum * penum,
break;
}
- rcode = gx_fill_rectangle_device_rop(ry, x, 1, rep, &devc, dev, lop);
- if (rcode < 0)
- return rcode;
+ if (abs_interp_limit <= 1) {
+ rcode = gx_fill_rectangle_device_rop(ry, x, 1, rep, &devc, dev, lop);
+ if (rcode < 0)
+ return rcode;
+ } else {
+ int scaled_x = xo + dda_current(pss->params.scale_dda.x);
+ int scaled_y = yo + (dy *dda_current(pss->params.scale_dda.y));
+ int scaled_h = interpolate_scaled_expanded_height(1, pss);
+
+ scaled_w = interpolate_scaled_expanded_width(rep, pss);
+ rcode = gx_fill_rectangle_device_rop(scaled_y, scaled_x, scaled_h, scaled_w,
+ &devc, dev, lop);
+ if (rcode < 0)
+ return rcode;
+ dda_advance(pss->params.scale_dda.x, rep);
+ }
x += rep;
}
} /* End on x loop */
/*if_debug1m('w', penum->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */
inactive:
penum->line_xy++;
+ if (abs_interp_limit > 1) {
+ dda_next(pss->params.scale_dda.y);
+ pss->params.scale_dda.x = save_x_dda; /* reset X to start of line */
+ }
if_debug0m('B', penum->memory, "\n");
}
if ((status == 0 && stream_r.ptr == stream_r.limit) || status == EOFC)