diff options
-rw-r--r-- | gs/base/gxht_thresh.c | 89 | ||||
-rw-r--r-- | gs/base/gxht_thresh.h | 2 | ||||
-rw-r--r-- | gs/base/gxicolor.c | 111 | ||||
-rw-r--r-- | gs/base/gxidata.c | 6 | ||||
-rw-r--r-- | gs/base/gximono.c | 117 | ||||
-rw-r--r-- | gs/base/lib.mak | 2 |
6 files changed, 219 insertions, 108 deletions
diff --git a/gs/base/gxht_thresh.c b/gs/base/gxht_thresh.c index a783407a8..279fbef4b 100644 --- a/gs/base/gxht_thresh.c +++ b/gs/base/gxht_thresh.c @@ -413,7 +413,7 @@ gxht_thresh_image_init(gx_image_enum *penum) data. */ if (penum->posture == image_landscape) { int col_length = - fixed2int_var_rounded(any_abs(penum->x_extent.y)) * spp_out; + fixed2int_var_rounded(any_abs(penum->x_extent.y)); ox = dda_current(penum->dda.pixel0.x); oy = dda_current(penum->dda.pixel0.y); /* Line_size is col_length rounded up - why? */ @@ -423,9 +423,9 @@ gxht_thresh_image_init(gx_image_enum *penum) penum->line_size = temp * LAND_BITS; /* The stride */ /* Now we need at most LAND_BITS of these */ penum->line = gs_alloc_bytes(penum->memory, - LAND_BITS * penum->line_size + 16, + LAND_BITS * penum->line_size * spp_out + 16, "gxht_thresh"); - /* Same with this */ + /* Same with this. However, we only need one plane here */ penum->thresh_buffer = gs_alloc_bytes(penum->memory, penum->line_size * LAND_BITS + 16, "gxht_thresh"); @@ -462,7 +462,7 @@ gxht_thresh_image_init(gx_image_enum *penum) penum->ht_offset_bits = 0; /* Will get set in call to render */ if (code >= 0) { #if defined(DEBUG) || defined(PACIFY_VALGRIND) - memset(penum->line, 0, LAND_BITS * penum->line_size + 16); + memset(penum->line, 0, LAND_BITS * penum->line_size * spp_out + 16); memset(penum->ht_buffer, 0, penum->line_size * (LAND_BITS>>3)); memset(penum->thresh_buffer, 0, LAND_BITS * penum->line_size + 16); #endif @@ -502,7 +502,7 @@ gxht_thresh_image_init(gx_image_enum *penum) max_height = (int) ceil(fixed2float(any_abs(penum->dst_height)) / (float) penum->Height); penum->ht_buffer = gs_alloc_bytes(penum->memory, - penum->ht_stride * max_height * spp_out, + penum->ht_stride * max_height, "gxht_thresh"); /* We want to have 128 bit alignement for our contone and threshold strips so that we can use SSE operations @@ -522,7 +522,7 @@ gxht_thresh_image_init(gx_image_enum *penum) penum->line = gs_alloc_bytes(penum->memory, penum->line_size * spp_out, "gxht_thresh"); penum->thresh_buffer = gs_alloc_bytes(penum->memory, - penum->line_size * max_height * spp_out, + penum->line_size * max_height, "gxht_thresh"); if (penum->line == NULL || penum->thresh_buffer == NULL || penum->ht_buffer == NULL) { @@ -530,10 +530,8 @@ gxht_thresh_image_init(gx_image_enum *penum) } else { #if defined(DEBUG) || defined(PACIFY_VALGRIND) memset(penum->line, 0, penum->line_size * spp_out); - memset(penum->ht_buffer, 0, - penum->ht_stride * max_height * spp_out); - memset(penum->thresh_buffer, 0, - penum->line_size * max_height * spp_out); + memset(penum->ht_buffer, 0, penum->ht_stride * max_height); + memset(penum->thresh_buffer, 0, penum->line_size * max_height); #endif } } @@ -567,6 +565,31 @@ fill_threshhold_buffer(byte *dest_strip, byte *src_strip, int src_width, memset(ptr_out_temp, 0, ii); #endif } +/* This only moves the data but does not do a reset of the variables. Used + for case where we have multiple bands of data (e.g. CMYK output) */ +static void +move_landscape_buffer(ht_landscape_info_t *ht_landscape, byte *contone_align, + int data_length) +{ + int k; + int position_curr, position_new; + + if (ht_landscape->index < 0) { + /* Moving right to left, move column to far right */ + position_curr = ht_landscape->curr_pos + 1; + position_new = LAND_BITS-1; + } else { + /* Moving left to right, move column to far left */ + position_curr = ht_landscape->curr_pos - 1; + position_new = 0; + } + for (k = 0; k < data_length; k++) { + contone_align[position_new] = contone_align[position_curr]; + position_curr += LAND_BITS; + position_new += LAND_BITS; + } +} + /* If we are in here, we had data left over. Move it to the proper position and get ht_landscape_info_t set properly */ @@ -612,7 +635,7 @@ int gxht_thresh_plane(gx_image_enum *penum, gx_ht_order *d_order, fixed xrun, int dest_width, int dest_height, byte *thresh_align, byte *contone_align, int contone_stride, - gx_device * dev, int plane_number) + gx_device * dev, int plane_number, bool allow_reset) { int thresh_width, thresh_height, dx; int left_rem_end, left_width, vdi; @@ -632,6 +655,7 @@ gxht_thresh_plane(gx_image_enum *penum, gx_ht_order *d_order, int dithered_stride = penum->ht_stride; bool is_planar_dev = dev_proc(dev, dev_spec_op)(dev, gxdso_is_native_planar, NULL, 0); + bool done = false; /* Go ahead and fill the threshold line buffer with tiled threshold values. First just grab the row or column that we are going to tile with and @@ -736,9 +760,9 @@ gxht_thresh_plane(gx_image_enum *penum, gx_ht_order *d_order, * partial to get us in sync with the 1 bit devices 16 bit * positions. */ vdi = penum->wci; - while (penum->ht_landscape.count >= LAND_BITS || + while ( (penum->ht_landscape.count >= LAND_BITS || ((penum->ht_landscape.count >= offset_bits) && - penum->ht_landscape.offset_set)) { + penum->ht_landscape.offset_set)) && !done ) { /* Go ahead and 2D tile in the threshold buffer at this time */ /* Always work the tiling from the upper left corner of our LAND_BITS columns */ @@ -808,7 +832,6 @@ gxht_thresh_plane(gx_image_enum *penum, gx_ht_order *d_order, gx_ht_threshold_landscape(contone_align, thresh_align, penum->ht_landscape, halftone, dest_height); /* Perform the copy mono */ - penum->ht_landscape.offset_set = false; if (penum->ht_landscape.index < 0) { if (!is_planar_dev) { (*dev_proc(dev, copy_mono)) (dev, halftone, 0, LAND_BITS>>3, @@ -846,22 +869,34 @@ gxht_thresh_plane(gx_image_enum *penum, gx_ht_order *d_order, } /* Clean up and reset our buffer. We may have a line left over that has to be maintained due to line replication in the - resolution conversion */ - if (width != penum->ht_landscape.count) { - reset_landscape_buffer(&(penum->ht_landscape), contone_align, - dest_height, width); + resolution conversion. However, pay attention to the reset + flag which indicates we are done with our last plane */ + if (!allow_reset) { + if (width != penum->ht_landscape.count) { + /* move the line do not reset the stuff */ + move_landscape_buffer(&(penum->ht_landscape), + contone_align, dest_height); + } + done = true; } else { - /* Reset the whole buffer */ - penum->ht_landscape.count = 0; - if (penum->ht_landscape.index < 0) { - /* Going right to left */ - penum->ht_landscape.curr_pos = LAND_BITS-1; + penum->ht_landscape.offset_set = false; + if (width != penum->ht_landscape.count) { + reset_landscape_buffer(&(penum->ht_landscape), + contone_align, dest_height, + width); } else { - /* Going left to right */ - penum->ht_landscape.curr_pos = 0; + /* Reset the whole buffer */ + penum->ht_landscape.count = 0; + if (penum->ht_landscape.index < 0) { + /* Going right to left */ + penum->ht_landscape.curr_pos = LAND_BITS-1; + } else { + /* Going left to right */ + penum->ht_landscape.curr_pos = 0; + } + penum->ht_landscape.num_contones = 0; + memset(&(penum->ht_landscape.widths[0]), 0, sizeof(int)*LAND_BITS); } - penum->ht_landscape.num_contones = 0; - memset(&(penum->ht_landscape.widths[0]), 0, sizeof(int)*LAND_BITS); } } break; diff --git a/gs/base/gxht_thresh.h b/gs/base/gxht_thresh.h index 88d0e1bf5..7f0f63153 100644 --- a/gs/base/gxht_thresh.h +++ b/gs/base/gxht_thresh.h @@ -36,5 +36,5 @@ int gxht_thresh_image_init(gx_image_enum *penum); int gxht_thresh_plane(gx_image_enum *penum, gx_ht_order *d_order, fixed xrun, int dest_width, int dest_height, byte *thresh_align, byte *contone_align, int contone_stride, - gx_device * dev, int plane_number); + gx_device * dev, int plane_number, bool allow_reset); #endif /* gshtx_INCLUDED */ diff --git a/gs/base/gxicolor.c b/gs/base/gxicolor.c index 90c5822f2..8e9f5d12b 100644 --- a/gs/base/gxicolor.c +++ b/gs/base/gxicolor.c @@ -405,7 +405,7 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat bool flush_buff = false; byte *psrc_temp; int offset_contone[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* to ensure 128 bit boundary */ - int offset_threshold[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* to ensure 128 bit boundary */ + int offset_threshold; /* to ensure 128 bit boundary */ gx_dda_int_t dda_ht; int code = 0; int spp_cm = 0; @@ -414,6 +414,7 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat int psrc_planestride = w/penum->spp; gx_color_value conc; int num_des_comp = penum->dev->color_info.num_components; + bool allow_reset; if (h != 0) { /* Get the buffer into the device color space */ @@ -455,13 +456,12 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat /* Can't do this earlier, as GC might move the buffers. */ vdi = penum->hci; contone_stride = penum->line_size; + offset_threshold = (- (((long)(penum->thresh_buffer)) + + penum->ht_offset_bits)) & 15; for (k = 0; k < spp_out; k ++) { offset_contone[k] = (- (((long)(penum->line)) + contone_stride * k + penum->ht_offset_bits)) & 15; - offset_threshold[k] = (- (((long)(penum->thresh_buffer)) + - contone_stride * vdi * k + - penum->ht_offset_bits)) & 15; } xrun = dda_current(penum->dda.pixel0.x); xrun = xrun - penum->adjust + (fixed_half - fixed_epsilon); @@ -473,7 +473,7 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat scale_factor = float2fixed_rounded((float) src_size / (float) (dest_width - 1)); #ifdef DEBUG /* Help in spotting problems */ - memset(penum->ht_buffer,0x00, penum->ht_stride * vdi * spp_out); + memset(penum->ht_buffer, 0x00, penum->ht_stride * vdi); #endif break; case image_landscape: @@ -483,12 +483,11 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat Can't do this earlier as GC may move the buffers. */ vdi = penum->wci; - contone_stride = penum->line_size; + contone_stride = penum->line_size; + offset_threshold = (-(long)(penum->thresh_buffer)) & 15; for (k = 0; k < spp_out; k ++) { offset_contone[k] = (- ((long)(penum->line) + contone_stride * k)) & 15; - offset_threshold[k] = (-((long)(penum->thresh_buffer) + - contone_stride * vdi * k)) & 15; } dest_width = fixed2int_var_rounded(any_abs(penum->y_extent.x)); dest_height = fixed2int_var_rounded(any_abs(penum->x_extent.y)); @@ -533,14 +532,22 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat /* For now we have 3 cases. A CMYK (4 channel), gray, or other case the latter of which is not yet implemented */ for (k = 0; k < spp_out; k++) { - devc_contone[k] = penum->line + contone_stride * k + offset_contone[k]; + if (posture == image_portrait) { + devc_contone[k] = penum->line + contone_stride * k + + offset_contone[k]; + } else { + devc_contone[k] = penum->line + offset_contone[k] + + LAND_BITS * k * contone_stride; + } psrc_plane[k] = psrc_cm + psrc_planestride * k; } switch (spp_out) { + /* Monochrome output case */ case 1: devc_contone_gray = devc_contone[0]; switch (posture) { + /* Monochrome portrait */ case image_portrait: if (penum->dst_width > 0) { if (scale_factor == fixed_1) { @@ -567,16 +574,17 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat } } break; + /* Monochrome landscape */ case image_landscape: /* We store the data at this point into a column. Depending upon our landscape direction we may be going left to right or right to left. */ if (penum->ht_landscape.flipy) { position = penum->ht_landscape.curr_pos + - 16 * (data_length - 1); + LAND_BITS * (data_length - 1); for (k = 0; k < data_length; k++) { devc_contone_gray[position] = psrc_cm[dda_ht.state.Q]; - position -= 16; + position -= LAND_BITS; dda_next(dda_ht); } } else { @@ -587,22 +595,22 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat if (scale_factor == fixed_1) { for (k = 0; k < data_length; k++) { devc_contone_gray[position] = psrc_cm[k]; - position += 16; + position += LAND_BITS; } } else if (scale_factor == fixed_half) { for (k = 0; k < data_length; k+=2) { offset = fixed2int_rounded(scale_factor * k); devc_contone_gray[position] = - devc_contone_gray[position + 16] = + devc_contone_gray[position + LAND_BITS] = psrc_cm[offset]; - position += 32; + position += 2*LAND_BITS; } } else { /* use dda */ for (k = 0; k < data_length; k++) { devc_contone_gray[position] = psrc_cm[dda_ht.state.Q]; - position += 16; + position += LAND_BITS; dda_next(dda_ht); } } @@ -619,8 +627,10 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat } break; + /* CMYK case */ case 4: switch (posture) { + /* CMYK portrait */ case image_portrait: if (penum->dst_width > 0) { if (scale_factor == fixed_1) { @@ -670,18 +680,21 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat } } break; + /* CMYK landscape */ case image_landscape: -#if 0 - /* THIS WILL NOT WORK YET */ - /* We store the data at this point into a column. Depending - upon our landscape direction we may be going left to right - or right to left. */ + /* Data is already color managed. */ + /* We store the data at this point into a columns in + seperate planes. Depending upon our landscape direction + we may be going left to right or right to left. */ if (penum->ht_landscape.flipy) { position = penum->ht_landscape.curr_pos + - 16 * (data_length - 1); + LAND_BITS * (data_length - 1); for (k = 0; k < data_length; k++) { - devc_contone[position] = psrc_cm[dda_ht.state.Q]; - position -= 16; + for (j = 0; j < spp_out; j++) { + *(devc_contone[j] + position) = + (psrc_plane[j])[dda_ht.state.Q]; + } + position -= LAND_BITS; dda_next(dda_ht); } } else { @@ -689,23 +702,38 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat /* Code up special cases for when we have no scaling and 2x scaling which we will run into in 300 and 600dpi devices and content */ + /* Apply initial offset */ + for (k = 0; k < spp_out; k++) { + devc_contone[k] = devc_contone[k] + position; + } if (scale_factor == fixed_1) { for (k = 0; k < data_length; k++) { - devc_contone[position] = psrc_cm[k]; - position += 16; + /* Is it better to unwind this? We know it is 4 */ + for (j = 0; j < spp_out; j++) { + *(devc_contone[j]) = (psrc_plane[j])[k]; + devc_contone[j] += LAND_BITS; + } } } else if (scale_factor == fixed_half) { for (k = 0; k < data_length; k+=2) { offset = fixed2int_rounded(scale_factor * k); - devc_contone[position] = - devc_contone[position + 16] = psrc_cm[offset]; - position += 32; + /* Is it better to unwind this? We know it is 4 */ + for (j = 0; j < spp_out; j++) { + *(devc_contone[j]) = + *(devc_contone[j] + LAND_BITS) = + (psrc_plane[j])[offset]; + devc_contone[j] += 2 * LAND_BITS; + } } } else { /* use dda */ for (k = 0; k < data_length; k++) { - devc_contone[position] = psrc_cm[dda_ht.state.Q]; - position += 16; + /* Is it better to unwind this? We know it is 4 */ + for (j = 0; j < spp_out; j++) { + *(devc_contone[j]) = + (psrc_plane[j])[dda_ht.state.Q]; + devc_contone[j] += LAND_BITS; + } dda_next(dda_ht); } } @@ -715,7 +743,6 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat penum->ht_landscape.widths[penum->ht_landscape.curr_pos] = vdi; penum->ht_landscape.curr_pos += penum->ht_landscape.index; penum->ht_landscape.num_contones++; -#endif break; default: /* error not allowed */ @@ -729,15 +756,25 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat /* Apply threshold array to image data. It may be neccessary to invert depnding upon the polarity of the device */ flush: + thresh_align = penum->thresh_buffer + offset_threshold; for (k = 0; k < spp_out; k++) { d_order = &(penum->pis->dev_ht->components[k].corder); - contone_align = penum->line + contone_stride * k + - offset_contone[k]; - thresh_align = penum->thresh_buffer + contone_stride * vdi * k + - offset_threshold[k]; + if (posture == image_portrait) { + contone_align = penum->line + contone_stride * k + + offset_contone[k]; + allow_reset = true; + } else { + contone_align = penum->line + offset_contone[k] + + LAND_BITS * k * contone_stride; + if (k == spp_out - 1) { + allow_reset = true; + } else { + allow_reset = false; + } + } code = gxht_thresh_plane(penum, d_order, xrun, dest_width, dest_height, - thresh_align, contone_align, contone_stride, - dev, k); + thresh_align, contone_align, + contone_stride, dev, k, allow_reset); } return code; } diff --git a/gs/base/gxidata.c b/gs/base/gxidata.c index e8b993e44..81e7c7d0c 100644 --- a/gs/base/gxidata.c +++ b/gs/base/gxidata.c @@ -476,12 +476,10 @@ gx_image1_end_image(gx_image_enum_common_t * info, bool draw_last) gs_free_object(mem, penum->color_cache, "image color cache"); } if (penum->thresh_buffer != NULL) { - gs_free_object(mem, penum->thresh_buffer, - "image thresh_buffer"); + gs_free_object(mem, penum->thresh_buffer, "image thresh_buffer"); } if (penum->ht_buffer != NULL) { - gs_free_object(mem, penum->ht_buffer, - "image ht_buffer"); + gs_free_object(mem, penum->ht_buffer, "image ht_buffer"); } if (penum->clues != NULL) { gs_free_object(mem,penum->clues, "image clues"); diff --git a/gs/base/gximono.c b/gs/base/gximono.c index c94bb8990..8a24a0c3f 100644 --- a/gs/base/gximono.c +++ b/gs/base/gximono.c @@ -40,6 +40,7 @@ #include "gscie.h" #include "gxht_thresh.h" #include "gxdda.h" +#include "gxdevsop.h" #define USE_FAST_CODE 1 #define fastfloor(x) (((int)(x)) - (((x)<0) && ((x) != (float)(int)(x)))) @@ -72,7 +73,10 @@ gs_image_class_3_mono(gx_image_enum * penum) gsicc_rendering_param_t rendering_params; int num_des_comps; cmm_dev_profile_t *dev_profile; - + bool dev_color_ok = false; + bool is_planar_dev = dev_proc(penum->dev, dev_spec_op)(penum->dev, + gxdso_is_native_planar, NULL, 0); + if (penum->spp == 1) { /* At this point in time, only use the ht approach if our device uses halftoning, and our source image is a reasonable size. We @@ -82,9 +86,14 @@ gs_image_class_3_mono(gx_image_enum * penum) to the limited precision and mismatch of the stepping space in which the interpolations occur this can cause a minor mismatch at large scalings */ - if (use_fast_code && penum->pcs != NULL && - penum->dev->color_info.num_components == 1 && - penum->dev->color_info.depth == 1 && + + /* Allow this for CMYK planar and mono binary halftoned devices */ + dev_color_ok = ((penum->dev->color_info.num_components == 1 && + penum->dev->color_info.depth == 1) || + (penum->dev->color_info.num_components == 4 && + penum->dev->color_info.depth == 4 && is_planar_dev)); + + if (use_fast_code && penum->pcs != NULL && dev_color_ok && penum->bps == 8 && (penum->posture == image_portrait || penum->posture == image_landscape) && penum->image_parent_type == gs_image_type1) { @@ -783,16 +792,18 @@ image_render_mono_ht(gx_image_enum * penum_orig, const byte * buffer, int data_x int dest_width, dest_height, data_length; byte *color_cache; gx_ht_order *d_order = &(penum->pis->dev_ht->components[0].corder); - int position, k; + int position, k, j; int offset_bits = penum->ht_offset_bits; int contone_stride = 0; /* Not used in landscape case */ fixed scale_factor, offset; int src_size; bool flush_buff = false; int offset_contone[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* to ensure 128 bit boundary */ - int offset_threshold[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* to ensure 128 bit boundary */ + int offset_threshold; /* to ensure 128 bit boundary */ gx_dda_int_t dda_ht; int code = 0; + bool allow_reset; + byte *dev_value; if (h == 0) { if (penum->ht_landscape.count == 0 || posture == image_portrait) { @@ -820,13 +831,12 @@ image_render_mono_ht(gx_image_enum * penum_orig, const byte * buffer, int data_x xrun += penum->x_extent.x; vdi = penum->hci; contone_stride = penum->line_size; + offset_threshold = (- (((long)(penum->thresh_buffer)) + + penum->ht_offset_bits)) & 15; for (k = 0; k < spp_out; k ++) { offset_contone[k] = (- (((long)(penum->line)) + contone_stride * k + penum->ht_offset_bits)) & 15; - offset_threshold[k] = (- (((long)(penum->thresh_buffer)) + - contone_stride * vdi * k + - penum->ht_offset_bits)) & 15; } data_length = dest_width; dest_height = fixed2int_var_rounded(any_abs(penum->y_extent.y)); @@ -843,15 +853,15 @@ image_render_mono_ht(gx_image_enum * penum_orig, const byte * buffer, int data_x Can't do this earlier as GC may move the buffers. */ vdi = penum->wci; + contone_stride = penum->line_size; dest_width = fixed2int_var_rounded(any_abs(penum->y_extent.x)); dest_height = fixed2int_var_rounded(any_abs(penum->x_extent.y)); data_length = dest_height; scale_factor = float2fixed_rounded((float) src_size / (float) (dest_height - 1)); + offset_threshold = (-(long)(penum->thresh_buffer)) & 15; for (k = 0; k < spp_out; k ++) { offset_contone[k] = (- ((long)(penum->line) + contone_stride * k)) & 15; - offset_threshold[k] = (-((long)(penum->thresh_buffer) + - contone_stride * vdi * k)) & 15; } /* In the landscaped case, we want to accumulate multiple columns of data before sending to the device. We want to have a full @@ -886,7 +896,13 @@ image_render_mono_ht(gx_image_enum * penum_orig, const byte * buffer, int data_x } /* Get the pointers to our buffers */ for (k = 0; k < spp_out; k++) { - devc_contone[k] = penum->line + offset_contone[k]; + if (posture == image_portrait) { + devc_contone[k] = penum->line + contone_stride * k + + offset_contone[k]; + } else { + devc_contone[k] = penum->line + offset_contone[k] + + LAND_BITS * k * contone_stride; + } } if (flush_buff) goto flush; /* All done */ /* Set up the dda. We could move this out but the cost is pretty small */ @@ -980,17 +996,19 @@ image_render_mono_ht(gx_image_enum * penum_orig, const byte * buffer, int data_x case image_portrait: if (penum->dst_width > 0) { if (spp_out == 1) { + /* Mono case */ for (k = 0; k < data_length; k++) { *devc_contone_gray++ = color_cache[psrc[dda_ht.state.Q]]; dda_next(dda_ht); } } else { - /* CMYK planar case: NEED TO FIX */ + /* CMYK case */ for (k = 0; k < data_length; k++) { - /* dev_value = color_cache + psrc[dda_ht.state.Q] * spp_out; - memcpy(devc_contone, dev_value, spp_out); - devc_contone += spp_out; - dda_next(dda_ht); */ + dev_value = color_cache + psrc[dda_ht.state.Q] * spp_out; + for (j = 0; j < spp_out; j++) { + *(devc_contone[j])++ = dev_value[j]; + } + dda_next(dda_ht); } } } else { @@ -1000,12 +1018,16 @@ image_render_mono_ht(gx_image_enum * penum_orig, const byte * buffer, int data_x dda_next(dda_ht); } } else { - /* CMYK planar case: NEED TO FIX */ + /* Move to the other end and we will decrement */ + for (j = 0; j < spp_out; j++) { + devc_contone[j] = devc_contone[j] + data_length - 1; + } for (k = 0; k < data_length; k++) { - /* dev_value = color_cache + psrc[dda_ht.state.Q] * spp_out; - memcpy(&(devc_contone[(data_length - k - 1) * spp_out]), - dev_value, spp_out); - dda_next(dda_ht); */ + dev_value = color_cache + psrc[dda_ht.state.Q] * spp_out; + for (j = 0; j < spp_out; j++) { + *(devc_contone[j])-- = dev_value[j]; + } + dda_next(dda_ht); } } } @@ -1025,30 +1047,39 @@ image_render_mono_ht(gx_image_enum * penum_orig, const byte * buffer, int data_x dda_next(dda_ht); } } else { - /* CMYK planar case: NEED TO FIX */ for (k = 0; k < data_length; k++) { - /* dev_value = color_cache + psrc[dda_ht.state.Q] * spp_out; - devc_contone[position] = dev_value[0]; + for (j = 0; j < spp_out; j++) { + *(devc_contone[j] + position) = + color_cache[psrc[dda_ht.state.Q] * spp_out + j]; + } position -= LAND_BITS; - dda_next(dda_ht); */ + dda_next(dda_ht); } } - } else { + } else { /* Not flipped in Y */ position = penum->ht_landscape.curr_pos; /* use dda */ if (spp_out == 1) { for (k = 0; k < data_length; k++) { - devc_contone_gray[position] = color_cache[psrc[dda_ht.state.Q]]; + devc_contone_gray[position] = + color_cache[psrc[dda_ht.state.Q]]; position += LAND_BITS; dda_next(dda_ht); } } else { - /* CMYK planar case: NEED TO FIX */ + /* CMYK case */ + /* Apply initial offset */ + for (k = 0; k < spp_out; k++) { + devc_contone[k] = devc_contone[k] + position; + } for (k = 0; k < data_length; k++) { - /* dev_value = color_cache + psrc[dda_ht.state.Q] * spp_out; - devc_contone[position] = dev_value[0]; - position += LAND_BITS; - dda_next(dda_ht); */ + /* Is it better to unwind this? We know it is 4 */ + for (j = 0; j < spp_out; j++) { + *(devc_contone[j]) = + color_cache[psrc[dda_ht.state.Q] * spp_out + j]; + devc_contone[j] += LAND_BITS; + } + dda_next(dda_ht); } } } @@ -1065,15 +1096,25 @@ image_render_mono_ht(gx_image_enum * penum_orig, const byte * buffer, int data_x } /* Apply threshold array to image data */ flush: + thresh_align = penum->thresh_buffer + offset_threshold; for (k = 0; k < spp_out; k++) { d_order = &(penum->pis->dev_ht->components[k].corder); - contone_align = penum->line + contone_stride * k + - offset_contone[k]; - thresh_align = penum->thresh_buffer + contone_stride * vdi * k + - offset_threshold[k]; + if (posture == image_portrait) { + contone_align = penum->line + contone_stride * k + + offset_contone[k]; + allow_reset = true; + } else { + contone_align = penum->line + offset_contone[k] + + LAND_BITS * k * contone_stride; + if (k == spp_out - 1) { + allow_reset = true; + } else { + allow_reset = false; + } + } code = gxht_thresh_plane(penum, d_order, xrun, dest_width, dest_height, thresh_align, contone_align, contone_stride, - dev, k); + dev, k, allow_reset); } return code; } diff --git a/gs/base/lib.mak b/gs/base/lib.mak index 317c1dbab..eefffe5fa 100644 --- a/gs/base/lib.mak +++ b/gs/base/lib.mak @@ -711,7 +711,7 @@ $(GLOBJ)gximono.$(OBJ) : $(GLSRC)gximono.c $(AK) $(gx_h) $(gserrors_h) $(memory_ $(gxarith_h) $(gxcmap_h) $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h)\ $(gxdevmem_h) $(gxfixed_h) $(gximage_h) $(gxistate_h) $(gxmatrix_h)\ $(gzht_h) $(vdtrace_h) $(gsicc_h) $(gsicc_cache_h) $(gsicc_cms_h)\ - $(gxcie_h) $(gscie_h) $(gxht_thresh_h) $(gxdda_h) + $(gxcie_h) $(gscie_h) $(gxht_thresh_h) $(gxdda_h) $(gxdevsop_h) $(GLCC) $(GLO_)gximono.$(OBJ) $(C_) $(GLSRC)gximono.c $(GLOBJ)gximask.$(OBJ) : $(GLSRC)gximask.c $(AK) $(gx_h) $(gserrors_h)\ |