[gs-commits] ghostpdl branch, master, updated. ghostpdl-9.02-753-g2780659
Michael Vrhel
mvrhel at ghostscript.com
Fri Nov 18 00:58:01 UTC 2011
The ghostpdl branch, master has been updated
via 27806596e3c2820064788bba903cc569ce89f1e7 (commit)
from aef9ee68391088d1c7e371a6f1e3fa4092688eae (commit)
----------------------------------------------------------------------
commit 27806596e3c2820064788bba903cc569ce89f1e7
Author: Michael Vrhel <michael.vrhel at artifex.com>
Date: Tue Nov 15 11:26:36 2011 -0800
Removal of WTS from code.
Plan is to suggest the use of screens generated with gs\toolbin\halftone\gen_ordered
diff --git a/gs/base/gdevdflt.c b/gs/base/gdevdflt.c
index 805b09b..feae182 100644
--- a/gs/base/gdevdflt.c
+++ b/gs/base/gdevdflt.c
@@ -378,7 +378,7 @@ set_linear_color_bits_mask_shift(gx_device * dev)
* a value of zero then the bits associated with that colorant are zero.
* These criteria allows the graphics library to build gx_color_index values
* from the colorant values and not using the encode_color routine. This is
- * useful and necessary for overprinting, the WTS screeening, halftoning more
+ * useful and necessary for overprinting, halftoning more
* than four colorants, and the fast shading logic. However this information
* is not setup by the default device macros. Thus we attempt to derive this
* information.
diff --git a/gs/base/gp.h b/gs/base/gp.h
index 8c15ea1..9c192fc 100644
--- a/gs/base/gp.h
+++ b/gs/base/gp.h
@@ -349,8 +349,6 @@ int gp_cache_query(int type, byte* key, int keylen, void **buffer,
/* cache data types */
#define GP_CACHE_TYPE_TEST 0
#define GP_CACHE_TYPE_FONTMAP 1
-#define GP_CACHE_TYPE_WTS_SIZE 2
-#define GP_CACHE_TYPE_WTS_CELL 3
/* ------ Printer accessing ------ */
diff --git a/gs/base/gsdcolor.h b/gs/base/gsdcolor.h
index 1728d0a..031851f 100644
--- a/gs/base/gsdcolor.h
+++ b/gs/base/gsdcolor.h
@@ -22,7 +22,6 @@
#include "gxbitmap.h"
#include "gxhttile.h"
#include "gxcindex.h"
-#include "gxwts.h"
#ifndef gx_device_color_DEFINED
# define gx_device_color_DEFINED
@@ -290,14 +289,6 @@ struct gx_device_color_s {
#endif
#endif
} colored;
- struct _wts {
- const gx_device_halftone *w_ht;
- wts_screen_sample_t levels[GX_DEVICE_COLOR_MAX_COMPONENTS];
- ushort num_components;
-
- /* plane_mask and base_color would be an optimization */
- gx_color_index plane_vector[GX_DEVICE_COLOR_MAX_COMPONENTS];
- } wts;
struct _pat {
gx_color_tile *p_tile;
} /*(colored) */ pattern;
@@ -385,9 +376,6 @@ struct gx_device_color_saved_s {
uint c_level[GX_DEVICE_COLOR_MAX_COMPONENTS];
ushort alpha;
} colored;
- struct _swts {
- wts_screen_sample_t levels[GX_DEVICE_COLOR_MAX_COMPONENTS];
- } wts;
struct _pattern {
gs_id id;
gs_int_point phase;
@@ -431,8 +419,5 @@ extern const gx_device_color_type_t *const gx_dc_type_ht_binary; /* gxht.c */
#ifndef gx_dc_type_ht_colored
extern const gx_device_color_type_t *const gx_dc_type_ht_colored; /* gxcht.c */
#endif
-#ifndef gx_dc_type_ht_colored
-extern const gx_device_color_type_t *const gx_dc_type_wts; /* gxwts.c */
-#endif
#endif /* gsdcolor_INCLUDED */
diff --git a/gs/base/gsdps1.c b/gs/base/gsdps1.c
index 4e4cae6..21a8fd4 100644
--- a/gs/base/gsdps1.c
+++ b/gs/base/gsdps1.c
@@ -211,8 +211,7 @@ gs_rectfill(gs_state * pgs, const gs_rect * pr, uint count)
(hl_color ||
pdc->type == gx_dc_type_pure ||
pdc->type == gx_dc_type_ht_binary ||
- pdc->type == gx_dc_type_ht_colored
- /* DeviceN todo: add wts case */) &&
+ pdc->type == gx_dc_type_ht_colored) &&
gs_state_color_load(pgs) >= 0 &&
(*dev_proc(pdev, get_alpha_bits)) (pdev, go_graphics)
<= 1 &&
diff --git a/gs/base/gsht.c b/gs/base/gsht.c
index 4c80366..7517ee7 100644
--- a/gs/base/gsht.c
+++ b/gs/base/gsht.c
@@ -24,7 +24,6 @@
#include "gzstate.h"
#include "gxdevice.h" /* for gzht.h */
#include "gzht.h"
-#include "gswts.h"
#include "gxfmap.h" /* For effective transfer usage in threshold */
#define TRANSFER_INVERSE_SIZE 1024
@@ -48,19 +47,6 @@ static const uint32_t bit_order[32]={
/* Forward declarations */
void gx_set_effective_transfer(gs_state *);
-/*
- * *HACK ALERT*
- *
- * Value stored in the width field of a well-tempered screen halftone
- * order, to indicate that the wts field of this order points to the
- * same structure as an earlier order. This is used to suppress
- * multiple realeases of shared wts_screen_t orders.
- *
- * The width field is available for this purpose at it is nominally
- * unused in a well-tempered screening halftone.
- */
-static const ushort ht_wts_suppress_release = (ushort)(-1);
-
/* Structure types */
public_st_ht_order();
private_st_ht_order_component();
@@ -285,17 +271,12 @@ gx_ht_process_screen_memory(gs_screen_enum * penum, gs_state * pgs,
* Internal procedure to allocate and initialize either an internally
* generated or a client-defined halftone order. For spot halftones,
* the client is responsible for calling gx_compute_cell_values.
- *
- * Note: this function is used for old-style halftones only. WTS
- * halftones are allocated in gs_sethalftone_try_wts().
*/
int
gx_ht_alloc_ht_order(gx_ht_order * porder, uint width, uint height,
uint num_levels, uint num_bits, uint strip_shift,
const gx_ht_order_procs_t *procs, gs_memory_t * mem)
{
- porder->wse = NULL;
- porder->wts = NULL;
porder->threshold = NULL;
porder->width = width;
porder->height = height;
@@ -356,8 +337,6 @@ gx_ht_copy_ht_order(gx_ht_order * pdest, gx_ht_order * psrc, gs_memory_t * mem)
if (pdest->bit_data != 0)
memcpy(pdest->bit_data, psrc->bit_data,
psrc->num_bits * psrc->procs->bit_data_elt_size);
- pdest->wse = psrc->wse;
- pdest->wts = psrc->wts;
pdest->transfer = psrc->transfer;
rc_increment(pdest->transfer);
return 0;
@@ -373,8 +352,6 @@ gx_ht_move_ht_order(gx_ht_order * pdest, gx_ht_order * psrc)
uint width = psrc->width, height = psrc->height, shift = psrc->shift;
pdest->params = psrc->params;
- pdest->wse = psrc->wse;
- pdest->wts = 0;
pdest->width = width;
pdest->height = height;
pdest->raster = bitmap_raster(width);
@@ -602,13 +579,8 @@ gx_ht_order_release(gx_ht_order * porder, gs_memory_t * mem, bool free_cache)
if (free_cache) {
if (porder->cache != 0)
gx_ht_free_cache(mem, porder->cache);
- else if (porder->wse != 0)
- gs_wts_free_enum(porder->wse);
}
porder->cache = 0;
- if (porder->wts != 0 && porder->width != ht_wts_suppress_release)
- gs_wts_free_screen(porder->wts);
- porder->wts = 0;
rc_decrement(porder->transfer, "gx_ht_order_release(transfer)");
porder->transfer = 0;
if (porder->data_memory != 0) {
@@ -867,18 +839,6 @@ gs_cname_to_colorant_number(gs_state * pgs, byte * pname, uint name_size,
* operand device halftone; it is not set in the device
* halftone in the imager state.
*
- * wse Points to an "enumerator" instance, used to construct
- * a well-tempered screen. This is only required while
- * the well-tempered screen is being constructed. This
- * field is always a null pointer in the device halftone
- * in the imager state.
- *
- * wts Points to the "constructed" form of a well-tempered
- * screen. The "construction" operation occurs as part
- * of the installation process. Hence, this should
- * always be a null pointer in the operand device
- * halftone.
- *
* orig_height, The height and shift values of the halftone cell,
* orig_shift prior to any replication. These fields are currently
* unused, and will always be the same as the height
@@ -996,9 +956,9 @@ gx_imager_dev_ht_install(
int i, code = 0;
bool used_default = false;
int lcm_width = 1, lcm_height = 1;
- gs_wts_screen_enum_t * wse0 = pdht->order.wse;
- wts_screen_t * wts0 = 0;
bool mem_diff = pdht->rc.memory != pis->memory;
+ uint w, h;
+ int dw, dh;
/* construct the new device halftone structure */
memset(&dht.order, 0, sizeof(dht.order));
@@ -1063,37 +1023,10 @@ gx_imager_dev_ht_install(
/*
* Copy the default order to any remaining components.
- *
- * For well-tempered screens, generate the wts_screen_t structure
- * for each component that corresponds to the sample information
- * that has been gathered.
- *
- * Some caution is necessary here, as multiple component orders may
- * have wse fields pointing to the same gs_wts_creeen_enum_t
- * structure. This structure should only be released once. If
- * multiple components have such a wse value, it will be the same as
- * pdht->order.wse pointer, so we can just release that pointer once
- * when done.
- *
- * If serveral component orders have the same wse value, this code
- * will create just one wts_screen_t structure. In a somewhat ugly
- * hack, the width field (which is otherwise unused) will be set to
- * 0xffff for all components other than the first component that
- * makes use of a give wts_screen_t structure. gx_ht_order_release
- * will check this field to see if it should release the structure
- * pointed to by the wts field of a component order.
- *
- * Components that are not well-tempered screens require a cache.
- * In practice, either all or non of the components will be well-
- * tempered screens, but we ignore that fact here.
- *
- * While engaged in all of these other activities, also calculate
- * the lcm_width and lcm_heigth values (only for non-well-tempered
- * components).
*/
+
for (i = 0; i < num_comps && code >= 0; i++) {
- gx_ht_order * porder = &dht.components[i].corder;
- gs_wts_screen_enum_t * wse;
+ gx_ht_order *porder = &dht.components[i].corder;
if (dht.components[i].comp_number != i) {
if (used_default || mem_diff)
@@ -1104,61 +1037,44 @@ gx_imager_dev_ht_install(
}
dht.components[i].comp_number = i;
}
- if ((wse = porder->wse) != 0) {
- wts_screen_t * wts = 0;
-
- porder->width = 0;
- porder->wse = 0;
- if (wse != wse0)
- wts = wts_screen_from_enum(wse);
- else {
- if (wts0 == 0)
- wts0 = wts_screen_from_enum(wse);
- else
- porder->width = ht_wts_suppress_release;
- wts = wts0;
- }
- if (wts == 0)
+
+ w = porder->width;
+ h = porder->full_height;
+ dw = igcd(lcm_width, w);
+ dh = igcd(lcm_height, h);
+
+ lcm_width /= dw;
+ lcm_height /= dh;
+ lcm_width = (w > max_int / lcm_width ? max_int : lcm_width * w);
+ lcm_height = (h > max_int / lcm_height ? max_int : lcm_height * h);
+
+ if (porder->cache == 0) {
+ uint tile_bytes, num_tiles, slots_wanted, rep_raster, rep_count;
+ gx_ht_cache * pcache;
+
+ tile_bytes = porder->raster
+ * (porder->num_bits / porder->width);
+ num_tiles = 1 + gx_ht_cache_default_bits_size() / tile_bytes;
+ /*
+ * Limit num_tiles to a reasonable number allowing for width repition.
+ * The most we need is one cache slot per bit.
+ * This prevents allocations of large cache bits that will never
+ * be used. See rep_count limit in gxht.c
+ */
+ slots_wanted = 1 + ( porder->width * porder->height );
+ rep_raster = ((num_tiles*tile_bytes) / porder->height /
+ slots_wanted) & ~(align_bitmap_mod - 1);
+ rep_count = rep_raster * 8 / porder->width;
+ if (rep_count > sizeof(ulong) * 8 && (num_tiles >
+ 1 + ((num_tiles * 8 * sizeof(ulong)) / rep_count) ))
+ num_tiles = 1 + ((num_tiles * 8 * sizeof(ulong)) / rep_count);
+ pcache = gx_ht_alloc_cache( pis->memory, num_tiles,
+ tile_bytes * num_tiles );
+ if (pcache == NULL)
code = gs_error_VMerror;
- else
- porder->wts = wts;
- } else if (porder->wts == 0) {
- uint w = porder->width, h = porder->full_height;
- int dw = igcd(lcm_width, w), dh = igcd(lcm_height, h);
-
- lcm_width /= dw;
- lcm_height /= dh;
- lcm_width = (w > max_int / lcm_width ? max_int : lcm_width * w);
- lcm_height = (h > max_int / lcm_height ? max_int : lcm_height * h);
-
- if (porder->cache == 0) {
- uint tile_bytes, num_tiles, slots_wanted, rep_raster, rep_count;
- gx_ht_cache * pcache;
-
- tile_bytes = porder->raster
- * (porder->num_bits / porder->width);
- num_tiles = 1 + gx_ht_cache_default_bits_size() / tile_bytes;
- /*
- * Limit num_tiles to a reasonable number allowing for width repition.
- * The most we need is one cache slot per bit.
- * This prevents allocations of large cache bits that will never
- * be used. See rep_count limit in gxht.c
- */
- slots_wanted = 1 + ( porder->width * porder->height );
- rep_raster = ((num_tiles*tile_bytes) / porder->height /
- slots_wanted) & ~(align_bitmap_mod - 1);
- rep_count = rep_raster * 8 / porder->width;
- if (rep_count > sizeof(ulong) * 8 && (num_tiles >
- 1 + ((num_tiles * 8 * sizeof(ulong)) / rep_count) ))
- num_tiles = 1 + ((num_tiles * 8 * sizeof(ulong)) / rep_count);
- pcache = gx_ht_alloc_cache( pis->memory, num_tiles,
- tile_bytes * num_tiles );
- if (pcache == NULL)
- code = gs_error_VMerror;
- else {
- porder->cache = pcache;
- gx_ht_init_cache(pis->memory, pcache, porder);
- }
+ else {
+ porder->cache = pcache;
+ gx_ht_init_cache(pis->memory, pcache, porder);
}
}
}
@@ -1203,8 +1119,7 @@ gx_imager_dev_ht_install(
/*
* Everything worked. "Assume ownership" of the appropriate
* portions of the source device halftone by clearing the
- * associated references. This includes explicitly releasing
- * any gs_wts_screen_enum_t structures. Since we might have
+ * associated references. Since we might have
* pdht == pis->dev_ht, this must done before updating pis->dev_ht.
*
* If the default order has been used for a device component, and
@@ -1224,8 +1139,6 @@ gx_imager_dev_ht_install(
if ( comp_num >= 0 &&
comp_num < GX_DEVICE_COLOR_MAX_COMPONENTS ) {
- if (p_s_order->wse != 0)
- gs_wts_free_enum(p_s_order->wse);
memset(p_s_order, 0, sizeof(*p_s_order));
} else if ( comp_num == GX_DEVICE_COLOR_MAX_COMPONENTS &&
used_default )
@@ -1233,8 +1146,6 @@ gx_imager_dev_ht_install(
}
}
if (used_default) {
- if (wse0 != 0)
- gs_wts_free_enum(wse0);
memset(&pdht->order, 0, sizeof(pdht->order));
}
diff --git a/gs/base/gsht1.c b/gs/base/gsht1.c
index c9cf766..4ae8903 100644
--- a/gs/base/gsht1.c
+++ b/gs/base/gsht1.c
@@ -23,8 +23,6 @@
#include "gxdevice.h" /* for gzht.h */
#include "gzht.h"
-#include "gxwts.h"
-#include "gswts.h"
/* Imports from gscolor.c */
void load_transfer_map(gs_state *, gx_transfer_map *, floatp);
@@ -38,9 +36,6 @@ static int process_threshold2(gx_ht_order *, gs_state *,
gs_threshold2_halftone *, gs_memory_t *);
static int process_client_order(gx_ht_order *, gs_state *,
gs_client_order_halftone *, gs_memory_t *);
-static int
-gs_sethalftone_try_wts(gs_halftone *pht, gs_state *pgs,
- gx_device_halftone *pdht);
/* Structure types */
public_st_halftone_component();
@@ -172,9 +167,6 @@ gs_sethalftone_prepare(gs_state * pgs, gs_halftone * pht,
gx_ht_order_component *pocs = 0;
int code = 0;
- if (gs_currentusewts(mem) && gs_sethalftone_try_wts(pht, pgs, pdht) == 0)
- return 0;
-
switch (pht->type) {
case ht_type_colorscreen:
{
@@ -548,132 +540,3 @@ process_client_order(gx_ht_order * porder, gs_state * pgs,
return process_transfer(porder, pgs, NULL,
&phcop->transfer_closure, mem);
}
-
-static const gx_ht_order_procs_t wts_order_procs = { 0
-};
-
-/**
- * gs_sethalftone_try_wts: Try creating a wts-based device halftone.
- * @pht: Client halftone.
- * @pdht: Device halftone to initialize.
- *
- * Tries initializing @pdht based on data from @pht, using WTS.
- *
- * Return value: 0 on success, 1 to indicate that the initialization
- * was not done, and that the legacy initialization code path should
- * be used.
- **/
-static int
-gs_sethalftone_try_wts(gs_halftone *pht, gs_state *pgs,
- gx_device_halftone *pdht)
-{
- gx_device *dev = pgs->device;
- int num_comps = dev->color_info.num_components;
- int depth = dev->color_info.depth;
-
- if (pht->type != ht_type_multiple)
- /* Only work with Type 5 halftones. todo: we probably want
- to relax this. */
- return 1;
-
- if_debug2('h', "[h]%s, num_comp = %d\n",
- dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN ? "Separable and linear" : "Not separable and linear!",
- pht->params.multiple.num_comp);
-
- if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN &&
- pht->params.multiple.num_comp > 1)
- /* WTS is only enabled for separable or monochrome devices. */
- return 1;
-
- /* only work with bilevel (not multilevel) devices */
- if (depth > num_comps) {
- if (depth >= 2 * num_comps)
- return 1;
- if (dev->color_info.gray_index != GX_CINFO_COMP_NO_INDEX &&
- (dev->color_info.max_gray > 1 ||
- (num_comps > 1 && dev->color_info.max_color > 1)))
- return 1;
- }
-
- if (pht->type == ht_type_multiple) {
- gs_halftone_component *components = pht->params.multiple.components;
- uint num_comp = pht->params.multiple.num_comp;
- int i;
- gx_ht_order_component *pocs;
- gx_ht_order_component *poc_next;
- int code = 0;
- bool have_Default = false;
-
- for (i = 0; i < num_comp; i++) {
- if (components[i].type != ht_type_spot)
- return 1;
- else {
- gs_spot_halftone *spot = &components[i].params.spot;
- if (!spot->accurate_screens)
- return 1;
- }
- }
-
- pocs = gs_alloc_struct_array( pgs->memory,
- num_comp,
- gx_ht_order_component,
- &st_ht_order_component_element,
- "gs_sethalftone_try_wts" );
- /* pocs = malloc(num_comp * sizeof(gx_ht_order_component)); */
- poc_next = &pocs[1];
- for (i = 0; i < num_comp; i++) {
- gs_halftone_component *component = &components[i];
- gs_spot_halftone *spot = &component->params.spot;
- gs_screen_halftone *h = &spot->screen;
- gx_wts_cell_params_t *wcp;
- gs_wts_screen_enum_t *wse;
- gs_matrix imat;
- gx_ht_order_component *poc;
-
- if (component->comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS) {
- if (have_Default) {
- /* Duplicate Default */
- code = gs_note_error(gs_error_rangecheck);
- break;
- }
- poc = pocs;
- have_Default = true;
- } else if (i == num_comp - 1 && !have_Default) {
- /* No Default */
- code = gs_note_error(gs_error_rangecheck);
- break;
- } else
- poc = poc_next++;
-
- gs_deviceinitialmatrix(gs_currentdevice(pgs), &imat);
-
- wcp = wts_pick_cell_size(h, &imat);
- wse = gs_wts_screen_enum_new(wcp);
-
- poc->corder.wse = wse;
- poc->corder.wts = NULL;
- poc->corder.procs = &wts_order_procs;
- poc->corder.data_memory = NULL;
- poc->corder.num_levels = 0;
- poc->corder.num_bits = 0;
- poc->corder.levels = NULL;
- poc->corder.bit_data = NULL;
- poc->corder.cache = NULL;
- poc->corder.transfer = NULL;
- poc->comp_number = component->comp_number;
- poc->cname = component->cname;
- code = process_transfer( &poc->corder,
- pgs,
- spot->transfer,
- &spot->transfer_closure,
- pgs->memory );
- if (code < 0)
- break;
- }
- /* todo: cleanup on error */
- pdht->components = pocs;
- pdht->num_comp = num_comp;
- return code;
- }
- return 1;
-}
diff --git a/gs/base/gshtscr.c b/gs/base/gshtscr.c
index 47bbef1..4f5b216 100644
--- a/gs/base/gshtscr.c
+++ b/gs/base/gshtscr.c
@@ -21,7 +21,6 @@
#include "gzstate.h"
#include "gxdevice.h" /* for gzht.h */
#include "gzht.h"
-#include "gswts.h"
/* Define whether to force all halftones to be strip halftones, */
/* for debugging. */
@@ -73,22 +72,6 @@ gs_currentaccuratescreens(gs_memory_t *mem)
}
void
-gs_setusewts(gs_memory_t *mem, bool use_wts)
-{
- gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem);
-
- ctx->screen_use_wts = use_wts;
-}
-
-bool
-gs_currentusewts(gs_memory_t *mem)
-{
- gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem);
-
- return ctx->screen_use_wts;
-}
-
-void
gs_setminscreenlevels(gs_memory_t *mem, uint levels)
{
gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem);
@@ -492,46 +475,44 @@ gs_screen_enum_init_memory(gs_screen_enum * penum, const gx_ht_order * porder,
penum->halftone.params.screen = *phsp;
penum->x = penum->y = 0;
- if (porder->wse == NULL) {
- penum->strip = porder->num_levels / porder->width;
- penum->shift = porder->shift;
- /*
- * We want a transformation matrix that maps the parallelogram
- * (0,0), (U,V), (U-V',V+U'), (-V',U') to the square (+/-1, +/-1).
- * If the coefficients are [a b c d e f] and we let
- * u = U = M/R, v = V = N/R,
- * r = -V' = -N'/R', s = U' = M'/R',
- * then we just need to solve the equations:
- * a*0 + c*0 + e = -1 b*0 + d*0 + f = -1
- * a*u + c*v + e = 1 b*u + d*v + f = 1
- * a*r + c*s + e = -1 b*r + d*s + f = 1
- * This has the following solution:
- * Q = 2 / (M*M' + N*N')
- * a = Q * R * M'
- * b = -Q * R' * N
- * c = Q * R * N'
- * d = Q * R' * M
- * e = -1
- * f = -1
- */
- {
- const int M = porder->params.M, N = porder->params.N, R = porder->params.R;
- const int M1 = porder->params.M1, N1 = porder->params.N1, R1 = porder->params.R1;
- double Q = 2.0 / ((long)M * M1 + (long)N * N1);
+ penum->strip = porder->num_levels / porder->width;
+ penum->shift = porder->shift;
+ /*
+ * We want a transformation matrix that maps the parallelogram
+ * (0,0), (U,V), (U-V',V+U'), (-V',U') to the square (+/-1, +/-1).
+ * If the coefficients are [a b c d e f] and we let
+ * u = U = M/R, v = V = N/R,
+ * r = -V' = -N'/R', s = U' = M'/R',
+ * then we just need to solve the equations:
+ * a*0 + c*0 + e = -1 b*0 + d*0 + f = -1
+ * a*u + c*v + e = 1 b*u + d*v + f = 1
+ * a*r + c*s + e = -1 b*r + d*s + f = 1
+ * This has the following solution:
+ * Q = 2 / (M*M' + N*N')
+ * a = Q * R * M'
+ * b = -Q * R' * N
+ * c = Q * R * N'
+ * d = Q * R' * M
+ * e = -1
+ * f = -1
+ */
+ {
+ const int M = porder->params.M, N = porder->params.N, R = porder->params.R;
+ const int M1 = porder->params.M1, N1 = porder->params.N1, R1 = porder->params.R1;
+ double Q = 2.0 / ((long)M * M1 + (long)N * N1);
- penum->mat.xx = Q * (R * M1);
- penum->mat.xy = Q * (-R1 * N);
- penum->mat.yx = Q * (R * N1);
- penum->mat.yy = Q * (R1 * M);
- penum->mat.tx = -1.0;
- penum->mat.ty = -1.0;
- gs_matrix_invert(&penum->mat, &penum->mat_inv);
- }
- if_debug7('h', "[h]Screen: (%dx%d)/%d [%f %f %f %f]\n",
- porder->width, porder->height, porder->params.R,
- penum->mat.xx, penum->mat.xy,
- penum->mat.yx, penum->mat.yy);
+ penum->mat.xx = Q * (R * M1);
+ penum->mat.xy = Q * (-R1 * N);
+ penum->mat.yx = Q * (R * N1);
+ penum->mat.yy = Q * (R1 * M);
+ penum->mat.tx = -1.0;
+ penum->mat.ty = -1.0;
+ gs_matrix_invert(&penum->mat, &penum->mat_inv);
}
+ if_debug7('h', "[h]Screen: (%dx%d)/%d [%f %f %f %f]\n",
+ porder->width, porder->height, porder->params.R,
+ penum->mat.xx, penum->mat.xy,
+ penum->mat.yx, penum->mat.yy);
return 0;
}
@@ -544,12 +525,6 @@ gs_screen_currentpoint(gs_screen_enum * penum, gs_point * ppt)
double sx, sy; /* spot center in spot coords (integers) */
gs_point spot_center; /* device coords */
- if (penum->order.wse) {
- int code;
- code = gs_wts_screen_enum_currentpoint(penum->order.wse, ppt);
- return code;
- }
-
if (penum->y >= penum->strip) { /* all done */
gx_ht_construct_spot_order(&penum->order);
return 1;
@@ -594,30 +569,26 @@ gs_screen_currentpoint(gs_screen_enum * penum, gs_point * ppt)
int
gs_screen_next(gs_screen_enum * penum, floatp value)
{
- if (penum->order.wse) {
- return gs_wts_screen_enum_next (penum->order.wse, value);
- } else {
- ht_sample_t sample;
- int width = penum->order.width;
- gx_ht_bit *bits = (gx_ht_bit *)penum->order.bit_data;
+ ht_sample_t sample;
+ int width = penum->order.width;
+ gx_ht_bit *bits = (gx_ht_bit *)penum->order.bit_data;
- if (value < -1.0 || value > 1.0)
- return_error(gs_error_rangecheck);
- sample = (ht_sample_t) ((value + 1) * max_ht_sample);
+ if (value < -1.0 || value > 1.0)
+ return_error(gs_error_rangecheck);
+ sample = (ht_sample_t) ((value + 1) * max_ht_sample);
#ifdef DEBUG
- if (gs_debug_c('H')) {
- gs_point pt;
+ if (gs_debug_c('H')) {
+ gs_point pt;
- gs_screen_currentpoint(penum, &pt);
- dlprintf6("[H]sample x=%d y=%d (%f,%f): %f -> %u\n",
- penum->x, penum->y, pt.x, pt.y, value, sample);
- }
+ gs_screen_currentpoint(penum, &pt);
+ dlprintf6("[H]sample x=%d y=%d (%f,%f): %f -> %u\n",
+ penum->x, penum->y, pt.x, pt.y, value, sample);
+ }
#endif
- bits[penum->y * width + penum->x].mask = sample;
- if (++(penum->x) >= width)
- penum->x = 0, ++(penum->y);
- return 0;
- }
+ bits[penum->y * width + penum->x].mask = sample;
+ if (++(penum->x) >= width)
+ penum->x = 0, ++(penum->y);
+ return 0;
}
/* Install a fully constructed screen in the gstate. */
diff --git a/gs/base/gslibctx.h b/gs/base/gslibctx.h
index 17dcc2e..ebc48ac 100644
--- a/gs/base/gslibctx.h
+++ b/gs/base/gslibctx.h
@@ -55,7 +55,6 @@ typedef struct gs_lib_ctx_s
/* Define the default value of AccurateScreens that affects setscreen
and setcolorscreen. */
bool screen_accurate_screens;
- bool screen_use_wts;
uint screen_min_screen_levels;
/* real time clock 'bias' value. Not strictly required, but some FTS
* tests work better if realtime starts from 0 at boot time. */
diff --git a/gs/base/gswts.c b/gs/base/gswts.c
deleted file mode 100644
index 854e880..0000000
--- a/gs/base/gswts.c
+++ /dev/null
@@ -1,1624 +0,0 @@
-/* Copyright (C) 2001-2006 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-/*$Id$ */
-/* Screen generation for Well Tempered Screening. */
-#include "stdpre.h"
-#include <stdlib.h> /* for malloc */
-#include "gx.h"
-#include "gp.h" /* for persistent cache */
-#include "gxstate.h"
-#include "gsht.h"
-#include "math_.h"
-#include "string_.h"
-#include "gserrors.h"
-#include "gxfrac.h"
-#include "gxwts.h"
-#include "gswts.h"
-
-#define noDUMP_WTS
-#ifdef DUMP_WTS
-#include "fcntl_.h"
-#endif
-
-#define noVERBOSE
-
-#ifdef UNIT_TEST
-/**
- * This file can be compiled independently for unit testing purposes.
- * Try this invocation:
- *
- * gcc -I../obj -DUNIT_TEST gswts.c gxwts.c -o test_gswts -lm
- * ./test_gswts | sed '/P5/,$!d' | xv -
- **/
-#undef printf
-#undef stdout
-#undef dlprintf1
-#define dlprintf1 printf
-#undef dlprintf2
-#define dlprintf2 printf
-#undef dlprintf3
-#define dlprintf3 printf
-#undef dlprintf4
-#define dlprintf4 printf
-#undef dlprintf5
-#define dlprintf5 printf
-#undef dlprintf6
-#define dlprintf6 printf
-#undef dlprintf7
-#define dlprintf7 printf
-
-#endif
-
-/* A datatype used for representing the product of two 32 bit integers.
- If a 64 bit integer type is available, it may be a better choice. */
-typedef double wts_bigint;
-
-typedef struct gx_wts_cell_params_j_s gx_wts_cell_params_j_t;
-typedef struct gx_wts_cell_params_h_s gx_wts_cell_params_h_t;
-
-struct gx_wts_cell_params_j_s {
- gx_wts_cell_params_t base;
- int shift;
-
- double ufast_a;
- double vfast_a;
- double uslow_a;
- double vslow_a;
-
- /* Probabilities of "jumps". A and B jumps can happen when moving
- one pixel to the right. C and D can happen when moving one pixel
- down. */
- double pa;
- double pb;
- double pc;
- double pd;
-
- int xa;
- int ya;
- int xb;
- int yb;
- int xc;
- int yc;
- int xd;
- int yd;
-};
-
-struct gx_wts_cell_params_h_s {
- gx_wts_cell_params_t base;
-
- /* This is the exact value that x1 and (width-x1) approximates. */
- double px;
- /* Ditto y1 and (height-y1). */
- double py;
-
- int x1;
- int y1;
-};
-
-#define WTS_EXTRA_SORT_BITS 9
-#define WTS_SORTED_MAX (((frac_1) << (WTS_EXTRA_SORT_BITS)) - 1)
-
-typedef struct {
- int u;
- int v;
- int k;
- int l;
-} wts_vec_t;
-
-static void
-wts_vec_set(wts_vec_t *wv, int u, int v, int k, int l)
-{
- wv->u = u;
- wv->v = v;
- wv->k = k;
- wv->l = l;
-}
-
-static wts_bigint
-wts_vec_smag(const wts_vec_t *a)
-{
- wts_bigint u = a->u;
- wts_bigint v = a->v;
- return u * u + v * v;
-}
-
-static void
-wts_vec_add(wts_vec_t *a, const wts_vec_t *b, const wts_vec_t *c)
-{
- a->u = b->u + c->u;
- a->v = b->v + c->v;
- a->k = b->k + c->k;
- a->l = b->l + c->l;
-}
-
-static void
-wts_vec_sub(wts_vec_t *a, const wts_vec_t *b, const wts_vec_t *c)
-{
- a->u = b->u - c->u;
- a->v = b->v - c->v;
- a->k = b->k - c->k;
- a->l = b->l - c->l;
-}
-
-/**
- * wts_vec_gcd3: Compute 3-way "gcd" of three vectors.
- * @a, @b, @c: Vectors.
- *
- * Compute pair of vectors satisfying three constraints:
- * They are integer combinations of the source vectors.
- * The source vectors are integer combinations of the results.
- * The magnitude of the vectors is minimized.
- *
- * The algorithm for this computation is quite reminiscent of the
- * classic Euclid GCD algorithm for integers.
- *
- * On return, @a and @b contain the result. @c is destroyed.
- **/
-static void
-wts_vec_gcd3(wts_vec_t *a, wts_vec_t *b, wts_vec_t *c)
-{
- wts_vec_t d, e;
- double ra, rb, rc, rd, re;
-
- wts_vec_set(&d, 0, 0, 0, 0);
- wts_vec_set(&e, 0, 0, 0, 0);
- for (;;) {
- ra = wts_vec_smag(a);
- rb = wts_vec_smag(b);
- rc = wts_vec_smag(c);
- wts_vec_sub(&d, a, b);
- wts_vec_add(&e, a, b);
- rd = wts_vec_smag(&d);
- re = wts_vec_smag(&e);
- if (re && re < rd) {
- d = e;
- rd = re;
- }
- if (rd && rd < ra && ra >= rb) *a = d;
- else if (rd < rb && rb > ra) *b = d;
- else {
- wts_vec_sub(&d, a, c);
- wts_vec_add(&e, a, c);
- rd = wts_vec_smag(&d);
- re = wts_vec_smag(&e);
- if (re < rd) {
- d = e;
- rd = re;
- }
- if (rd && rd < ra && ra >= rc) *a = d;
- else if (rd < rc && rc > ra) *c = d;
- else {
- wts_vec_sub(&d, b, c);
- wts_vec_add(&e, b, c);
- rd = wts_vec_smag(&d);
- re = wts_vec_smag(&e);
- if (re < rd) {
- d = e;
- rd = re;
- }
- if (rd && rd < rb && rb >= rc) *b = d;
- else if (rd < rc && rc > rb) *c = d;
- else
- break;
- }
- }
- }
-}
-
-static wts_bigint
-wts_vec_cross(const wts_vec_t *a, const wts_vec_t *b)
-{
- wts_bigint au = a->u;
- wts_bigint av = a->v;
- wts_bigint bu = b->u;
- wts_bigint bv = b->v;
- return au * bv - av * bu;
-}
-
-static void
-wts_vec_neg(wts_vec_t *a)
-{
- a->u = -a->u;
- a->v = -a->v;
- a->k = -a->k;
- a->l = -a->l;
-}
-
-/* compute k mod m */
-static void
-wts_vec_modk(wts_vec_t *a, int m)
-{
- while (a->k < 0) a->k += m;
- while (a->k >= m) a->k -= m;
-}
-
-/* Compute modulo in rational cell. */
-static void
-wts_vec_modkls(wts_vec_t *a, int m, int i, int s)
-{
- while (a->l < 0) {
- a->l += i;
- a->k -= s;
- }
- while (a->l >= i) {
- a->l -= i;
- a->k += s;
- }
- while (a->k < 0) a->k += m;
- while (a->k >= m) a->k -= m;
-}
-
-static void
-wts_set_mat(gx_wts_cell_params_t *wcp, double sratiox, double sratioy,
- double sangledeg)
-{
- double sangle = sangledeg * M_PI / 180;
-
- wcp->ufast = cos(sangle) / sratiox;
- wcp->vfast = -sin(sangle) / sratiox;
- wcp->uslow = sin(sangle) / sratioy;
- wcp->vslow = cos(sangle) / sratioy;
-}
-
-/**
- * Calculate Screen H cell sizes.
- **/
-static void
-wts_cell_calc_h(double inc, int *px1, int *pxwidth, double *pp1, double memw)
-{
- double minrep = pow(2, memw) * 50 / pow(2, 7.5);
- int m1 = 0, m2 = 0;
- double e1, e2;
-
- int uacc;
-
- e1 = 1e5;
- e2 = 1e5;
- for (uacc = (int)ceil(minrep * inc); uacc <= floor(2 * minrep * inc); uacc++) {
- int mt;
- double et;
-
- mt = (int)floor(uacc / inc + 1e-5);
- et = uacc / inc - mt + mt * 0.001;
- if (et < e1) {
- e1 = et;
- m1 = mt;
- }
- mt = (int)ceil(uacc / inc - 1e-5);
- et = mt - uacc / inc + mt * 0.001;
- if (et < e2) {
- e2 = et;
- m2 = mt;
- }
- }
- if (m1 == m2) {
- *px1 = m1;
- *pxwidth = m1;
- *pp1 = 1.0;
- } else {
- *px1 = m1;
- *pxwidth = m1 + m2;
- e1 = fabs(m1 * inc - floor(0.5 + m1 * inc));
- e2 = fabs(m2 * inc - floor(0.5 + m2 * inc));
- *pp1 = e2 / (e1 + e2);
- }
-}
-
-/* Implementation for Screen H. This is optimized for 0 and 45 degree
- rotations. */
-static gx_wts_cell_params_t *
-wts_pick_cell_size_h(double sratiox, double sratioy, double sangledeg,
- double memw)
-{
- gx_wts_cell_params_h_t *wcph;
- double xinc, yinc;
-
- wcph = malloc(sizeof(gx_wts_cell_params_h_t));
- if (wcph == NULL)
- return NULL;
-
- wcph->base.t = WTS_SCREEN_H;
- wts_set_mat(&wcph->base, sratiox, sratioy, sangledeg);
-
- xinc = fabs(wcph->base.ufast);
- if (xinc == 0)
- xinc = fabs(wcph->base.vfast);
-
- wts_cell_calc_h(xinc, &wcph->x1, &wcph->base.width, &wcph->px, memw);
-
- yinc = fabs(wcph->base.uslow);
- if (yinc == 0)
- yinc = fabs(wcph->base.vslow);
- wts_cell_calc_h(yinc, &wcph->y1, &wcph->base.height, &wcph->py, memw);
-
- return &wcph->base;
-}
-
-static double
-wts_qart(double r, double rbase, double p, double pbase)
-{
- if (p < 1e-5) {
- return ((r + rbase) * p);
- } else {
- return ((r + rbase) * (p + pbase) - rbase * pbase);
- }
-}
-
-#ifdef VERBOSE
-static void
-wts_print_j_jump(const gx_wts_cell_params_j_t *wcpj, const char *name,
- double pa, int xa, int ya)
-{
- dlprintf6("jump %s: (%d, %d) %f, actual (%f, %f)\n",
- name, xa, ya, pa,
- wcpj->ufast_a * xa + wcpj->uslow_a * ya,
- wcpj->vfast_a * xa + wcpj->vslow_a * ya);
-}
-
-static void
-wts_j_add_jump(const gx_wts_cell_params_j_t *wcpj, double *pu, double *pv,
- double pa, int xa, int ya)
-{
- double jump_u = wcpj->ufast_a * xa + wcpj->uslow_a * ya;
- double jump_v = wcpj->vfast_a * xa + wcpj->vslow_a * ya;
- jump_u -= floor(jump_u + 0.5);
- jump_v -= floor(jump_v + 0.5);
- *pu += pa * jump_u;
- *pv += pa * jump_v;
-}
-
-static void
-wts_print_j(const gx_wts_cell_params_j_t *wcpj)
-{
- double uf, vf;
- double us, vs;
-
- dlprintf3("cell = %d x %d, shift = %d\n",
- wcpj->base.width, wcpj->base.height, wcpj->shift);
- wts_print_j_jump(wcpj, "a", wcpj->pa, wcpj->xa, wcpj->ya);
- wts_print_j_jump(wcpj, "b", wcpj->pb, wcpj->xb, wcpj->yb);
- wts_print_j_jump(wcpj, "c", wcpj->pc, wcpj->xc, wcpj->yc);
- wts_print_j_jump(wcpj, "d", wcpj->pd, wcpj->xd, wcpj->yd);
- uf = wcpj->ufast_a;
- vf = wcpj->vfast_a;
- us = wcpj->uslow_a;
- vs = wcpj->vslow_a;
- wts_j_add_jump(wcpj, &uf, &vf, wcpj->pa, wcpj->xa, wcpj->ya);
- wts_j_add_jump(wcpj, &uf, &vf, wcpj->pb, wcpj->xb, wcpj->yb);
- wts_j_add_jump(wcpj, &us, &vs, wcpj->pc, wcpj->xc, wcpj->yc);
- wts_j_add_jump(wcpj, &us, &vs, wcpj->pd, wcpj->xd, wcpj->yd);
- dlprintf6("d: %f, %f; a: %f, %f; err: %g, %g\n",
- wcpj->base.ufast, wcpj->base.vfast,
- wcpj->ufast_a, wcpj->vfast_a,
- wcpj->base.ufast - uf, wcpj->base.vfast - vf);
- dlprintf6("d: %f, %f; a: %f, %f; err: %g, %g\n",
- wcpj->base.uslow, wcpj->base.vslow,
- wcpj->uslow_a, wcpj->vslow_a,
- wcpj->base.uslow - us, wcpj->base.vslow - vs);
-}
-#endif
-
-/**
- * wts_set_scr_jxi_try: Try a width for setting Screen J parameters.
- * @wcpj: Screen J parameters.
- * @m: Width to try.
- * @qb: Best quality score seen so far.
- * @jmem: Weight given to memory usage.
- *
- * Evaluate the quality for width @i. If the quality is better than
- * @qb, then set the rest of the parameters in @wcpj.
- *
- * This routine corresponds to SetScrJXITrySP in the WTS source.
- *
- * Return value: Quality score for parameters chosen.
- **/
-static double
-wts_set_scr_jxi_try(gx_wts_cell_params_j_t *wcpj, int m, double qb,
- double jmem)
-{
- const double uf = wcpj->base.ufast;
- const double vf = wcpj->base.vfast;
- const double us = wcpj->base.uslow;
- const double vs = wcpj->base.vslow;
- wts_vec_t a, b, c;
- double ufj, vfj;
- const double rbase = 0.1;
- const double pbase = 0.001;
- double ug, vg;
- double pp, pa, pb;
- double rf;
- double xa, ya, ra, xb, yb, rb;
- double q, qx, qw, qxl, qbi;
- double pya, pyb;
- int i;
- bool jumpok;
-
- wts_vec_set(&a, (int)floor(uf * m + 0.5), (int)floor(vf * m + 0.5), 1, 0);
- if (a.u == 0 && a.v == 0)
- return qb + 1;
-
- ufj = a.u / (double)m;
- vfj = a.v / (double)m;
- /* (ufj, vfj) = movement in UV space from (0, 1) in XY space */
-
- wts_vec_set(&b, m, 0, 0, 0);
- wts_vec_set(&c, 0, m, 0, 0);
- wts_vec_gcd3(&a, &b, &c);
- ug = (uf - ufj) * m;
- vg = (vf - vfj) * m;
- pp = 1.0 / wts_vec_cross(&b, &a);
- pa = (b.u * vg - ug * b.v) * pp;
- pb = (ug * a.v - a.u * vg) * pp;
- if (pa < 0) {
- wts_vec_neg(&a);
- pa = -pa;
- }
- if (pb < 0) {
- wts_vec_neg(&b);
- pb = -pb;
- }
- wts_vec_modk(&a, m);
- wts_vec_modk(&b, m);
-
- /* Prefer nontrivial jumps. */
- jumpok = (wcpj->xa == 0 && wcpj->ya == 0) ||
- (wcpj->xb == 0 && wcpj->yb == 0) ||
- (a.k != 0 && b.k != 0);
-
- rf = (uf * uf + vf * vf) * m;
- xa = (a.u * uf + a.v * vf) / rf;
- ya = (a.v * uf - a.u * vf) / rf;
- xb = (b.u * uf + b.v * vf) / rf;
- yb = (b.v * uf - b.u * vf) / rf;
- ra = sqrt(xa * xa + 0.0625 * ya * ya);
- rb = sqrt(xb * xb + 0.0625 * yb * yb);
- qx = 0.5 * (wts_qart(ra, rbase, pa, pbase) +
- wts_qart(rb, rbase, pb, pbase));
- if (qx < 1.0 / 4000.0)
- qx *= 0.25;
- else
- qx -= 0.75 / 4000.0;
- if (m < 7500)
- qw = 0;
- else
- qw = 0.00025; /* cache penalty */
- qxl = qx + qw;
- if (qxl > qb)
- return qxl;
-
- /* width is ok, now try heights */
-
- pp = m / (double)wts_vec_cross(&b, &a);
- pya = (b.u * vs - us * b.v) * pp;
- pyb = (us * a.v - a.u * vs) * pp;
-
- qbi = qb;
- for (i = 1; qxl + m * i * jmem < qbi; i++) {
- int s = m * i;
- int ca, cb;
- double usj, vsj;
- double usg, vsg;
- wts_vec_t a1, b1, a2, b2;
- double pc, pd;
- int ck;
- double qy, qm;
-
- ca = (int)floor(i * pya + 0.5);
- cb = (int)floor(i * pyb + 0.5);
- wts_vec_set(&c, ca * a.u + cb * b.u, ca * a.v + cb * b.v, 0, 1);
- usj = c.u / (double)s;
- vsj = c.v / (double)s;
- usg = (us - usj);
- vsg = (vs - vsj);
-
- a1 = a;
- b1 = b;
- a1.u *= i;
- a1.v *= i;
- b1.u *= i;
- b1.v *= i;
- wts_vec_gcd3(&a1, &b1, &c);
- a2 = a1;
- b2 = b1;
- pp = s / (double)wts_vec_cross(&b1, &a1);
- pc = (b1.u * vsg - usg * b1.v) * pp;
- pd = (usg * a1.v - a1.u * vsg) * pp;
- if (pc < 0) {
- wts_vec_neg(&a1);
- pc = -pc;
- }
- if (pd < 0) {
- wts_vec_neg(&b1);
- pd = -pd;
- }
- ck = ca * a.k + cb * b.k;
- while (ck < 0) ck += m;
- while (ck >= m) ck -= m;
- wts_vec_modkls(&a1, m, i, ck);
- wts_vec_modkls(&b1, m, i, ck);
- rf = (us * us - vs * vs) * s;
- xa = (a1.u * us + a1.v * vs) / rf;
- ya = (a1.v * us - a1.u * vs) / rf;
- xb = (b1.u * us + b1.v * vs) / rf;
- yb = (b1.v * us - b1.u * vs) / rf;
- ra = sqrt(xa * xa + 0.0625 * ya * ya);
- rb = sqrt(xb * xb + 0.0625 * yb * yb);
- qy = 0.5 * (wts_qart(ra, rbase, pc, pbase) +
- wts_qart(rb, rbase, pd, pbase));
- if (qy < 1.0 / 100.0)
- qy *= 0.025;
- else
- qy -= 0.75 / 100.0;
- qm = s * jmem;
-
- /* first try a and b jumps within the scanline */
- q = qm + qw + qx + qy;
- if (q < qbi && jumpok) {
-#ifdef VERBOSE
- dlprintf7("m = %d, n = %d, q = %d, qx = %d, qy = %d, qm = %d, qw = %d\n",
- m, i, (int)(q * 1e6), (int)(qx * 1e6), (int)(qy * 1e6), (int)(qm * 1e6), (int)(qw * 1e6));
-#endif
- qbi = q;
- wcpj->base.width = m;
- wcpj->base.height = i;
- wcpj->shift = ck;
- wcpj->ufast_a = ufj;
- wcpj->vfast_a = vfj;
- wcpj->uslow_a = usj;
- wcpj->vslow_a = vsj;
- wcpj->xa = a.k;
- wcpj->ya = 0;
- wcpj->xb = b.k;
- wcpj->yb = 0;
- wcpj->xc = a1.k;
- wcpj->yc = a1.l;
- wcpj->xd = b1.k;
- wcpj->yd = b1.l;
- wcpj->pa = pa;
- wcpj->pb = pb;
- wcpj->pc = pc;
- wcpj->pd = pd;
-#ifdef VERBOSE
- wts_print_j(wcpj);
-#endif
- }
-
- /* then try unconstrained a and b jumps */
- if (i > 1) {
- double pa2, pb2, pp2;
- double qx2, qw2, q2;
-
- pp2 = pp;
- pa2 = (b2.u * vg - ug * b2.v) * pp2;
- pb2 = (ug * a2.v - a2.u * vg) * pp2;
- rf = (uf * uf + vf * vf) * s;
- xa = (a2.u * uf + a2.v * vf) / rf;
- ya = (a2.v * uf - a2.u * vf) / rf;
- xb = (b2.u * uf + b2.v * vf) / rf;
- yb = (b2.v * uf - b2.u * vf) / rf;
- ra = sqrt(xa * xa + 0.0625 * ya * ya);
- rb = sqrt(xb * xb + 0.0625 * yb * yb);
- if (pa2 < 0) {
- pa2 = -pa2;
- wts_vec_neg(&a2);
- }
- if (pb2 < 0) {
- pb2 = -pb2;
- wts_vec_neg(&b2);
- }
- wts_vec_modkls(&a2, m, i, ck);
- wts_vec_modkls(&b2, m, i, ck);
- qx2 = 0.5 * (wts_qart(ra, rbase, pa2, pbase) +
- wts_qart(rb, rbase, pb2, pbase));
- if (qx2 < 1.0 / 4000.0)
- qx2 *= 0.25;
- else
- qx2 -= 0.75 / 4000.0;
- if (s < 7500)
- qw2 = 0;
- else
- qw2 = 0.00025; /* cache penalty */
- q2 = qm + qw2 + qx2 + qy;
- if (q2 < qbi) {
-#ifdef VERBOSE
- dlprintf7("m = %d, n = %d, q = %d, qx2 = %d, qy = %d, qm = %d, qw2 = %d\n",
- m, i, (int)(q * 1e6), (int)(qx * 1e6), (int)(qy * 1e6), (int)(qm * 1e6), (int)(qw2 * 1e6));
-#endif
- if (qxl > qw2 + qx2)
- qxl = qw2 + qx2;
- qbi = q2;
- wcpj->base.width = m;
- wcpj->base.height = i;
- wcpj->shift = ck;
- wcpj->ufast_a = ufj;
- wcpj->vfast_a = vfj;
- wcpj->uslow_a = usj;
- wcpj->vslow_a = vsj;
- wcpj->xa = a2.k;
- wcpj->ya = a2.l;
- wcpj->xb = b2.k;
- wcpj->yb = a2.l;
- wcpj->xc = a1.k;
- wcpj->yc = a1.l;
- wcpj->xd = b1.k;
- wcpj->yd = b1.l;
- wcpj->pa = pa2;
- wcpj->pb = pb2;
- wcpj->pc = pc;
- wcpj->pd = pd;
-#ifdef VERBOSE
- wts_print_j(wcpj);
-#endif
- }
- } /* if (i > 1) */
- if (qx > 10 * qy)
- break;
- }
- return qbi;
-}
-
-static int
-wts_double_to_int_cap(double d)
-{
- if (d > 0x7fffffff)
- return 0x7fffffff;
- else return (int)d;
-}
-
-/**
- * wts_set_scr_jxi: Choose Screen J parameters.
- * @wcpj: Screen J parameters.
- * @jmem: Weight given to memory usage.
- *
- * Chooses a cell size based on the [uv]{fast,slow} parameters,
- * setting the rest of the parameters in @wcpj. Essentially, this
- * algorithm iterates through all plausible widths for the cell.
- *
- * This routine corresponds to SetScrJXISP in the WTS source.
- *
- * Return value: Quality score for parameters chosen.
- **/
-static double
-wts_set_scr_jxi(gx_wts_cell_params_j_t *wcpj, double jmem)
-{
- int i, imax;
- double q, qb;
-
- wcpj->xa = 0;
- wcpj->ya = 0;
- wcpj->xb = 0;
- wcpj->yb = 0;
- wcpj->xc = 0;
- wcpj->yc = 0;
- wcpj->xd = 0;
- wcpj->yd = 0;
-
- qb = 1.0;
- imax = wts_double_to_int_cap(qb / jmem);
- for (i = 1; i <= imax; i++) {
- if (i > 1) {
- q = wts_set_scr_jxi_try(wcpj, i, qb, jmem);
- if (q < qb) {
- qb = q;
- imax = wts_double_to_int_cap(q / jmem);
- if (imax >= 7500)
- imax = wts_double_to_int_cap((q - 0.00025) / jmem);
- if (imax < 7500) {
- imax = 7500;
- }
- }
- }
- }
- return qb;
-}
-
-/* Implementation for Screen J. This is optimized for general angles. */
-static gx_wts_cell_params_t *
-wts_pick_cell_size_j(double sratiox, double sratioy, double sangledeg,
- double memw)
-{
- gx_wts_cell_params_j_t *wcpj;
- double code;
-
- wcpj = malloc(sizeof(gx_wts_cell_params_j_t));
- if (wcpj == NULL)
- return NULL;
-
- wcpj->base.t = WTS_SCREEN_J;
- wts_set_mat(&wcpj->base, sratiox, sratioy, sangledeg);
-
- code = wts_set_scr_jxi(wcpj, pow(0.1, memw));
- if (code < 0) {
- free(wcpj);
- return NULL;
- }
-
- return &wcpj->base;
-}
-
-typedef struct {
- double sratiox;
- double sratioy;
- double sangledeg;
- double memw;
-} wts_cell_size_key;
-
-static void *
-wts_cache_alloc_callback(void *data, int bytes)
-{
- return malloc(bytes);
-}
-
-static void
-store_be32(byte *ptr, int x)
-{
- ptr[0] = (x >> 24) & 0xff;
- ptr[1] = (x >> 16) & 0xff;
- ptr[2] = (x >> 8) & 0xff;
- ptr[3] = x & 0xff;
-}
-
-/**
- * wts_pick_cell_size: Choose cell size for WTS screen.
- * @ph: The halftone parameters.
- * @pmat: Transformation from 1/72" Y-up coords to device coords.
- *
- * Return value: The WTS cell parameters, or NULL on error.
- **/
-gx_wts_cell_params_t *
-wts_pick_cell_size(gs_screen_halftone *ph, const gs_matrix *pmat)
-{
- gx_wts_cell_params_t *result;
-
- /* todo: deal with landscape and mirrored coordinate systems */
- double sangledeg = ph->angle;
- double sratiox = 72.0 * fabs(pmat->xx) / ph->frequency;
- double sratioy = 72.0 * fabs(pmat->yy) / ph->frequency;
- double octangle;
- double memw = 8.0;
- wts_cell_size_key key;
- int len;
- byte *keyptr = NULL;
- byte intkey[12];
- int keysize;
-
- octangle = sangledeg;
- while (octangle >= 45.0) octangle -= 45.0;
- while (octangle < -45.0) octangle += 45.0;
-
- /* try persistent cache */
- if (sangledeg == 45.0) {
- int srxi, sryi;
-
- srxi = (int)floor(sratiox / sqrt(2) + 0.5);
- sryi = (int)floor(sratioy / sqrt(2) + 0.5);
- if (fabs(srxi * sqrt(2) - sratiox) < 2e-6 &&
- fabs(sryi * sqrt(2) - sratioy) < 2e-6) {
- store_be32(intkey, (int)sangledeg);
- store_be32(intkey + 4, srxi);
- store_be32(intkey + 8, sryi);
- keyptr = intkey;
- keysize = sizeof(intkey);
- }
- }
- if (keyptr == NULL) {
- key.sratiox = sratiox;
- key.sratioy = sratioy;
- key.sangledeg = sangledeg;
- key.memw = memw;
- keyptr = (byte *)&key;
- keysize = sizeof(key);
- }
- len = gp_cache_query(GP_CACHE_TYPE_WTS_SIZE, keyptr, keysize,
- (void **)&result, wts_cache_alloc_callback, NULL);
- if (len >= 0)
- return result;
-
- if (fabs(octangle) < 1e-4)
- result = wts_pick_cell_size_h(sratiox, sratioy, sangledeg, memw);
- else
- result = wts_pick_cell_size_j(sratiox, sratioy, sangledeg, memw);
-
- if (result != NULL) {
- int resultsize = 0;
-
- /* insert computed cell size into cache */
- if (result->t == WTS_SCREEN_H)
- resultsize = sizeof(gx_wts_cell_params_h_t);
- else if (result->t == WTS_SCREEN_J)
- resultsize = sizeof(gx_wts_cell_params_j_t);
- if (resultsize)
- gp_cache_insert(GP_CACHE_TYPE_WTS_SIZE, (byte *)&key, sizeof(key),
- (void *)result, resultsize);
-
- ph->actual_frequency = ph->frequency;
- ph->actual_angle = ph->angle;
- }
- return result;
-}
-
-struct gs_wts_screen_enum_s {
- wts_screen_type t;
- bits32 *cell;
- int width;
- int height;
- int size;
-
- int idx;
-};
-
-typedef struct {
- gs_wts_screen_enum_t base;
- const gx_wts_cell_params_j_t *wcpj;
-} gs_wts_screen_enum_j_t;
-
-typedef struct {
- gs_wts_screen_enum_t base;
- const gx_wts_cell_params_h_t *wcph;
-
- /* an argument can be made that these should be in the params */
- double ufast1, vfast1;
- double ufast2, vfast2;
- double uslow1, vslow1;
- double uslow2, vslow2;
-} gs_wts_screen_enum_h_t;
-
-static gs_wts_screen_enum_t *
-gs_wts_screen_enum_j_new(gx_wts_cell_params_t *wcp)
-{
- gs_wts_screen_enum_j_t *wsej;
-
- wsej = malloc(sizeof(gs_wts_screen_enum_j_t));
- wsej->base.t = WTS_SCREEN_J;
- wsej->wcpj = (const gx_wts_cell_params_j_t *)wcp;
- wsej->base.width = wcp->width;
- wsej->base.height = wcp->height;
- wsej->base.size = wcp->width * wcp->height;
- wsej->base.cell = malloc(wsej->base.size * sizeof(wsej->base.cell[0]));
- wsej->base.idx = 0;
-
- return (gs_wts_screen_enum_t *)wsej;
-}
-
-static int
-gs_wts_screen_enum_j_currentpoint(gs_wts_screen_enum_t *self,
- gs_point *ppt)
-{
- gs_wts_screen_enum_j_t *z = (gs_wts_screen_enum_j_t *)self;
- const gx_wts_cell_params_j_t *wcpj = z->wcpj;
-
- int x, y;
- double u, v;
-
- if (z->base.idx == z->base.size) {
- return 1;
- }
- x = z->base.idx % wcpj->base.width;
- y = z->base.idx / wcpj->base.width;
- u = wcpj->ufast_a * x + wcpj->uslow_a * y;
- v = wcpj->vfast_a * x + wcpj->vslow_a * y;
- u -= floor(u);
- v -= floor(v);
- ppt->x = 2 * u - 1;
- ppt->y = 2 * v - 1;
- return 0;
-}
-
-static gs_wts_screen_enum_t *
-gs_wts_screen_enum_h_new(gx_wts_cell_params_t *wcp)
-{
- gs_wts_screen_enum_h_t *wseh;
- const gx_wts_cell_params_h_t *wcph = (const gx_wts_cell_params_h_t *)wcp;
- int x1 = wcph->x1;
- int x2 = wcp->width - x1;
- int y1 = wcph->y1;
- int y2 = wcp->height - y1;
-
- wseh = malloc(sizeof(gs_wts_screen_enum_h_t));
- wseh->base.t = WTS_SCREEN_H;
- wseh->wcph = wcph;
- wseh->base.width = wcp->width;
- wseh->base.height = wcp->height;
- wseh->base.size = wcp->width * wcp->height;
- wseh->base.cell = malloc(wseh->base.size * sizeof(wseh->base.cell[0]));
- wseh->base.idx = 0;
-
- wseh->ufast1 = floor(0.5 + wcp->ufast * x1) / x1;
- wseh->vfast1 = floor(0.5 + wcp->vfast * x1) / x1;
- if (x2 > 0) {
- wseh->ufast2 = floor(0.5 + wcp->ufast * x2) / x2;
- wseh->vfast2 = floor(0.5 + wcp->vfast * x2) / x2;
- }
- wseh->uslow1 = floor(0.5 + wcp->uslow * y1) / y1;
- wseh->vslow1 = floor(0.5 + wcp->vslow * y1) / y1;
- if (y2 > 0) {
- wseh->uslow2 = floor(0.5 + wcp->uslow * y2) / y2;
- wseh->vslow2 = floor(0.5 + wcp->vslow * y2) / y2;
- }
-
- return &wseh->base;
-}
-
-static int
-gs_wts_screen_enum_h_currentpoint(gs_wts_screen_enum_t *self,
- gs_point *ppt)
-{
- gs_wts_screen_enum_h_t *z = (gs_wts_screen_enum_h_t *)self;
- const gx_wts_cell_params_h_t *wcph = z->wcph;
-
- int x, y;
- double u, v;
-
- if (self->idx == self->size) {
- return 1;
- }
- x = self->idx % wcph->base.width;
- y = self->idx / wcph->base.width;
- if (x < wcph->x1) {
- u = z->ufast1 * x;
- v = z->vfast1 * x;
- } else {
- u = z->ufast2 * (x - wcph->x1);
- v = z->vfast2 * (x - wcph->x1);
- }
- if (y < wcph->y1) {
- u += z->uslow1 * y;
- v += z->vslow1 * y;
- } else {
- u += z->uslow2 * (y - wcph->y1);
- v += z->vslow2 * (y - wcph->y1);
- }
- u -= floor(u);
- v -= floor(v);
- ppt->x = 2 * u - 1;
- ppt->y = 2 * v - 1;
- return 0;
-}
-
-gs_wts_screen_enum_t *
-gs_wts_screen_enum_new(gx_wts_cell_params_t *wcp)
-{
- if (wcp->t == WTS_SCREEN_J)
- return gs_wts_screen_enum_j_new(wcp);
- else if (wcp->t == WTS_SCREEN_H)
- return gs_wts_screen_enum_h_new(wcp);
- else
- return NULL;
-}
-
-int
-gs_wts_screen_enum_currentpoint(gs_wts_screen_enum_t *wse, gs_point *ppt)
-{
- if (wse->t == WTS_SCREEN_J)
- return gs_wts_screen_enum_j_currentpoint(wse, ppt);
- if (wse->t == WTS_SCREEN_H)
- return gs_wts_screen_enum_h_currentpoint(wse, ppt);
- else
- return -1;
-}
-
-int
-gs_wts_screen_enum_next(gs_wts_screen_enum_t *wse, floatp value)
-{
- bits32 sample;
-
- if (value < -1.0 || value > 1.0)
- return_error(gs_error_rangecheck);
- sample = (bits32) ((value + 1) * 0x7fffffff);
- wse->cell[wse->idx] = sample;
- wse->idx++;
- return 0;
-}
-
-/* Run the enum with a square dot. This is useful for testing. */
-#ifdef UNIT_TEST
-static void
-wts_run_enum_squaredot(gs_wts_screen_enum_t *wse)
-{
- int code;
- gs_point pt;
- floatp spot;
-
- for (;;) {
- code = gs_wts_screen_enum_currentpoint(wse, &pt);
- if (code)
- break;
- spot = 0.5 * (cos(pt.x * M_PI) + cos(pt.y * M_PI));
- gs_wts_screen_enum_next(wse, spot);
- }
-}
-#endif /* UNIT_TEST */
-
-static int
-wts_sample_cmp(const void *av, const void *bv) {
- const bits32 *const *a = (const bits32 *const *)av;
- const bits32 *const *b = (const bits32 *const *)bv;
-
- if (**a > **b) return 1;
- if (**a < **b) return -1;
- return 0;
-}
-
-/* This implementation simply sorts the threshold values (evening the
- distribution), without applying any moire reduction. */
-int
-wts_sort_cell(gs_wts_screen_enum_t *wse)
-{
- int size = wse->width * wse->height;
- bits32 *cell = wse->cell;
- bits32 **pcell;
- int i;
-
- pcell = malloc(size * sizeof(bits32 *));
- if (pcell == NULL)
- return -1;
- for (i = 0; i < size; i++)
- pcell[i] = &cell[i];
- qsort(pcell, size, sizeof(bits32 *), wts_sample_cmp);
- for (i = 0; i < size; i++)
- *pcell[i] = (bits32)floor(WTS_SORTED_MAX * (i + 0.5) / size);
- free(pcell);
- return 0;
-}
-
-/**
- * wts_blue_bump: Generate bump function for BlueDot.
- *
- * Return value: newly allocated bump.
- **/
-static bits32 *
-wts_blue_bump(const gs_wts_screen_enum_t *wse)
-{
- const gx_wts_cell_params_t *wcp;
- int width = wse->width;
- int height = wse->height;
- int shift;
- int size = width * height;
- bits32 *bump;
- int i;
- double uf, vf;
- double am, eg;
- int z;
- int x0, y0;
- int x, y;
-
- if (wse->t == WTS_SCREEN_J) {
- gs_wts_screen_enum_j_t *wsej = (gs_wts_screen_enum_j_t *)wse;
- shift = wsej->wcpj->shift;
- wcp = &wsej->wcpj->base;
- } else if (wse->t == WTS_SCREEN_H) {
- gs_wts_screen_enum_h_t *wseh = (gs_wts_screen_enum_h_t *)wse;
- shift = 0;
- wcp = &wseh->wcph->base;
- } else
- return NULL;
-
- bump = (bits32 *)malloc(size * sizeof(bits32));
- if (bump == NULL)
- return NULL;
-
- for (i = 0; i < size; i++)
- bump[i] = 0;
- /* todo: more intelligence for anisotropic scaling */
- uf = wcp->ufast;
- vf = wcp->vfast;
-
- am = uf * uf + vf * vf;
- eg = (1 << 24) * 2.0 * sqrt (am);
- z = (int)(5 / sqrt (am));
-
- x0 = -(z / width) * shift - z;
- y0 = -(z % width);
- while (y0 < 0) {
- x0 -= shift;
- y0 += height;
- }
- while (x0 < 0) x0 += width;
- for (y = -z; y <= z; y++) {
- int x1 = x0;
- for (x = -z; x <= z; x++) {
- bump[y0 * width + x1] += (bits32)(eg * exp (-am * (x * x + y * y)));
- x1++;
- if (x1 == width)
- x1 = 0;
- }
- y0++;
- if (y0 == height) {
- x0 += shift;
- if (x0 >= width) x0 -= width;
- y0 = 0;
- }
- }
- return bump;
-}
-
-/**
- * wts_sort_blue: Sort cell using BlueDot.
- **/
-static int
-wts_sort_blue(const gs_wts_screen_enum_t *wse)
-{
- bits32 *cell = wse->cell;
- int width = wse->width;
- int height = wse->height;
- int shift;
- int size = width * height;
- bits32 *ref;
- bits32 **pcell;
- bits32 *bump;
- int i;
-
- if (wse->t == WTS_SCREEN_J) {
- gs_wts_screen_enum_j_t *wsej = (gs_wts_screen_enum_j_t *)wse;
- shift = wsej->wcpj->shift;
- } else
- shift = 0;
-
- ref = (bits32 *)malloc(size * sizeof(bits32));
- pcell = (bits32 **)malloc(size * sizeof(bits32 *));
- bump = wts_blue_bump(wse);
- if (ref == NULL || pcell == NULL || bump == NULL) {
- free(ref);
- free(pcell);
- free(bump);
- return -1;
- }
- for (i = 0; i < size; i++)
- pcell[i] = &cell[i];
- qsort(pcell, size, sizeof(bits32 *), wts_sample_cmp);
- /* set ref to sorted cell; pcell will now point to ref */
- for (i = 0; i < size; i++) {
- pcell[i] = (pcell[i] - cell) + ref;
- *pcell[i] = (bits32)floor((1 << 24) * (i + 0.5) / size);
- cell[i] = 0;
- }
-
- for (i = 0; i < size; i++) {
- bits32 gmin = *pcell[i];
- int j;
- int j_end = i + 5000;
- int jmin = i;
- int ix;
- int x0, y0;
- int x, y;
- int ref_ix, bump_ix;
-
- /* find minimum cell value, but prune search */
- if (j_end > size) j_end = size;
- for (j = i + 1; j < j_end; j++) {
- if (*pcell[j] < gmin) {
- gmin = *pcell[j];
- jmin = j;
- }
- }
- ix = pcell[jmin] - ref;
- pcell[jmin] = pcell[i];
- cell[ix] = (bits32)floor(WTS_SORTED_MAX * (i + 0.5) / size);
-
- x0 = ix % width;
- y0 = ix / width;
-
- /* Add in bump, centered at (x0, y0) */
- ref_ix = y0 * width;
- bump_ix = 0;
- for (y = 0; y < height; y++) {
- for (x = x0; x < width; x++)
- ref[ref_ix + x] += bump[bump_ix++];
- for (x = 0; x < x0; x++)
- ref[ref_ix + x] += bump[bump_ix++];
- ref_ix += width;
- y0++;
- if (y0 == height) {
- x0 += shift;
- if (x0 >= width) x0 -= width;
- y0 = 0;
- ref_ix = 0;
- }
- }
-
- /* Remove DC component to avoid integer overflow. */
- if ((i & 255) == 255 && i + 1 < size) {
- bits32 gmin = *pcell[i + 1];
- int j;
-
- for (j = i + 2; j < size; j++) {
- if (*pcell[j] < gmin) {
- gmin = *pcell[j];
- }
- }
-#ifdef VERBOSE
- if_debug1('h', "[h]gmin = %d\n", gmin);
-#endif
- for (j = i + 1; j < size; j++)
- *pcell[j] -= gmin;
-
- }
- }
-
- free(ref);
- free(pcell);
- free(bump);
- return 0;
-}
-
-static wts_screen_t *
-wts_screen_from_enum_j(const gs_wts_screen_enum_t *wse)
-{
- const gs_wts_screen_enum_j_t *wsej = (const gs_wts_screen_enum_j_t *)wse;
- wts_screen_j_t *wsj;
- wts_screen_sample_t *samples;
- int size;
- int i;
-
- wsj = malloc(sizeof(wts_screen_j_t));
- wsj->base.type = WTS_SCREEN_J;
- wsj->base.cell_width = wsej->base.width;
- wsj->base.cell_height = wsej->base.height;
- size = wsj->base.cell_width * wsj->base.cell_height;
- wsj->base.cell_shift = wsej->wcpj->shift;
- wsj->pa = (int)floor(wsej->wcpj->pa * (1 << 16) + 0.5);
- wsj->pb = (int)floor(wsej->wcpj->pb * (1 << 16) + 0.5);
- wsj->pc = (int)floor(wsej->wcpj->pc * (1 << 16) + 0.5);
- wsj->pd = (int)floor(wsej->wcpj->pd * (1 << 16) + 0.5);
- wsj->XA = wsej->wcpj->xa;
- wsj->YA = wsej->wcpj->ya;
- wsj->XB = wsej->wcpj->xb;
- wsj->YB = wsej->wcpj->yb;
- wsj->XC = wsej->wcpj->xc;
- wsj->YC = wsej->wcpj->yc;
- wsj->XD = wsej->wcpj->xd;
- wsj->YD = wsej->wcpj->yd;
-
- samples = malloc(sizeof(wts_screen_sample_t) * size);
- wsj->base.samples = samples;
- for (i = 0; i < size; i++) {
- samples[i] = wsej->base.cell[i] >> WTS_EXTRA_SORT_BITS;
- }
-
-#ifdef WTS_CACHE_SIZE_X
- for (i = 0; i < WTS_CACHE_SIZE_X; i++)
- wsj->xcache[i].tag = -1;
- for (i = 0; i < WTS_CACHE_SIZE_Y; i++)
- wsj->ycache[i].tag = -1;
-#endif
-
- return &wsj->base;
-}
-
-static wts_screen_t *
-wts_screen_from_enum_h(const gs_wts_screen_enum_t *wse)
-{
- const gs_wts_screen_enum_h_t *wseh = (const gs_wts_screen_enum_h_t *)wse;
- wts_screen_h_t *wsh;
- wts_screen_sample_t *samples;
- int size;
- int i;
-
- /* factor some of this out into a common init routine? */
- wsh = malloc(sizeof(wts_screen_h_t));
- wsh->base.type = WTS_SCREEN_H;
- wsh->base.cell_width = wseh->base.width;
- wsh->base.cell_height = wseh->base.height;
- size = wsh->base.cell_width * wsh->base.cell_height;
- wsh->base.cell_shift = 0;
- wsh->px = wseh->wcph->px;
- wsh->py = wseh->wcph->py;
- wsh->x1 = wseh->wcph->x1;
- wsh->y1 = wseh->wcph->y1;
-
- samples = malloc(sizeof(wts_screen_sample_t) * size);
- wsh->base.samples = samples;
- for (i = 0; i < size; i++) {
- samples[i] = wseh->base.cell[i] >> WTS_EXTRA_SORT_BITS;
- }
-
- return &wsh->base;
-}
-
-typedef struct {
- wts_screen_type t;
- int width;
- int height;
-} wts_key_j;
-
-typedef struct {
- wts_screen_type t;
- int width;
- int height;
-} wts_key_h;
-
-wts_screen_t *
-wts_screen_from_enum(const gs_wts_screen_enum_t *wse)
-{
- wts_screen_t *result = NULL;
- byte *key = NULL;
- int key_size = 0; /* A stub. Was uninitialized when wse->t != WTS_SCREEN_J */
- int cell_off;
- int cell_len = -1;
- byte *cell_result;
-
- if (wse->t == WTS_SCREEN_J) {
- wts_key_j k;
- k.t = wse->t;
- k.width = wse->width;
- k.height = wse->height;
- cell_off = sizeof(k);
-
- key_size = cell_off + wse->size * sizeof(bits32);
- key = (byte *)malloc(key_size);
- /* todo: more params */
- memcpy(key, &k, cell_off);
- memcpy(key + cell_off, wse->cell, wse->size * sizeof(bits32));
- } else if (wse->t == WTS_SCREEN_H) {
- wts_key_h k;
- k.t = wse->t;
- k.width = wse->width;
- k.height = wse->height;
- key_size = sizeof(k);
- key = (byte *)malloc(key_size);
- /* todo: more params */
- memcpy(key, &k, key_size);
- }
-
- if (key != NULL)
- cell_len = gp_cache_query(GP_CACHE_TYPE_WTS_CELL, key, key_size,
- (void **)&cell_result,
- wts_cache_alloc_callback, NULL);
- if (cell_len >= 0) {
- memcpy(wse->cell, cell_result, cell_len);
- free(cell_result);
- } else {
- wts_sort_blue(wse);
- cell_len = wse->size * sizeof(bits32);
- gp_cache_insert(GP_CACHE_TYPE_WTS_CELL, key, key_size,
- (void *)wse->cell, cell_len);
- }
- free(key);
-
- if (wse->t == WTS_SCREEN_J)
- result = wts_screen_from_enum_j(wse);
- else if (wse->t == WTS_SCREEN_H)
- result = wts_screen_from_enum_h(wse);
-
-#ifdef DUMP_WTS
- {
- static int dump_idx = 0;
- char dump_fn[128];
- int dump_fd;
- byte *buf;
- int size;
-
- size = gs_wts_to_buf(result, &buf);
- sprintf(dump_fn, "wts_dump_%d", dump_idx++);
- dump_fd = open(dump_fn, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- write(dump_fd, buf, size);
- close(dump_fd);
- free(buf);
- }
-#endif
-
- return result;
-}
-
-void
-gs_wts_free_enum(gs_wts_screen_enum_t *wse)
-{
- free(wse);
-}
-
-void
-gs_wts_free_screen(wts_screen_t * wts)
-{
- /* todo: free cell */
- free(wts);
-}
-
-/* 20090929:mu: dirty fix to deal with bug #690710.
- wts plane files (wts_plane_{0,1,2,3}) are not maintained long time
- and contains littile endian 32 bit machine specific data.
- this quick fix only adresses reading this file on 64 bit and big endian machines.
- writing of those files are not supported this time. */
-/* short le_s16(byte *p), ushort le_u16(byte *p) */
-#define le_u16(p) (ushort)(*(byte *)(p) | *((byte *)(p) + 1) << 8)
-#define le_s16(p) (short)le_u16(p)
-/* int le_s32(byte *p), uint le_u32(byte *p) */
-#define le_u32(p) (uint)(*(byte *)(p) | *((byte *)(p) + 1) << 8 | *((byte *)(p) + 2) << 16 | *((byte *)(p) + 3) << 24)
-#define le_s32(p) (int)le_u32(p)
-
-int
-wts_size(const wts_screen_t *ws)
-{
- int size = 0; /* A stub. Was uninitialized when none of 3 cases below. */
- int type = le_s32(&ws->type);
-
- if (type == WTS_SCREEN_RAT) {
- size = sizeof(wts_screen_t);
- } else if (type == WTS_SCREEN_J) {
- size = sizeof(wts_screen_j_t);
- } else if (type == WTS_SCREEN_H) {
- size = sizeof(wts_screen_h_t);
- }
- return size;
-}
-
-wts_screen_t *
-gs_wts_from_buf(const byte *buf, int bufsize)
-{
- const wts_screen_t *ws = (const wts_screen_t *)buf;
- wts_screen_t *result;
- int size = wts_size(ws);
- int hdr_size;
- int cell_size; /* size of cell in bytes */
-
- result = (wts_screen_t *)malloc(size);
- if (result == NULL)
- return NULL;
-
- hdr_size = offset_of(wts_screen_t, samples) + sizeof(int);
- if (bufsize < hdr_size ) {
- free(result);
- return NULL;
- }
- result->type = le_s32(&ws->type);
- result->cell_width = le_s32(&ws->cell_width);
- result->cell_height = le_s32(&ws->cell_height);
- result->cell_shift = le_s32(&ws->cell_shift);
- result->samples = NULL;
- if (result->type == WTS_SCREEN_J) {
- wts_screen_j_t *wsj = (wts_screen_j_t *)result;
- const int *wsj_params = (const int *)((const byte *)ws + hdr_size);
-
- hdr_size += sizeof(int) * 12;
- if (bufsize < hdr_size ) {
- free(result);
- return NULL;
- }
- wsj->pa = le_s32(&wsj_params[0]);
- wsj->pb = le_s32(&wsj_params[1]);
- wsj->pc = le_s32(&wsj_params[2]);
- wsj->pd = le_s32(&wsj_params[3]);
- wsj->XA = le_s32(&wsj_params[4]);
- wsj->YA = le_s32(&wsj_params[5]);
- wsj->XB = le_s32(&wsj_params[6]);
- wsj->YB = le_s32(&wsj_params[7]);
- wsj->XC = le_s32(&wsj_params[8]);
- wsj->YC = le_s32(&wsj_params[9]);
- wsj->XD = le_s32(&wsj_params[10]);
- wsj->YD = le_s32(&wsj_params[11]);
- /* 20090929:mu: In last version, we didn't copied these entries unless
- WTS_SCREEN_J_SIZE_NOCACHE has been defined.
- But, judging from gs_wts_to_buf() code below,
- those are written into file even WTS_SCREEN_J_SIZE_NOCACHE haven't defined
- and thereofore I think these should be read. */
- }
- /* 20090929:mu: This code doesn't care about WTS_SCREEN_H type file.
- If you attenpt to read such files, probably end up with errors. */
- cell_size = result->cell_width * result->cell_height * sizeof(wts_screen_sample_t);
-
- if (bufsize < (cell_size + hdr_size) ||
- (result->samples = (wts_screen_sample_t *)malloc(cell_size)) == NULL) {
- free(result);
- return NULL;
- }
-#ifdef WTS_SCREEN_J_SIZE_NOCACHE
- if (ws->type == WTS_SCREEN_J) {
- wts_screen_j_t *wsj = (wts_screen_j_t *)result;
- int i;
-
- for (i = 0; i < WTS_CACHE_SIZE_X; i++)
- wsj->xcache[i].tag = -1;
- for (i = 0; i < WTS_CACHE_SIZE_Y; i++)
- wsj->ycache[i].tag = -1;
- }
-#endif
- { /* 20090929:mu: memcpy(result->samples, buf + hdr_size, cell_size); */
- /* assuming wts_screen_sample_t == ushort */
- wts_screen_sample_t *p = result->samples, *q = (wts_screen_sample_t *)(buf + hdr_size);
- int i = result->cell_width * result->cell_height;
- for ( ; i > 0; i-- ) {
- *p++ = le_u16(q);
- q++;
- }
- }
-
- return result;
-}
-
-#if 0 /* Never called. */
-/* Return value is size of buf in bytes */
-static int
-gs_wts_to_buf(const wts_screen_t *ws, byte **pbuf)
-{
- int size = wts_size(ws);
- int cell_size = ws->cell_width * ws->cell_height * sizeof(wts_screen_sample_t);
- byte *buf;
-
- buf = (byte *)malloc(size + cell_size);
- if (buf == NULL)
- return -1;
- memcpy(buf, ws, size);
- ((wts_screen_t *)buf)->samples = NULL;
- memcpy(buf + size, ws->samples, cell_size);
- *pbuf = buf;
-
- return size + cell_size;
-}
-#endif
-
-#ifdef UNIT_TEST
-static int
-dump_thresh(const wts_screen_t *ws, int width, int height)
-{
- int x, y;
- wts_screen_sample_t *s0;
- int cx, cy
- int dummy;
-
- wts_get_samples(ws, 0, 0, &cx, &cy, &dummy);
- s0 = ws->samples + cy * ws->cell_width + cx;
-
- printf("P5\n%d %d\n255\n", width, height);
- for (y = 0; y < height; y++) {
- for (x = 0; x < width;) {
- wts_screen_sample_t *samples;
- int n_samples, i;
-
- wts_get_samples(ws, x, y, &cx, &cy, &n_samples);
- samples = ws->samples + cy * ws->cell_width + cx;
-#if 1
- for (i = 0; x + i < width && i < n_samples; i++)
- fputc(samples[i] >> 7, stdout);
-#else
- printf("(%d, %d): %d samples at %d\n",
- x, y, n_samples, samples - s0);
-#endif
- x += n_samples;
- }
- }
- return 0;
-}
-
-int
-main (int argc, char **argv)
-{
- gs_screen_halftone h;
- gs_matrix mat;
- double xres = 1200;
- double yres = 1200;
- gx_wts_cell_params_t *wcp;
- gs_wts_screen_enum_t *wse;
- wts_screen_t *ws;
-
- mat.xx = xres / 72.0;
- mat.xy = 0;
- mat.yx = 0;
- mat.yy = yres / 72.0;
-
- h.frequency = 121;
- h.angle = 45;
-
- wcp = wts_pick_cell_size(&h, &mat);
- dlprintf2("cell size = %d x %d\n", wcp->width, wcp->height);
- wse = gs_wts_screen_enum_new(wcp);
- wts_run_enum_squaredot(wse);
-#if 1
- wts_sort_blue(wse);
-#else
- wts_sort_cell(wse);
-#endif
- ws = wts_screen_from_enum(wse);
-
- dump_thresh(ws, 512, 512);
- return 0;
-}
-#endif
diff --git a/gs/base/gswts.h b/gs/base/gswts.h
deleted file mode 100644
index 788f466..0000000
--- a/gs/base/gswts.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (C) 2001-2006 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-/*$Id$ */
-#ifndef gswts_INCLUDED
-# define gswts_INCLUDED
-
-#ifndef gs_wts_screen_enum_t_DEFINED
-# define gs_wts_screen_enum_t_DEFINED
-typedef struct gs_wts_screen_enum_s gs_wts_screen_enum_t;
-#endif
-
-typedef struct gx_wts_cell_params_s gx_wts_cell_params_t;
-
-/* Note: this corresponds roughly to the SP structure in the WTS code. */
-struct gx_wts_cell_params_s {
- wts_screen_type t;
- int width;
- int height;
- double ufast;
- double vfast;
- double uslow;
- double vslow;
-};
-
-gx_wts_cell_params_t *
-wts_pick_cell_size(gs_screen_halftone *ph, const gs_matrix *pmat);
-
-gs_wts_screen_enum_t *
-gs_wts_screen_enum_new(gx_wts_cell_params_t *wcp);
-
-int
-gs_wts_screen_enum_currentpoint(gs_wts_screen_enum_t *wse, gs_point *ppt);
-
-int
-gs_wts_screen_enum_next(gs_wts_screen_enum_t *wse, floatp value);
-
-int
-wts_sort_cell(gs_wts_screen_enum_t *wse);
-
-wts_screen_t *
-wts_screen_from_enum(const gs_wts_screen_enum_t *wse);
-
-void
-gs_wts_free_enum(gs_wts_screen_enum_t *wse);
-
-void
-gs_wts_free_screen(wts_screen_t *wts);
-
-int
-wts_size(const wts_screen_t *ws);
-
-wts_screen_t *
-gs_wts_from_buf(const byte *buf, int bufsize);
-
-#endif
diff --git a/gs/base/gxbitfmt.h b/gs/base/gxbitfmt.h
index 141489b..c6c44c2 100644
--- a/gs/base/gxbitfmt.h
+++ b/gs/base/gxbitfmt.h
@@ -192,8 +192,7 @@ typedef ulong gx_bitmap_format_t;
/*
* Return halftoned raster. (This requires a custom get_bit_rectangle
- * device procedure. See the wtsimdi device. Most devices ignore this
- * bit.
+ * device procedure. Most devices ignore this bit.
*/
#define GB_HALFTONED (1L<<31)
#define GB_HALFTONED_NAMES\
diff --git a/gs/base/gxclread.c b/gs/base/gxclread.c
index 20a1e27..81212dd 100644
--- a/gs/base/gxclread.c
+++ b/gs/base/gxclread.c
@@ -762,10 +762,10 @@ clist_render_rectangle(gx_device_clist *cldev, const gs_int_rect *prect,
/*
* Set the band_offset_? values in case the buffer device
- * needs this. Example, wtsimdi device needs to adjust the
+ * needs this. Example, a device may need to adjust the
* phase of the dithering based on the page position, NOT
* the position within the band buffer to avoid band stitch
- * lines in the dither pattern.
+ * lines in the dither pattern. The old wtsimdi device did this
*
* The band_offset_x is not important for placed pages that
* are nested on a 'master' page (imposition) since each
diff --git a/gs/base/gxdcolor.c b/gs/base/gxdcolor.c
index df25b1b..45e8b39 100644
--- a/gs/base/gxdcolor.c
+++ b/gs/base/gxdcolor.c
@@ -182,7 +182,6 @@ static const gx_device_color_type_t * dc_color_type_table[] = {
gx_dc_type_pattern, /* patterns */
gx_dc_type_ht_binary, /* binary halftone device colors */
gx_dc_type_ht_colored, /* general halftone device colors */
- gx_dc_type_wts /* well-tempered screen device colors */
};
int
diff --git a/gs/base/gxdcolor.h b/gs/base/gxdcolor.h
index 94617ac..564fa26 100644
--- a/gs/base/gxdcolor.h
+++ b/gs/base/gxdcolor.h
@@ -274,9 +274,7 @@ extern const gx_device_color_type_t
#define gx_dc_type_ht_binary (&gx_dc_type_data_ht_binary)
gx_dc_type_data_ht_binary, /* gxht.c */
#define gx_dc_type_ht_colored (&gx_dc_type_data_ht_colored)
- gx_dc_type_data_ht_colored, /* gxcht.c */
-#define gx_dc_type_wts (&gx_dc_type_data_wts)
- gx_dc_type_data_wts; /* gxwts.c */
+ gx_dc_type_data_ht_colored; /* gxcht.c */
/* the following are exported for the benefit of gsptype1.c */
extern dev_color_proc_get_nonzero_comps(gx_dc_pure_get_nonzero_comps);
diff --git a/gs/base/gxdevcli.h b/gs/base/gxdevcli.h
index 4b3ff31..2ad3b0b 100644
--- a/gs/base/gxdevcli.h
+++ b/gs/base/gxdevcli.h
@@ -722,7 +722,7 @@ typedef struct gx_device_cached_colors_s {
bool UseCIEColor; /* for PS LL3 */\
bool LockSafetyParams; /* If true, prevent unsafe changes */\
long band_offset_x; /* offsets of clist band base to (mem device) buffer */\
- long band_offset_y; /* for rendering that is phase sensitive (wtsimdi) */\
+ long band_offset_y; /* for rendering that is phase sensitive (old wtsimdi) */\
gx_stroked_gradient_recognizer_t sgr;\
int MaxPatternBitmap; /* Threshold for switching to pattern_clist mode */\
cmm_dev_profile_t *icc_struct; /* object dependent profiles */\
diff --git a/gs/base/gxdevndi.c b/gs/base/gxdevndi.c
index 3153ffc..ad839bd 100644
--- a/gs/base/gxdevndi.c
+++ b/gs/base/gxdevndi.c
@@ -21,7 +21,6 @@
#include "gxdither.h"
#include "gzht.h"
#include "gxfrac.h"
-#include "gxwts.h"
/*
* Binary halftoning algorithms.
@@ -75,53 +74,6 @@ const gx_color_value *const fc_color_quo[8] = {
q0, q1, q2, q3, q4, q5, q6, q7
};
-/* Begin code for setting up WTS device color. This should probably
- move into its own module. */
-
-/**
- * gx_render_device_DevN_wts: Render DeviceN color by halftoning with WTS.
- *
- * This routine is the primary constructor for WTS device colors.
- * Note that, in the WTS code path, we sample the plane_vector array
- * during device color construction, while in the legacy code path,
- * it is sampled in the set_ht_colors procedure, invoked from
- * fill_rectangle. Does it affect correctness? I don't think so, but
- * it needs to be tested.
- **/
-static int
-gx_render_device_DeviceN_wts(frac * pcolor,
- gx_device_color * pdevc, gx_device * dev,
- gx_device_halftone * pdht,
- const gs_int_point * ht_phase)
-{
- int i;
- gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
- int num_comp = pdht->num_comp;
-
- for (i = 0; i < num_comp; i++) {
- cv[i] = 0;
- }
-
- pdevc->type = gx_dc_type_wts;
- pdevc->colors.wts.w_ht = pdht;
-
- if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN) {
- /* Monochrome case may be inverted. */
- pdevc->colors.wts.plane_vector[1] =
- dev_proc(dev, encode_color)(dev, cv);
- }
- for (i = 0; i < num_comp; i++) {
- pdevc->colors.wts.levels[i] = pcolor[i];
- cv[i] = gx_max_color_value;
- pdevc->colors.wts.plane_vector[i] =
- dev_proc(dev, encode_color)(dev, cv);
- cv[i] = 0;
- }
- pdevc->colors.wts.num_components = num_comp;
- pdevc->phase = *ht_phase;
- return 0;
-}
-
/*
* Render DeviceN possibly by halftoning.
* pcolors = pointer to an array color values (as fracs)
@@ -146,10 +98,6 @@ gx_render_device_DeviceN(frac * pcolor,
int num_colors = dev->color_info.num_components;
uint l_color[GS_CLIENT_COLOR_MAX_COMPONENTS];
- if (pdht && pdht->components && pdht->components[0].corder.wts)
- return gx_render_device_DeviceN_wts(pcolor, pdevc, dev, pdht,
- ht_phase);
-
for (i=0; i<num_colors; i++) {
max_value[i] = (dev->color_info.gray_index == i) ?
dev->color_info.dither_grays - 1 :
diff --git a/gs/base/gxdht.h b/gs/base/gxdht.h
index 50490fe..eabcc26 100644
--- a/gs/base/gxdht.h
+++ b/gs/base/gxdht.h
@@ -120,16 +120,6 @@ typedef ht_mask_t ht_sample_t;
/* The following awkward expression avoids integer overflow. */
#define max_ht_sample (ht_sample_t)(((1 << (ht_mask_bits - 2)) - 1) * 2 + 1)
-#ifndef wts_screen_t_DEFINED
-# define wts_screen_t_DEFINED
-typedef struct wts_screen_s wts_screen_t;
-#endif
-
-#ifndef gs_wts_screen_enum_t_DEFINED
-# define gs_wts_screen_enum_t_DEFINED
-typedef struct gs_wts_screen_enum_s gs_wts_screen_enum_t;
-#endif
-
/*
* Define the internal representation of a halftone order.
* Note that it may include a cached transfer function.
@@ -213,8 +203,6 @@ typedef struct gx_ht_order_screen_params_s {
} gx_ht_order_screen_params_t;
struct gx_ht_order_s {
gx_ht_cell_params_t params; /* parameters defining the cells */
- gs_wts_screen_enum_t *wse;
- wts_screen_t *wts; /* if non-NULL, then rest of the structure is irrelevant */
ushort width;
ushort height;
ushort raster;
diff --git a/gs/base/gxdhtserial.c b/gs/base/gxdhtserial.c
index da73037..a120ba1 100644
--- a/gs/base/gxdhtserial.c
+++ b/gs/base/gxdhtserial.c
@@ -23,7 +23,6 @@
#include "gzstate.h"
#include "gxdevice.h" /* for gzht.h */
#include "gzht.h"
-#include "gswts.h"
#include "gxdhtres.h"
#include "gsserial.h"
#include "gxdhtserial.h"
@@ -47,12 +46,6 @@ typedef enum {
gx_ht_tf_complete
} gx_ht_tf_type_t;
-/* enumeration to distinguish well-tempered screening orders from others */
-typedef enum {
- gx_ht_traditional,
- gx_ht_wts
-} gx_ht_order_type_t;
-
/*
* Serialize a transfer function. These will occupy one byte if they are
* not present or provide an identity mapping,
@@ -146,33 +139,6 @@ gx_ht_read_tf(
}
}
-static int
-gx_ht_write_component_wts(const wts_screen_t *wts, byte *data, uint *psize)
-{
- uint hdr_size = wts_size(wts);
- uint cell_nsamples = wts->cell_width * wts->cell_height;
- uint cell_size = cell_nsamples * sizeof(wts_screen_sample_t);
- uint req_size = 1 + hdr_size + cell_size;
-
- if (req_size > *psize) {
- *psize = req_size;
- return gs_error_rangecheck;
- }
-
- /* identify this as a wts halftone. */
- *data++ = (byte)gx_ht_wts;
-
- /* copy in wts header */
- memcpy(data, wts, hdr_size);
- ((wts_screen_t *)data)->samples = NULL;
- data += hdr_size;
-
- /* copy in treshold cell */
- memcpy(data, wts->samples, cell_size);
- *psize = req_size;
- return 0;
-}
-
/*
* Serialize a halftone component. The only part that is serialized is the
* halftone order; the other two components are only required during
@@ -210,20 +176,13 @@ gx_ht_write_component(
* get the information from their color models).
*
* This leaves the order itself.
- *
- * Check if we are a well-tempered-screening order. Serialization of these
- * is handled in a separate function.
*/
- if (porder->wts != 0)
- return gx_ht_write_component_wts(porder->wts, data, psize);
/*
* The following order fields are not transmitted:
*
* params Only required during halftone cell construction
*
- * wse, wts Only used for well-tempered screens (see above)
- *
* raster Can be re-calculated by the renderer from the width
*
* orig_height, The only potential use for these parameters is in
@@ -246,8 +205,7 @@ gx_ht_write_component(
*/
levels_size = porder->num_levels * sizeof(porder->levels[0]);
bits_size = porder->num_bits * porder->procs->bit_data_elt_size;
- req_size = 1 /* gx_ht_type_t */
- + enc_u_sizew(porder->width)
+ req_size = enc_u_sizew(porder->width)
+ enc_u_sizew(porder->height)
+ enc_u_sizew(porder->shift)
+ enc_u_sizew(porder->num_levels)
@@ -264,9 +222,6 @@ gx_ht_write_component(
return gs_error_rangecheck;
}
- /* identify this as a traditional halftone */
- *data++ = (byte)gx_ht_traditional;
-
/* write out the dimensional data */
enc_u_putw(porder->width, data);
enc_u_putw(porder->height, data);
@@ -290,29 +245,6 @@ gx_ht_write_component(
return code;
}
-static int
-gx_ht_read_component_wts(gx_ht_order_component *pcomp,
- const byte *data, uint size,
- gs_memory_t *mem)
-{
- const wts_screen_t *ws = (const wts_screen_t *)data;
- int hdr_size = wts_size(ws);
- int cell_size = ws->cell_width * ws->cell_height *
- sizeof(wts_screen_sample_t);
- int bufsize = 1+hdr_size+cell_size;
-
- memset(&pcomp->corder, 0, sizeof(pcomp->corder));
-
- if (size < bufsize)
- return -1;
- pcomp->corder.wts = gs_wts_from_buf(data, bufsize);
- pcomp->cname = 0;
- if (pcomp->corder.wts == NULL)
- return -1;
-
- return bufsize;
-}
-
/*
* Reconstruct a halftone component from its serial representation. The
* buffer provided is expected to be large enough to hold the entire
@@ -337,19 +269,12 @@ gx_ht_read_component(
gx_ht_order new_order;
const byte * data0 = data;
const byte * data_lim = data + size;
- gx_ht_order_type_t order_type;
int i, code, levels_size, bits_size;
const gx_dht_proc * phtrp = gx_device_halftone_list;
/* check the order type */
if (size == 0)
return_error(gs_error_rangecheck);
- --size;
- order_type = (gx_ht_order_type_t)*data++;
-
- /* currently only the traditional halftone order are supported */
- if (order_type != gx_ht_traditional)
- return gx_ht_read_component_wts(pcomp, data, size, mem);
/*
* For performance reasons, the number encoding macros do not
@@ -386,8 +311,6 @@ gx_ht_read_component(
* and allocates the levels and bit data arrays. In particular, it
* sets all of the following fields:
*
- * wse = 0,
- * wts = 0,
* width = operand width
* height = operand height
* raster = bitmap_raster(operand width)
diff --git a/gs/base/gxht.h b/gs/base/gxht.h
index b178556..a17daf8 100644
--- a/gs/base/gxht.h
+++ b/gs/base/gxht.h
@@ -210,12 +210,6 @@ extern_st(st_halftone);
void gs_setaccuratescreens(gs_memory_t *, bool);
bool gs_currentaccuratescreens(gs_memory_t *);
-/*
- * Set/get the value for UseWTS.
- */
-void gs_setusewts(gs_memory_t *, bool);
-bool gs_currentusewts(gs_memory_t *);
-
/* Initiate screen sampling with optional AccurateScreens. */
int gs_screen_init_memory(gs_screen_enum *, gs_state *,
gs_screen_halftone *, bool, gs_memory_t *);
diff --git a/gs/base/gxshade.c b/gs/base/gxshade.c
index 5df10b5..c616fb4 100644
--- a/gs/base/gxshade.c
+++ b/gs/base/gxshade.c
@@ -357,11 +357,8 @@ top:
}
if (num_colors <= 32) {
gx_ht_order_component *components = pis->dev_ht->components;
- if (components && components[0].corder.wts)
- num_colors = 256;
- else
- /****** WRONG FOR MULTI-PLANE HALFTONES ******/
- num_colors *= pis->dev_ht->components[0].corder.num_levels;
+ /****** WRONG FOR MULTI-PLANE HALFTONES ******/
+ num_colors *= pis->dev_ht->components[0].corder.num_levels;
}
if (psh->head.type == 2 || psh->head.type == 3) {
max_error *= 0.25;
diff --git a/gs/base/gxwts.c b/gs/base/gxwts.c
deleted file mode 100644
index ee3f535..0000000
--- a/gs/base/gxwts.c
+++ /dev/null
@@ -1,613 +0,0 @@
-/* Copyright (C) 2001-2006 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-/*$Id$ */
-/* Rendering using Well Tempered Screening. */
-#include "stdpre.h"
-#include "memory_.h" /* for memcmp */
-#include "malloc_.h"
-#include "gx.h"
-#include "gxstate.h"
-#include "gsht.h"
-#include "math_.h"
-#include "gserrors.h"
-#include "gxdcolor.h"
-#include "gxdevcli.h"
-#include "gxdht.h"
-#include "gxwts.h"
-
-#define GXWTS_USE_DOUBLE
-
-#ifndef UNIT_TEST
-/* device color type for wts. */
-
-/* todo: trace and relocate pointers */
-gs_private_st_simple(st_dc_wts, gx_device_color, "dc_wts");
-static dev_color_proc_save_dc(gx_dc_wts_save_dc);
-static dev_color_proc_get_dev_halftone(gx_dc_wts_get_dev_halftone);
-static dev_color_proc_load(gx_dc_wts_load);
-static dev_color_proc_fill_rectangle(gx_dc_wts_fill_rectangle);
-static dev_color_proc_equal(gx_dc_wts_equal);
-static dev_color_proc_write(gx_dc_wts_write);
-static dev_color_proc_read(gx_dc_wts_read);
-static dev_color_proc_get_nonzero_comps(gx_dc_wts_get_nonzero_comps);
-const gx_device_color_type_t gx_dc_type_data_wts = {
- &st_dc_wts,
- gx_dc_wts_save_dc, gx_dc_wts_get_dev_halftone,
- gx_dc_ht_get_phase,
- gx_dc_wts_load, gx_dc_wts_fill_rectangle,
- gx_dc_default_fill_masked, gx_dc_wts_equal,
- gx_dc_wts_write, gx_dc_wts_read,
- gx_dc_wts_get_nonzero_comps
-};
-#undef gx_dc_type_wts
-const gx_device_color_type_t *const gx_dc_type_wts =
-&gx_dc_type_data_wts;
-#endif
-
-/* Low-level implementation follows. */
-
-/**
- * mul_shr_16: Multiply and shift right 16.
- * @a: 32-bit signed number.
- * @b: 32-bit signed number.
- *
- * Multiply @a and @b, then shift right 16 bits. Allow intermediate value
- * to overflow 32 bits.
- *
- * Return value: result.
- **/
-#ifdef GXWTS_USE_DOUBLE
-static int
-mul_shr_16 (int a, int b)
-{
- return (int)floor(((double) a) * ((double) b) * (1.0 / (1 << 16)));
-}
-#else
-#error todo: supply mul_shr_16 based on 64 bit integer type
-#endif
-
-/* Implementation of wts_get_samples for rational cells. */
-#if 0
-static int
-wts_get_samples_rat(const wts_screen_t *ws, int x, int y,
- int *pcellx, int *pcelly, int *p_nsamples)
-{
- int d = y / ws->cell_height;
- int r = y % ws->cell_height;
- int x_ix = ((d * ws->cell_shift) + x) % ws->cell_width;
- *p_nsamples = ws->cell_width - x_ix;
- *pcellx = x_ix;
- *pcelly = y_ix;
- return 0;
-}
-#endif
-
-#define MOD_IS_SLOWER_THAN_BRANCH
-
-#ifdef WTS_CACHE_SIZE_X
-/* Implementation of wts_get_samples for Screen J, with cache. */
-static int
-wts_get_samples_j(wts_screen_t *ws, int x, int y,
- int *pcellx, int *pcelly, int *p_nsamples)
-{
- int x_ix, y_ix;
- int nsamples;
- wts_screen_j_t *wsj = (wts_screen_j_t *)ws;
- wts_j_cache_el *xcache = &wsj->xcache[(x >> 3) & (WTS_CACHE_SIZE_X - 1)];
- wts_j_cache_el *ycache = &wsj->ycache[y & (WTS_CACHE_SIZE_Y - 1)];
-
- if (xcache->tag != x || (x & 7)) {
- double pad = (wsj->pa) * (1.0 / (1 << 16));
- double pbd = (wsj->pb) * (1.0 / (1 << 16));
- double afrac = x * pad;
- double bfrac = x * pbd;
- int acount = (int)floor(afrac);
- int bcount = (int)floor(bfrac);
- int nsa = (int)ceil((acount + 1 - afrac) / pad);
- int nsb = (int)ceil((acount + 1 - afrac) / pad);
-
- xcache->x = x + acount * wsj->XA + bcount * wsj->XB;
- xcache->y = acount * wsj->YA + bcount * wsj->YB;
-#ifdef MOD_IS_SLOWER_THAN_BRANCH
- xcache->x += (xcache->y / ws->cell_height) * ws->cell_shift;
- xcache->y %= ws->cell_height;
-#endif
- xcache->nsamples = min(nsa, nsb);
- xcache->tag = x;
- }
- x_ix = xcache->x;
- y_ix = xcache->y;
- nsamples = xcache->nsamples;
-
- if (ycache->tag != y) {
- int ccount = mul_shr_16(y, wsj->pc);
- int dcount = mul_shr_16(y, wsj->pd);
-
- ycache->x = ccount * wsj->XC + dcount * wsj->XD;
- ycache->y = y + ccount * wsj->YC + dcount * wsj->YD;
-#ifdef MOD_IS_SLOWER_THAN_BRANCH
- ycache->x += (ycache->y / ws->cell_height) * ws->cell_shift;
- ycache->y %= ws->cell_height;
-#endif
- ycache->tag = y;
- }
- x_ix += ycache->x;
- y_ix += ycache->y;
-
-#ifdef MOD_IS_SLOWER_THAN_BRANCH
- if (y_ix >= ws->cell_height) {
- x_ix += ws->cell_shift;
- y_ix -= ws->cell_height;
- }
-#else
- x_ix += (y_ix / ws->cell_height) * ws->cell_shift;
- y_ix %= ws->cell_height;
-#endif
- x_ix %= ws->cell_width;
-
- nsamples = min(nsamples, ws->cell_width - x_ix);
- *p_nsamples = nsamples;
- *pcellx = x_ix;
- *pcelly = y_ix;
- return 0;
-}
-#else
-/* Implementation of wts_get_samples for Screen J. */
-static int
-wts_get_samples_j(wts_screen_t *ws, int x, int y,
- int *pcellx, int *pcelly, int *p_nsamples)
-{
- const wts_screen_j_t *wsj = (const wts_screen_j_t *)ws;
- /* int d = y / ws->cell_height; */
- int y_ix = y;
- int x_ix = x;
- double pad = (wsj->pa) * (1.0 / (1 << 16));
- double pbd = (wsj->pb) * (1.0 / (1 << 16));
- double afrac = x * pad;
- double bfrac = x * pbd;
- int acount = (int)floor(afrac);
- int bcount = (int)floor(bfrac);
- int ccount = mul_shr_16(y, wsj->pc);
- int dcount = mul_shr_16(y, wsj->pd);
- int nsamples;
-
- x_ix += acount * wsj->XA + bcount * wsj->XB +
- ccount * wsj->XC + dcount * wsj->XD;
- y_ix += acount * wsj->YA + bcount * wsj->YB +
- ccount * wsj->YC + dcount * wsj->YD;
-
- x_ix += (y_ix / ws->cell_height) * ws->cell_shift;
- x_ix %= ws->cell_width;
- y_ix %= ws->cell_height;
-
- nsamples = ws->cell_width - x_ix;
- if (floor (afrac + (nsamples - 1) * pad) > acount)
- nsamples = (int)ceil((acount + 1 - afrac) / pad);
-
- if (floor (bfrac + (nsamples - 1) * pbd) > bcount)
- nsamples = (int)ceil((bcount + 1 - bfrac) / pbd);
-#if 0
- printf("get_samples: (%d, %d) -> (%d, %d) %d (cc=%d)\n",
- x, y, x_ix, y_ix, nsamples, ccount);
-#endif
- *p_nsamples = nsamples;
- *pcellx = x_ix;
- *pcelly = y_ix;
- return 0;
-}
-#endif
-
-static int
-wts_screen_h_offset(int x, double p1, int m1, int m2)
-{
- /* todo: this is a linear search; constant time should be feasible */
- double running_p = 0;
- int width_so_far;
- int this_width;
-
- for (width_so_far = 0;; width_so_far += this_width) {
- running_p += p1;
- if (running_p >= 0.5) {
- this_width = m1;
- running_p -= 1;
- } else {
- this_width = m2;
- }
- if (width_so_far + this_width > x)
- break;
- }
- return x - width_so_far + (this_width == m1 ? 0 : m1);
-}
-
-/* Implementation of wts_get_samples for Screen H. */
-static int
-wts_get_samples_h(const wts_screen_t *ws, int x, int y,
- int *pcellx, int *pcelly, int *p_nsamples)
-{
- const wts_screen_h_t *wsh = (const wts_screen_h_t *)ws;
- int x_ix = wts_screen_h_offset(x, wsh->px,
- wsh->x1, ws->cell_width - wsh->x1);
- int y_ix = wts_screen_h_offset(y, wsh->py,
- wsh->y1, ws->cell_height - wsh->y1);
- *p_nsamples = (x_ix >= wsh->x1 ? ws->cell_width : wsh->x1) - x_ix;
- *pcellx = x_ix;
- *pcelly = y_ix;
- return 0;
-}
-
-/**
- * wts_get_samples: Get samples from Well Tempered Screening cell.
- * @ws: Well Tempered Screening cell.
- * @x: X coordinate of starting point.
- * @y: Y coordinate of starting point.
- * @samples: Where to store pointer to samples.
- * @p_nsamples: Where to store number of valid samples.
- *
- * Finds samples from the cell for use in halftoning. On success,
- * @p_nsamples is set to the number of valid samples, ie for 0 <= i <
- * nsamples, samples[i] is a valid sample for coordinate (x + i, y).
- * p_nsamples is guaranteed to at least 1. The samples in @samples
- * are valid for the lifetime of the cell, or until the next garbage
- * collection, whichever comes first.
- *
- * Todo: describe meaning of wts_screen_sample_t (particularly edge
- * cases).
- *
- * Note: may want to add a "cursor" to the api as an optimization. It
- * can wait, though.
- *
- * Return value: 0 on success.
- **/
-int
-wts_get_samples(wts_screen_t *ws, int x, int y,
- int *pcellx, int *pcelly, int *p_nsamples)
-{
- if (ws->type == WTS_SCREEN_J)
- return wts_get_samples_j(ws, x, y, pcellx, pcelly, p_nsamples);
- if (ws->type == WTS_SCREEN_H)
- return wts_get_samples_h(ws, x, y, pcellx, pcelly, p_nsamples);
- else
- return -1;
-}
-
-/* Device color methods follow. */
-
-static void
-gx_dc_wts_save_dc(const gx_device_color * pdevc, gx_device_color_saved * psdc)
-{
- psdc->type = pdevc->type;
- memcpy( psdc->colors.wts.levels,
- pdevc->colors.wts.levels,
- sizeof(psdc->colors.wts.levels) );
- psdc->phase = pdevc->phase;
-}
-
-static const gx_device_halftone *
-gx_dc_wts_get_dev_halftone(const gx_device_color * pdevc)
-{
- return pdevc->colors.wts.w_ht;
-}
-
-static int
-gx_dc_wts_load(gx_device_color *pdevc, const gs_imager_state * pis,
- gx_device *ignore_dev, gs_color_select_t select)
-{
- return 0;
-}
-
-/**
- * wts_draw: Draw a halftoned shade into a 1 bit deep buffer.
- * @ws: WTS screen.
- * @shade: Gray shade to draw.
- * @data: Destination buffer.
- * @data_raster: Rowstride for destination buffer.
- * @x, @y, @w, @h: coordinates of rectangle to draw.
- *
- * This is close to an implementation of the "draw" method for the
- * gx_ht_order class. Currently, only WTS screens implement this
- * method, and only WTS device colors invoke it. However, implementing
- * this for legacy order objects is probably a good idea, to improve
- * halftoning performance as the cell size scales up.
- *
- * However, it's not exactly an implementation of the "draw" method
- * for the gx_ht_order class because the "self" type would need to be
- * gx_ht_order. Currently, however, device colors don't hold a pointer
- * to the order object. Some amount of refactoring seems to be in
- * order.
- *
- * Return value: 0 on success.
- **/
-static int
-wts_draw(wts_screen_t *ws, wts_screen_sample_t shade,
- byte *data, int data_raster,
- int x, int y, int w, int h)
-{
- int xo, yo;
- unsigned char *line_start = data;
-
- for (yo = 0; yo < h; yo++) {
- unsigned char *line_ptr = line_start;
- int mask = 0x80;
- unsigned char b = 0;
- int imax;
-
- for (xo = 0; xo < w; xo += imax) {
- wts_screen_sample_t *samples;
- int n_samples, i;
- int cx, cy;
-
- wts_get_samples(ws, x + xo, y + yo, &cx, &cy, &n_samples);
- samples = ws->samples + cy * ws->cell_width + cx;
- imax = min(w - xo, n_samples);
- for (i = 0; i < imax; i++) {
- if (shade > samples[i])
- b |= mask;
- mask >>= 1;
- if (mask == 0) {
- *line_ptr++ = b;
- b = 0;
- mask = 0x80;
- }
- }
- }
- if (mask != 0x80)
- *line_ptr = b;
- line_start += data_raster;
- }
- return 0;
-}
-
-/**
- * Special case implementation for one component. When we do plane_mask,
- * we'll want to generalize this to handle any single-bit plane_mask.
- **/
-static int
-gx_dc_wts_fill_rectangle_1(const gx_device_color *pdevc,
- int x, int y, int w, int h,
- gx_device *dev, gs_logical_operation_t lop,
- const gx_rop_source_t *source)
-{
- /* gx_rop_source_t no_source; */
- int tile_raster = ((w + 31) & -32) >> 3;
- int tile_size = tile_raster * h;
- unsigned char *tile_data;
- int code = 0;
- gx_ht_order_component *components = pdevc->colors.wts.w_ht->components;
- wts_screen_t *ws = components[0].corder.wts;
- wts_screen_sample_t shade = pdevc->colors.wts.levels[0];
- gx_color_index color0, color1;
- int xph = pdevc->phase.x;
- int yph = pdevc->phase.y;
-
- color0 = dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN ? 0 :
- pdevc->colors.wts.plane_vector[1];
- color1 = pdevc->colors.wts.plane_vector[0];
-
- tile_data = malloc(tile_size);
-
- wts_draw(ws, shade, tile_data, tile_raster, x - xph, y - yph, w, h);
-
- /* See gx_dc_ht_binary_fill_rectangle() for explanation. */
- if (dev->color_info.depth > 1)
- lop &= ~lop_T_transparent;
-
- /* Interesting question: should data_x be (x & 7), rather than 0,
- to improve alignment? */
- if (source == NULL && lop_no_S_is_T(lop))
- code = (*dev_proc(dev, copy_mono))
- (dev, tile_data, 0, tile_raster, gx_no_bitmap_id,
- x, y, w, h, color0, color1);
-
- free(tile_data);
- return code;
-}
-
-static int
-gx_dc_wts_write(
- const gx_device_color * pdevc,
- const gx_device_color_saved * psdc,
- const gx_device * dev,
- int64_t offset,
- byte * pdata,
- uint * psize )
-{
- /* not yet implemented */
- return_error(gs_error_unknownerror);
-}
-
-static int
-gx_dc_wts_read(
- gx_device_color * pdevc,
- const gs_imager_state * pis,
- const gx_device_color * prior_devc,
- const gx_device * dev,
- int64_t offset,
- const byte * pdata,
- uint size,
- gs_memory_t * mem )
-{
- /* not yet implemented */
- return_error(gs_error_unknownerror);
-}
-
-/**
- * wts_repack_tile_4: Repack four 1-bit tiles into chunky nibbles.
- * Note: argument list will change. plane_mask and base_color will
- * probably get added as an optimization.
- *
- * Note: we round w up to an even value. We're counting on the
- * subsequent copy_color to ignore any extra bits.
- **/
-static void
-wts_repack_tile_4(unsigned char *ctile_data, int ctile_raster,
- const unsigned char **tile_data, int tile_raster,
- const gx_color_index *plane_vector, bool invert,
- int w, int h)
-{
- int y;
- int tile_idx_start = 0;
- unsigned char *ctile_start = ctile_data;
- byte inv_byte = invert ? 0xff : 0;
-
- for (y = 0; y < h; y++) {
- int x;
- int tile_idx = tile_idx_start;
-
- for (x = 0; x < w; x += 2) {
- byte b = 0;
- byte m0 = 0x80 >> (x & 6);
- byte m1 = m0 >> 1;
- byte td;
-
- td = tile_data[0][tile_idx] ^ inv_byte;
- if (td & m0) b |= plane_vector[0] << 4;
- if (td & m1) b |= plane_vector[0];
-
- td = tile_data[1][tile_idx] ^ inv_byte;
- if (td & m0) b |= plane_vector[1] << 4;
- if (td & m1) b |= plane_vector[1];
-
- td = tile_data[2][tile_idx] ^ inv_byte;
- if (td & m0) b |= plane_vector[2] << 4;
- if (td & m1) b |= plane_vector[2];
-
- td = tile_data[3][tile_idx] ^ inv_byte;
- if (td & m0) b |= plane_vector[3] << 4;
- if (td & m1) b |= plane_vector[3];
-
- if ((x & 6) == 6)
- tile_idx++;
- ctile_start[x >> 1] = b;
- }
- tile_idx_start += tile_raster;
- ctile_start += ctile_raster;
- }
-}
-
-/* Special case implementation for four components. Intermediate color
- * to the order objecttile (for copy_color) is packed 2 to a byte.
- *
- * Looking at this code, it should generalize to more than four
- * components. Probably the repack code should get factored out.
- */
-static int
-gx_dc_wts_fill_rectangle_4(const gx_device_color *pdevc,
- int x, int y, int w, int h,
- gx_device *dev, gs_logical_operation_t lop,
- const gx_rop_source_t *source)
-{
- int num_comp = pdevc->colors.wts.num_components;
- /* gx_rop_source_t no_source; */
-
- int tile_raster = ((w + 31) & -32) >> 3;
- int tile_size = tile_raster * h;
- unsigned char *tile_data[4];
-
- int ctile_raster = ((w + 7) & -8) >> 1;
- int ctile_size = ctile_raster * h;
- unsigned char *ctile_data;
-
- int code = 0;
- bool invert = 0 && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE;
- int i;
- int xph = pdevc->phase.x;
- int yph = pdevc->phase.y;
-
- for (i = 0; i < num_comp; i++) {
- wts_screen_sample_t shade = pdevc->colors.wts.levels[i];
- gx_ht_order_component *components = pdevc->colors.wts.w_ht->components;
- wts_screen_t *ws = components[i].corder.wts;
-
- tile_data[i] = malloc(tile_size);
- wts_draw(ws, shade, tile_data[i], tile_raster, x - xph, y - yph, w, h);
- }
-
- ctile_data = malloc(ctile_size);
- wts_repack_tile_4(ctile_data, ctile_raster,
- (const unsigned char **)tile_data, tile_raster,
- pdevc->colors.wts.plane_vector, invert, w, h);
-
- /* See gx_dc_ht_binary_fill_rectangle() for explanation. */
- if (dev->color_info.depth > 1)
- lop &= ~lop_T_transparent;
-
- if (source == NULL && lop_no_S_is_T(lop))
- code = (*dev_proc(dev, copy_color))
- (dev, ctile_data, 0, ctile_raster, gx_no_bitmap_id,
- x, y, w, h);
-
- free(ctile_data);
- for (i = 0; i < num_comp; i++) {
- free(tile_data[i]);
- }
-
- return code;
-}
-
-static int
-gx_dc_wts_fill_rectangle(const gx_device_color *pdevc,
- int x, int y, int w, int h,
- gx_device *dev, gs_logical_operation_t lop,
- const gx_rop_source_t *source)
-{
- int num_comp = pdevc->colors.wts.num_components;
-
- if (num_comp == 1)
- return gx_dc_wts_fill_rectangle_1(pdevc, x, y, w, h, dev, lop, source);
- else if (num_comp <= 4)
- return gx_dc_wts_fill_rectangle_4(pdevc, x, y, w, h, dev, lop, source);
- else
- return -1;
-}
-
-/* Compare two wts colors for equality. */
-static int
-gx_dc_wts_equal(const gx_device_color *pdevc1,
- const gx_device_color *pdevc2)
-{
- uint num_comp = pdevc1->colors.wts.num_components;
-
- if (pdevc2->type != pdevc1->type ||
- pdevc1->phase.x != pdevc2->phase.x ||
- pdevc1->phase.y != pdevc2->phase.y ||
- num_comp != pdevc2->colors.wts.num_components
- )
- return false;
- return
- !memcmp(pdevc1->colors.wts.levels,
- pdevc2->colors.wts.levels,
- num_comp * sizeof(pdevc1->colors.wts.levels[0]));
-}
-
-/*
- * Get the nonzero components of a wts halftone. This is used to
- * distinguish components that are given zero intensity due to halftoning
- * from those for which the original color intensity was in fact zero.
- */
-int
-gx_dc_wts_get_nonzero_comps(
- const gx_device_color * pdevc,
- const gx_device * dev_ignored,
- gx_color_index * pcomp_bits )
-{
- int i, ncomps = pdevc->colors.wts.num_components;
- gx_color_index comp_bits = 0; /* todo: plane_mask */
-
- for (i = 0; i < ncomps; i++) {
- if (pdevc->colors.wts.levels[i] != 0)
- comp_bits |= ((gx_color_index)1) << i;
- }
- *pcomp_bits = comp_bits;
-
- return 0;
-}
diff --git a/gs/base/gxwts.h b/gs/base/gxwts.h
deleted file mode 100644
index f5dd03d..0000000
--- a/gs/base/gxwts.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Copyright (C) 2001-2006 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-/*$Id$ */
-#ifndef gxwts_INCLUDED
-# define gxwts_INCLUDED
-
-typedef bits16 wts_screen_sample_t;
-
-#ifndef wts_screen_t_DEFINED
-# define wts_screen_t_DEFINED
-typedef struct wts_screen_s wts_screen_t;
-#endif
-
-/* We cache intermediate results for wts_get_samples_j. In general, if these
- are set so that a band fits, then the hit rate will be excellent. */
-#define WTS_CACHE_SIZE_X 512
-#define WTS_CACHE_SIZE_Y 512
-
-typedef enum {
- WTS_SCREEN_RAT,
- WTS_SCREEN_J,
- WTS_SCREEN_H
-} wts_screen_type;
-
-struct wts_screen_s {
- wts_screen_type type;
- int cell_width;
- int cell_height;
- int cell_shift;
- wts_screen_sample_t *samples;
-};
-
-typedef struct {
- int tag;
- int x;
- int y;
- int nsamples;
-} wts_j_cache_el;
-
-typedef struct {
- wts_screen_t base;
-
- /* Probabilities of "jumps". A and B jumps can happen when moving
- one pixel to the right. C and D can happen when moving one pixel
- down. */
- int pa; /* change to double? */
- int pb;
- int pc;
- int pd;
-
- int XA;
- int YA;
- int XB;
- int YB;
- int XC;
- int YC;
- int XD;
- int YD;
-
-#ifdef WTS_CACHE_SIZE_X
-#define WTS_SCREEN_J_SIZE_NOCACHE 68
- wts_j_cache_el xcache[WTS_CACHE_SIZE_X];
- wts_j_cache_el ycache[WTS_CACHE_SIZE_Y];
-#endif
-} wts_screen_j_t;
-
-typedef struct {
- wts_screen_t base;
-
- /* This is the exact value that x1 and (width-x1) approximates. */
- double px;
- /* Ditto y1 and (height-y1). */
- double py;
-
- int x1;
- int y1;
-} wts_screen_h_t;
-
-int
-wts_get_samples(wts_screen_t *ws, int x, int y,
- int *pcellx, int *pcelly, int *p_nsamples);
-
-#endif
diff --git a/gs/base/lib.mak b/gs/base/lib.mak
index 0de2d05..d8d4118 100644
--- a/gs/base/lib.mak
+++ b/gs/base/lib.mak
@@ -376,7 +376,6 @@ gsgcache_h=$(GLSRC)gsgcache.h
gshsb_h=$(GLSRC)gshsb.h
gsht_h=$(GLSRC)gsht.h
gsht1_h=$(GLSRC)gsht1.h $(gsht_h)
-gswts_h=$(GLSRC)gswts.h
gsjconf_h=$(GLSRC)gsjconf.h $(arch_h) $(stdpre_h)
gslib_h=$(GLSRC)gslib.h
gslparam_h=$(GLSRC)gslparam.h
@@ -446,9 +445,8 @@ gxband_h=$(GLSRC)gxband.h $(gxclio_h)
gxcdevn_h=$(GLSRC)gxcdevn.h $(gsrefct_h) $(gxcindex_h)
gxchar_h=$(GLSRC)gxchar.h $(gschar_h) $(gxtext_h)
gxchrout_h=$(GLSRC)gxchrout.h
-gxwts_h=$(GLSRC)gxwts.h
gsdcolor_h=$(GLSRC)gsdcolor.h $(gsccolor_h)\
- $(gxarith_h) $(gxbitmap_h) $(gxcindex_h) $(gxhttile_h) $(gxwts_h)
+ $(gxarith_h) $(gxbitmap_h) $(gxcindex_h) $(gxhttile_h)
gxdcolor_h=$(GLSRC)gxdcolor.h\
$(gscsel_h) $(gsdcolor_h) $(gsropt_h) $(gsstruct_h) $(stdint__h)
gsnamecl_h=$(GLSRC)gsnamecl.h $(gsccolor_h) $(gscsel_h) $(gxcspace_h)\
@@ -719,16 +717,6 @@ $(GLOBJ)gxht_thresh.$(OBJ) : $(GLSRC)gxht_thresh.c $(AK) $(memory__h)\
$(gxdevice_h) $(gxdht_h) $(gxht_thresh_h) $(gzht_h) $(gxdevsop_h) $(MAKEDIRS)
$(GLCC) $(GLO_)gxht_thresh.$(OBJ) $(C_) $(GLSRC)gxht_thresh.c
-$(GLOBJ)gxwts.$(OBJ) : $(GLSRC)gxwts.c $(AK) $(gx_h) $(gserrors_h)\
- $(gxwts_h) $(stdpre_h) $(memory__h) $(gxstate_h) $(gsht_h) $(math__h)\
- $(gxdevcli_h) $(gxdht_h) $(gxdcolor_h) $(malloc__h) $(MAKEDIRS)
- $(GLCC) $(GLO_)gxwts.$(OBJ) $(C_) $(GLSRC)gxwts.c
-
-$(GLOBJ)gswts.$(OBJ) : $(GLSRC)gswts.c $(AK) $(gserrors_h) $(gxwts_h)\
- $(gswts_h) $(fcntl__h) $(gp_h) $(string__h)\
- $(stdpre_h) $(gx_h) $(gxstate_h) $(gsht_h) $(math__h) $(gxfrac_h) $(MAKEDIRS)
- $(GLCC) $(GLO_)gswts.$(OBJ) $(C_) $(GLSRC)gswts.c
-
$(GLOBJ)gxidata.$(OBJ) : $(GLSRC)gxidata.c $(AK) $(gx_h) $(gserrors_h)\
$(memory__h) $(gxcpath_h) $(gxdevice_h) $(gximage_h) $(gsicc_cache_h)\
$(MAKEDIRS)
@@ -938,12 +926,12 @@ $(GLOBJ)gsgcache.$(OBJ) : $(GLSRC)gsgcache.c $(AK) $(gx_h)\
$(GLOBJ)gsht.$(OBJ) : $(GLSRC)gsht.c $(AK) $(gx_h) $(gserrors_h)\
$(memory__h) $(string__h) $(gsstruct_h) $(gsutil_h) $(gxarith_h)\
- $(gxdevice_h) $(gzht_h) $(gzstate_h) $(gswts_h) $(gxfmap_h) $(MAKEDIRS)
+ $(gxdevice_h) $(gzht_h) $(gzstate_h) $(gxfmap_h) $(MAKEDIRS)
$(GLCC) $(GLO_)gsht.$(OBJ) $(C_) $(GLSRC)gsht.c
$(GLOBJ)gshtscr.$(OBJ) : $(GLSRC)gshtscr.c $(AK) $(gx_h) $(gserrors_h)\
$(math__h) $(gsstruct_h) $(gxarith_h) $(gxdevice_h) $(gzht_h) $(gzstate_h)\
- $(gswts_h) $(MAKEDIRS)
+ $(MAKEDIRS)
$(GLCC) $(GLO_)gshtscr.$(OBJ) $(C_) $(GLSRC)gshtscr.c
$(GLOBJ)gsimage.$(OBJ) : $(GLSRC)gsimage.c $(AK) $(gx_h) $(gserrors_h)\
@@ -1222,7 +1210,7 @@ LIB3s=$(GLOBJ)gscedata.$(OBJ) $(GLOBJ)gscencs.$(OBJ) $(GLOBJ)gschar.$(OBJ) $(GLO
LIB4s=$(GLOBJ)gscoord.$(OBJ) $(GLOBJ)gscparam.$(OBJ) $(GLOBJ)gscspace.$(OBJ) $(GLOBJ)gscicach.$(OBJ) $(GLOBJ)gsovrc.$(OBJ) $(GLOBJ)gxoprect.$(OBJ)
LIB5s=$(GLOBJ)gsdevice.$(OBJ) $(GLOBJ)gsdevmem.$(OBJ) $(GLOBJ)gsdparam.$(OBJ) $(GLOBJ)gsdfilt.$(OBJ)
LIB6s=$(GLOBJ)gsfname.$(OBJ) $(GLOBJ)gsfont.$(OBJ) $(GLOBJ)gsgdata.$(OBJ) $(GLOBJ)gsgcache.$(OBJ)
-LIB7s=$(GLOBJ)gsht.$(OBJ) $(GLOBJ)gshtscr.$(OBJ) $(GLOBJ)gswts.$(OBJ)
+LIB7s=$(GLOBJ)gsht.$(OBJ) $(GLOBJ)gshtscr.$(OBJ)
LIB8s=$(GLOBJ)gsimage.$(OBJ) $(GLOBJ)gsimpath.$(OBJ) $(GLOBJ)gsinit.$(OBJ)
LIB9s=$(GLOBJ)gsiodev.$(OBJ) $(GLOBJ)gsistate.$(OBJ) $(GLOBJ)gsline.$(OBJ)
LIB10s=$(GLOBJ)gsmalloc.$(OBJ) $(GLOBJ)memento.$(OBJ) $(GLOBJ)gsmatrix.$(OBJ)
@@ -1236,7 +1224,7 @@ LIB3x=$(GLOBJ)gxclip.$(OBJ) $(GLOBJ)gxcmap.$(OBJ) $(GLOBJ)gxcpath.$(OBJ)
LIB4x=$(GLOBJ)gxdcconv.$(OBJ) $(GLOBJ)gxdcolor.$(OBJ) $(GLOBJ)gxhldevc.$(OBJ)
LIB5x=$(GLOBJ)gxfill.$(OBJ) $(GLOBJ)gxfdrop.$(OBJ) $(GLOBJ)gxht.$(OBJ) $(GLOBJ)gxhtbit.$(OBJ)\
$(GLOBJ)gxht_thresh.$(OBJ)
-LIB6x=$(GLOBJ)gxwts.$(OBJ) $(GLOBJ)gxidata.$(OBJ) $(GLOBJ)gxifast.$(OBJ) $(GLOBJ)gximage.$(OBJ)
+LIB6x=$(GLOBJ)gxidata.$(OBJ) $(GLOBJ)gxifast.$(OBJ) $(GLOBJ)gximage.$(OBJ)
LIB7x=$(GLOBJ)gximage1.$(OBJ) $(GLOBJ)gximono.$(OBJ) $(GLOBJ)gxipixel.$(OBJ) $(GLOBJ)gximask.$(OBJ)
LIB8x=$(GLOBJ)gxi12bit.$(OBJ) $(GLOBJ)gxi16bit.$(OBJ) $(GLOBJ)gxiscale.$(OBJ) $(GLOBJ)gxpaint.$(OBJ) $(GLOBJ)gxpath.$(OBJ) $(GLOBJ)gxpath2.$(OBJ)
LIB9x=$(GLOBJ)gxpcopy.$(OBJ) $(GLOBJ)gxpdash.$(OBJ) $(GLOBJ)gxpflat.$(OBJ)
@@ -1977,7 +1965,7 @@ $(GLOBJ)gxclpath.$(OBJ) : $(GLSRC)gxclpath.c $(AK) $(gx_h)\
$(GLOBJ)gxdhtserial.$(OBJ) : $(GLSRC)gxdhtserial.c $(memory__h) $(AK)\
$(gx_h) $(gserrors_h)\
$(gscdefs_h) $(gsstruct_h) $(gsutil_h) $(gzstate_h) $(gxdevice_h) $(gzht_h)\
- $(gswts_h) $(gxdhtres_h) $(gsserial_h) $(gxdhtserial_h) $(MAKEDIRS)
+ $(gxdhtres_h) $(gsserial_h) $(gxdhtserial_h) $(MAKEDIRS)
$(GLCC) $(GLO_)gxdhtserial.$(OBJ) $(C_) $(GLSRC)gxdhtserial.c
$(GLOBJ)gxclutil.$(OBJ) : $(GLSRC)gxclutil.c $(AK) $(gx_h)\
@@ -2526,7 +2514,7 @@ $(GLOBJ)gscolor1.$(OBJ) : $(GLSRC)gscolor1.c $(AK) $(gx_h)\
$(GLOBJ)gsht1.$(OBJ) : $(GLSRC)gsht1.c $(AK) $(gx_h) $(gserrors_h)\
$(memory__h) $(string__h) $(gsstruct_h) $(gsutil_h) $(gxdevice_h) $(gzht_h)\
- $(gzstate_h) $(gxwts_h) $(gswts_h) $(MAKEDIRS)
+ $(gzstate_h) $(MAKEDIRS)
$(GLCC) $(GLO_)gsht1.$(OBJ) $(C_) $(GLSRC)gsht1.c
colimlib_=$(GLOBJ)gxicolor.$(OBJ)
@@ -2878,7 +2866,7 @@ $(GLOBJ)gscdevn.$(OBJ) : $(GLSRC)gscdevn.c $(AK) $(gx_h) $(gserrors_h)\
$(GLCC) $(GLO_)gscdevn.$(OBJ) $(C_) $(GLSRC)gscdevn.c
$(GLOBJ)gxdevndi.$(OBJ) : $(GLSRC)gxdevndi.c $(AK) $(gx_h)\
- $(gsstruct_h) $(gsdcolor_h) $(gxfrac_h) $(gxwts_h)\
+ $(gsstruct_h) $(gsdcolor_h) $(gxfrac_h)\
$(gxcmap_h) $(gxdevice_h) $(gxdither_h) $(gxlum_h) $(gzht_h) $(MAKEDIRS)
$(GLCC) $(GLO_)gxdevndi.$(OBJ) $(C_) $(GLSRC)gxdevndi.c
diff --git a/gs/doc/Language.htm b/gs/doc/Language.htm
index 1fda8bc..f3bdfe4 100644
--- a/gs/doc/Language.htm
+++ b/gs/doc/Language.htm
@@ -2181,31 +2181,6 @@ The reduced bytecode interpreter is based in part of the work of the
The topological grid fitting is a new original Ghostscript method.
</dl>
-<dl>
-<dt><code>UseWTS <boolean></code>
-<dd>If <tt>true</tt>, and if AccurateScreens are specified (either as
-a user parameter, or as a type 1 halftone dictionary parameter), then
-the Well Tempered Screening algorithm is used for
-halftoning. Otherwise, a rational tangent algorithm is chosen, which
-will typically result in significant differences between the screen
-angle and ruling requested, and actually rendered. Currently, the
-performance of WTS is reasonably good when rendering to a full page
-buffer, but not optimized for banded mode. Thus, when using WTS,
-disable banding (setting
-<code>-dMaxBitmap=500000000</code> should work). In a future
-version, WTS will be optimized for banded mode, and
-<code>UseWTS</code> will be <tt>true</tt> by default.
-
-<p>
-<b>Note:</b> Currently, <code>UseWTS</code> can only be set using
-the PostScript user parameters mechanism, not on the command line with
-a <code>-d</code> switch. Use this code to enable it:
-
-<blockquote><pre>
-<< /UseWTS true >> setuserparams
-</pre></blockquote>
-</dl>
-
<hr>
<h2><a name="Miscellaneous_additions"></a>Miscellaneous additions</h2>
diff --git a/gs/ghostscript.vcproj b/gs/ghostscript.vcproj
index 1e138c1..f73148f 100644
--- a/gs/ghostscript.vcproj
+++ b/gs/ghostscript.vcproj
@@ -735,10 +735,6 @@
>
</File>
<File
- RelativePath="base\gswts.c"
- >
- </File>
- <File
RelativePath="base\gxacpath.c"
>
</File>
@@ -891,10 +887,6 @@
>
</File>
<File
- RelativePath="base\gxwts.c"
- >
- </File>
- <File
RelativePath="base\gzspotan.c"
>
</File>
@@ -9301,4 +9293,4 @@
</Files>
<Globals>
</Globals>
-</VisualStudioProject>
+</VisualStudioProject>
\ No newline at end of file
diff --git a/gs/psi/zusparam.c b/gs/psi/zusparam.c
index 5511460..64a5487 100644
--- a/gs/psi/zusparam.c
+++ b/gs/psi/zusparam.c
@@ -954,17 +954,6 @@ set_OverrideICC(i_ctx_t *i_ctx_p, bool val)
return 0;
}
static bool
-current_UseWTS(i_ctx_t *i_ctx_p)
-{
- return gs_currentusewts(imemory);
-}
-static int
-set_UseWTS(i_ctx_t *i_ctx_p, bool val)
-{
- gs_setusewts(imemory, val);
- return 0;
-}
-static bool
current_LockFilePermissions(i_ctx_t *i_ctx_p)
{
return i_ctx_p->LockFilePermissions;
@@ -992,7 +981,6 @@ set_RenderTTNotdef(i_ctx_t *i_ctx_p, bool val)
static const bool_param_def_t user_bool_params[] =
{
{"AccurateScreens", current_AccurateScreens, set_AccurateScreens},
- {"UseWTS", current_UseWTS, set_UseWTS},
{"LockFilePermissions", current_LockFilePermissions, set_LockFilePermissions},
{"RenderTTNotdef", current_RenderTTNotdef, set_RenderTTNotdef},
{"OverrideICC", current_OverrideICC, set_OverrideICC},
diff --git a/pl/plsrgb.c b/pl/plsrgb.c
index 5e5d175..52c1859 100644
--- a/pl/plsrgb.c
+++ b/pl/plsrgb.c
@@ -31,7 +31,7 @@
color conversion. If the definition is commented out we set up an
srgb color space and associated color rendering dictionary using
the regular color conversion machinery in the graphics library
- pipeline. The wtsimdi device is an example device that does color
+ pipeline. The wtsimdi device is an example device that did color
conversion as a "postprocess" and requires the definition. If
defined all additive colors are passed through as Device RGB but
the device assumes the triples are in fact sRGB. NB eventually
Summary of changes:
gs/base/gdevdflt.c | 2 +-
gs/base/gp.h | 2 -
gs/base/gsdcolor.h | 15 -
gs/base/gsdps1.c | 3 +-
gs/base/gsht.c | 171 ++----
gs/base/gsht1.c | 137 -----
gs/base/gshtscr.c | 135 ++---
gs/base/gslibctx.h | 1 -
gs/base/gswts.c | 1624 -------------------------------------------------
gs/base/gswts.h | 65 --
gs/base/gxbitfmt.h | 3 +-
gs/base/gxclread.c | 4 +-
gs/base/gxdcolor.c | 1 -
gs/base/gxdcolor.h | 4 +-
gs/base/gxdevcli.h | 2 +-
gs/base/gxdevndi.c | 52 --
gs/base/gxdht.h | 12 -
gs/base/gxdhtserial.c | 79 +---
gs/base/gxht.h | 6 -
gs/base/gxshade.c | 7 +-
gs/base/gxwts.c | 613 -------------------
gs/base/gxwts.h | 93 ---
gs/base/lib.mak | 28 +-
gs/doc/Language.htm | 25 -
gs/ghostscript.vcproj | 10 +-
gs/psi/zusparam.c | 12 -
pl/plsrgb.c | 2 +-
27 files changed, 114 insertions(+), 2994 deletions(-)
delete mode 100644 gs/base/gswts.c
delete mode 100644 gs/base/gswts.h
delete mode 100644 gs/base/gxwts.c
delete mode 100644 gs/base/gxwts.h
More information about the gs-commits
mailing list