17dd7cddfSDavid du Colombier /* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. 27dd7cddfSDavid du Colombier 3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or 4*593dc095SDavid du Colombier implied. 57dd7cddfSDavid du Colombier 6*593dc095SDavid du Colombier This software is distributed under license and may not be copied, 7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms 8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution. 97dd7cddfSDavid du Colombier 10*593dc095SDavid du Colombier For more information about licensing, please refer to 11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on 12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or 13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110, 14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861. 157dd7cddfSDavid du Colombier */ 167dd7cddfSDavid du Colombier 17*593dc095SDavid du Colombier /* $Id: gximage.h,v 1.8 2005/06/08 14:00:32 igor Exp $ */ 187dd7cddfSDavid du Colombier /* Default image rendering state structure */ 197dd7cddfSDavid du Colombier /* Requires gxcpath.h, gxdevmem.h, gxdcolor.h, gzpath.h */ 207dd7cddfSDavid du Colombier 217dd7cddfSDavid du Colombier #ifndef gximage_INCLUDED 227dd7cddfSDavid du Colombier # define gximage_INCLUDED 237dd7cddfSDavid du Colombier 247dd7cddfSDavid du Colombier #include "gsiparam.h" 257dd7cddfSDavid du Colombier #include "gxcspace.h" 267dd7cddfSDavid du Colombier #include "strimpl.h" /* for sisparam.h */ 277dd7cddfSDavid du Colombier #include "sisparam.h" 287dd7cddfSDavid du Colombier #include "gxdda.h" 297dd7cddfSDavid du Colombier #include "gxiclass.h" 307dd7cddfSDavid du Colombier #include "gxiparam.h" 317dd7cddfSDavid du Colombier #include "gxsample.h" 327dd7cddfSDavid du Colombier 337dd7cddfSDavid du Colombier /* Define the abstract type for the image enumerator state. */ 347dd7cddfSDavid du Colombier /*typedef struct gx_image_enum_s gx_image_enum;*/ /* in gxiclass.h */ 357dd7cddfSDavid du Colombier 367dd7cddfSDavid du Colombier /* 377dd7cddfSDavid du Colombier * Incoming samples may go through two different transformations: 387dd7cddfSDavid du Colombier * 397dd7cddfSDavid du Colombier * - For N-bit input samples with N <= 8, N-to-8-bit expansion 407dd7cddfSDavid du Colombier * may involve a lookup map. Currently this map is either an 417dd7cddfSDavid du Colombier * identity function or a subtraction from 1 (inversion). 427dd7cddfSDavid du Colombier * 437dd7cddfSDavid du Colombier * - The 8-bit or frac expanded sample may undergo decoding (a linear 447dd7cddfSDavid du Colombier * transformation) before being handed off to the color mapping 457dd7cddfSDavid du Colombier * machinery. 467dd7cddfSDavid du Colombier * 477dd7cddfSDavid du Colombier * If the decoding function's range is [0..1], we fold it into the 487dd7cddfSDavid du Colombier * expansion lookup; otherwise we must compute it separately. 497dd7cddfSDavid du Colombier * For speed, we distinguish 3 different cases of the decoding step: 507dd7cddfSDavid du Colombier */ 517dd7cddfSDavid du Colombier typedef enum { 527dd7cddfSDavid du Colombier sd_none, /* decoded during expansion */ 537dd7cddfSDavid du Colombier sd_lookup, /* use lookup_decode table */ 547dd7cddfSDavid du Colombier sd_compute /* compute using base and factor */ 557dd7cddfSDavid du Colombier } sample_decoding; 56*593dc095SDavid du Colombier struct sample_map_s { 577dd7cddfSDavid du Colombier 587dd7cddfSDavid du Colombier sample_lookup_t table; 597dd7cddfSDavid du Colombier 607dd7cddfSDavid du Colombier /* 617dd7cddfSDavid du Colombier * If an 8-bit fraction doesn't represent the decoded value 627dd7cddfSDavid du Colombier * accurately enough, but the samples have 4 bits or fewer, 637dd7cddfSDavid du Colombier * we precompute the decoded values into a table. 647dd7cddfSDavid du Colombier * Different entries are used depending on bits/sample: 657dd7cddfSDavid du Colombier * 1,8,12 bits/sample: 0,15 667dd7cddfSDavid du Colombier * 2 bits/sample: 0,5,10,15 677dd7cddfSDavid du Colombier * 4 bits/sample: all 687dd7cddfSDavid du Colombier */ 697dd7cddfSDavid du Colombier 707dd7cddfSDavid du Colombier float decode_lookup[16]; 717dd7cddfSDavid du Colombier #define decode_base decode_lookup[0] 727dd7cddfSDavid du Colombier #define decode_max decode_lookup[15] 737dd7cddfSDavid du Colombier 747dd7cddfSDavid du Colombier /* 757dd7cddfSDavid du Colombier * In the worst case, we have to do the decoding on the fly. 767dd7cddfSDavid du Colombier * The value is base + sample * factor, where the sample is 777dd7cddfSDavid du Colombier * an 8-bit (unsigned) integer or a frac. 787dd7cddfSDavid du Colombier */ 797dd7cddfSDavid du Colombier 807dd7cddfSDavid du Colombier double decode_factor; 817dd7cddfSDavid du Colombier 827dd7cddfSDavid du Colombier sample_decoding decoding; 837dd7cddfSDavid du Colombier 847dd7cddfSDavid du Colombier /* 857dd7cddfSDavid du Colombier * If decoding is sd_none for a non-mask image, we still need to know 867dd7cddfSDavid du Colombier * whether the table includes an inversion, so that we can transform 877dd7cddfSDavid du Colombier * mask values correctly. 887dd7cddfSDavid du Colombier */ 897dd7cddfSDavid du Colombier 907dd7cddfSDavid du Colombier bool inverted; 917dd7cddfSDavid du Colombier 92*593dc095SDavid du Colombier }; 93*593dc095SDavid du Colombier 94*593dc095SDavid du Colombier #ifndef sample_map_DEFINED 95*593dc095SDavid du Colombier #define sample_map_DEFINED 96*593dc095SDavid du Colombier typedef struct sample_map_s sample_map; 97*593dc095SDavid du Colombier #endif 987dd7cddfSDavid du Colombier 997dd7cddfSDavid du Colombier /* Decode an 8-bit sample into a floating point color component. */ 1007dd7cddfSDavid du Colombier /* penum points to the gx_image_enum structure. */ 1017dd7cddfSDavid du Colombier #define decode_sample(sample_value, cc, i)\ 1027dd7cddfSDavid du Colombier switch ( penum->map[i].decoding )\ 1037dd7cddfSDavid du Colombier {\ 1047dd7cddfSDavid du Colombier case sd_none:\ 1057dd7cddfSDavid du Colombier cc.paint.values[i] = (sample_value) * (1.0 / 255.0); /* faster than / */\ 1067dd7cddfSDavid du Colombier break;\ 1077dd7cddfSDavid du Colombier case sd_lookup: /* <= 4 significant bits */\ 1087dd7cddfSDavid du Colombier cc.paint.values[i] =\ 1097dd7cddfSDavid du Colombier penum->map[i].decode_lookup[(sample_value) >> 4];\ 1107dd7cddfSDavid du Colombier break;\ 1117dd7cddfSDavid du Colombier case sd_compute:\ 1127dd7cddfSDavid du Colombier cc.paint.values[i] =\ 1137dd7cddfSDavid du Colombier penum->map[i].decode_base + (sample_value) * penum->map[i].decode_factor;\ 1147dd7cddfSDavid du Colombier } 1157dd7cddfSDavid du Colombier 1167dd7cddfSDavid du Colombier /* Decode a frac value similarly. */ 1177dd7cddfSDavid du Colombier #define decode_frac(frac_value, cc, i)\ 1187dd7cddfSDavid du Colombier cc.paint.values[i] =\ 1197dd7cddfSDavid du Colombier penum->map[i].decode_base + (frac_value) * penum->map[i].decode_factor 1207dd7cddfSDavid du Colombier 1217dd7cddfSDavid du Colombier /* 1227dd7cddfSDavid du Colombier * Declare the pointer that holds the 12-bit unpacking procedure 1237dd7cddfSDavid du Colombier * if 12-bit samples are supported, 0 otherwise. 1247dd7cddfSDavid du Colombier */ 1257dd7cddfSDavid du Colombier extern const sample_unpack_proc_t sample_unpack_12_proc; 1267dd7cddfSDavid du Colombier 127*593dc095SDavid du Colombier /* 128*593dc095SDavid du Colombier * Declare the pointer that holds the 16-bit unpacking procedure 129*593dc095SDavid du Colombier * if 16-bit samples are supported, 0 otherwise. 130*593dc095SDavid du Colombier */ 131*593dc095SDavid du Colombier extern const sample_unpack_proc_t sample_unpack_16_proc; 132*593dc095SDavid du Colombier 1337dd7cddfSDavid du Colombier /* Define the distinct postures of an image. */ 1347dd7cddfSDavid du Colombier /* Each posture includes its reflected variant. */ 1357dd7cddfSDavid du Colombier typedef enum { 1367dd7cddfSDavid du Colombier image_portrait = 0, /* 0 or 180 degrees */ 1377dd7cddfSDavid du Colombier image_landscape, /* 90 or 270 degrees */ 1387dd7cddfSDavid du Colombier image_skewed /* any other transformation */ 1397dd7cddfSDavid du Colombier } image_posture; 1407dd7cddfSDavid du Colombier 1417dd7cddfSDavid du Colombier /* 1427dd7cddfSDavid du Colombier * Define an entry in the image color table. For single-source-plane 1437dd7cddfSDavid du Colombier * images, the table index is the sample value, and the key is not used; 1447dd7cddfSDavid du Colombier * for multiple-plane (color) images, the table index is a hash of the key, 1457dd7cddfSDavid du Colombier * which is the concatenation of the source pixel components. 1467dd7cddfSDavid du Colombier * "Clue" = Color LookUp Entry (by analogy with CLUT). 1477dd7cddfSDavid du Colombier */ 1487dd7cddfSDavid du Colombier typedef struct gx_image_clue_s { 1497dd7cddfSDavid du Colombier gx_device_color dev_color; 1507dd7cddfSDavid du Colombier bits32 key; 1517dd7cddfSDavid du Colombier } gx_image_clue; 1527dd7cddfSDavid du Colombier 1537dd7cddfSDavid du Colombier /* Main state structure */ 1547dd7cddfSDavid du Colombier 1557dd7cddfSDavid du Colombier #ifndef gx_device_clip_DEFINED 1567dd7cddfSDavid du Colombier # define gx_device_clip_DEFINED 1577dd7cddfSDavid du Colombier typedef struct gx_device_clip_s gx_device_clip; 1587dd7cddfSDavid du Colombier #endif 1597dd7cddfSDavid du Colombier 1607dd7cddfSDavid du Colombier #ifndef gx_device_rop_texture_DEFINED 1617dd7cddfSDavid du Colombier # define gx_device_rop_texture_DEFINED 1627dd7cddfSDavid du Colombier typedef struct gx_device_rop_texture_s gx_device_rop_texture; 1637dd7cddfSDavid du Colombier #endif 1647dd7cddfSDavid du Colombier 1657dd7cddfSDavid du Colombier struct gx_image_enum_s { 1667dd7cddfSDavid du Colombier gx_image_enum_common; 1677dd7cddfSDavid du Colombier /* We really want the map structure to be long-aligned, */ 1687dd7cddfSDavid du Colombier /* so we choose shorter types for some flags. */ 1697dd7cddfSDavid du Colombier /* Following are set at structure initialization */ 1707dd7cddfSDavid du Colombier byte bps; /* bits per sample: 1, 2, 4, 8, 12 */ 1717dd7cddfSDavid du Colombier byte unpack_bps; /* bps for computing unpack proc, */ 1727dd7cddfSDavid du Colombier /* set to 8 if no unpacking */ 1737dd7cddfSDavid du Colombier byte log2_xbytes; /* log2(bytes per expanded sample): */ 1747dd7cddfSDavid du Colombier /* 0 if bps <= 8, log2(sizeof(frac)) */ 1757dd7cddfSDavid du Colombier /* if bps > 8 */ 1767dd7cddfSDavid du Colombier byte spp; /* samples per pixel */ 1777dd7cddfSDavid du Colombier gs_image_alpha_t alpha; /* Alpha from image structure */ 1787dd7cddfSDavid du Colombier struct mc_ { 1797dd7cddfSDavid du Colombier uint values[GS_IMAGE_MAX_COMPONENTS * 2]; /* MaskColor values, */ 1807dd7cddfSDavid du Colombier /* always as ranges, guaranteed in range */ 1817dd7cddfSDavid du Colombier /* and in order (v0 <= v1) */ 1827dd7cddfSDavid du Colombier bits32 mask, test; /* (if spp > 1, bps <= 8) */ 1837dd7cddfSDavid du Colombier /* mask & test value for quick filtering */ 1847dd7cddfSDavid du Colombier bool exact; /* (if spp > 1, bps <= 8) */ 1857dd7cddfSDavid du Colombier /* if true, mask/test filter is exact */ 1867dd7cddfSDavid du Colombier } mask_color; /* (if ImageType 4) */ 1877dd7cddfSDavid du Colombier byte use_mask_color; /* true if color masking is being used */ 1887dd7cddfSDavid du Colombier /*byte num_planes; */ /* (in common part) */ 1897dd7cddfSDavid du Colombier byte spread; /* (spp if multi-plane, 1 if not) */ 1907dd7cddfSDavid du Colombier /* << log2_xbytes */ 1917dd7cddfSDavid du Colombier byte masked; /* 0 = [color]image, 1 = imagemask */ 1927dd7cddfSDavid du Colombier byte interpolate; /* true if Interpolate requested */ 1937dd7cddfSDavid du Colombier gs_matrix matrix; /* image space -> device space */ 1947dd7cddfSDavid du Colombier struct r_ { 1957dd7cddfSDavid du Colombier int x, y, w, h; /* subrectangle being rendered */ 1967dd7cddfSDavid du Colombier } rect; 1977dd7cddfSDavid du Colombier gs_fixed_point x_extent, y_extent; /* extent of one row of rect */ 1987dd7cddfSDavid du Colombier SAMPLE_UNPACK_PROC((*unpack)); 1997dd7cddfSDavid du Colombier irender_proc((*render)); 2007dd7cddfSDavid du Colombier const gs_imager_state *pis; 2017dd7cddfSDavid du Colombier const gs_color_space *pcs; /* color space of image */ 2027dd7cddfSDavid du Colombier gs_memory_t *memory; 2037dd7cddfSDavid du Colombier byte *buffer; /* for expanding samples to a */ 2047dd7cddfSDavid du Colombier /* byte or frac */ 2057dd7cddfSDavid du Colombier uint buffer_size; 2067dd7cddfSDavid du Colombier byte *line; /* buffer for an output scan line */ 2077dd7cddfSDavid du Colombier uint line_size; 2087dd7cddfSDavid du Colombier uint line_width; /* width of line in device pixels */ 2097dd7cddfSDavid du Colombier image_posture posture; 2107dd7cddfSDavid du Colombier byte use_rop; /* true if CombineWithColor requested */ 2117dd7cddfSDavid du Colombier byte clip_image; /* mask, see below */ 2127dd7cddfSDavid du Colombier /* Either we are clipping to a rectangle, in which case */ 2137dd7cddfSDavid du Colombier /* the individual x/y flags may be set, or we are clipping */ 2147dd7cddfSDavid du Colombier /* to a general region, in which case only clip_region */ 2157dd7cddfSDavid du Colombier /* is set. */ 2167dd7cddfSDavid du Colombier #define image_clip_xmin 1 2177dd7cddfSDavid du Colombier #define image_clip_xmax 2 2187dd7cddfSDavid du Colombier #define image_clip_ymin 4 2197dd7cddfSDavid du Colombier #define image_clip_ymax 8 2207dd7cddfSDavid du Colombier #define image_clip_region 0x10 2217dd7cddfSDavid du Colombier byte slow_loop; /* true if must use slower loop */ 2227dd7cddfSDavid du Colombier /* (if needed) */ 2237dd7cddfSDavid du Colombier byte device_color; /* true if device color space and */ 2247dd7cddfSDavid du Colombier /* standard decoding */ 2257dd7cddfSDavid du Colombier gs_fixed_rect clip_outer; /* outer box of clip path */ 2267dd7cddfSDavid du Colombier gs_fixed_rect clip_inner; /* inner box of clip path */ 2277dd7cddfSDavid du Colombier gs_logical_operation_t log_op; /* logical operation */ 2287dd7cddfSDavid du Colombier fixed adjust; /* adjustment when rendering */ 2297dd7cddfSDavid du Colombier /* characters */ 2307dd7cddfSDavid du Colombier fixed dxx, dxy; /* fixed versions of matrix */ 2317dd7cddfSDavid du Colombier /* components (as needed) */ 2327dd7cddfSDavid du Colombier gx_device_clip *clip_dev; /* clipping device (if needed) */ 2337dd7cddfSDavid du Colombier gx_device_rop_texture *rop_dev; /* RasterOp device (if needed) */ 2347dd7cddfSDavid du Colombier stream_image_scale_state *scaler; /* scale state for Interpolate */ 2357dd7cddfSDavid du Colombier /* (if needed) */ 2367dd7cddfSDavid du Colombier /* Following are updated dynamically */ 2377dd7cddfSDavid du Colombier int y; /* next source y */ 2387dd7cddfSDavid du Colombier gs_int_point used; /* amount of data already used, if */ 2397dd7cddfSDavid du Colombier /* interrupted by error */ 2407dd7cddfSDavid du Colombier gs_fixed_point cur, prev; /* device x, y of current & */ 2417dd7cddfSDavid du Colombier /* previous row */ 2427dd7cddfSDavid du Colombier struct dd_ { 2437dd7cddfSDavid du Colombier gx_dda_fixed_point row; /* DDA for row origin, has been */ 2447dd7cddfSDavid du Colombier /* advanced when render proc called */ 2457dd7cddfSDavid du Colombier gx_dda_fixed_point strip; /* row + rect.x */ 2467dd7cddfSDavid du Colombier gx_dda_fixed_point pixel0; /* DDA for first pixel to render, */ 2477dd7cddfSDavid du Colombier /* strip + used.x */ 2487dd7cddfSDavid du Colombier } dda; 2497dd7cddfSDavid du Colombier int line_xy; /* x or y value at start of buffered line */ 2507dd7cddfSDavid du Colombier int xi_next; /* expected xci of next row */ 2517dd7cddfSDavid du Colombier /* (landscape only) */ 2527dd7cddfSDavid du Colombier gs_int_point xyi; /* integer origin of row */ 2537dd7cddfSDavid du Colombier /* (Interpolate only) */ 2547dd7cddfSDavid du Colombier int yci, hci; /* integer y & h of row (portrait) */ 2557dd7cddfSDavid du Colombier int xci, wci; /* integer x & w of row (landscape) */ 2567dd7cddfSDavid du Colombier /* The maps are set at initialization. We put them here */ 2577dd7cddfSDavid du Colombier /* so that the scalars will have smaller offsets. */ 2587dd7cddfSDavid du Colombier sample_map map[GS_IMAGE_MAX_COMPONENTS]; 2597dd7cddfSDavid du Colombier /* Entries 0 and 255 of the following are set at initialization */ 2607dd7cddfSDavid du Colombier /* for monochrome images; other entries are updated dynamically. */ 2617dd7cddfSDavid du Colombier gx_image_clue clues[256]; 2627dd7cddfSDavid du Colombier #define icolor0 clues[0].dev_color 2637dd7cddfSDavid du Colombier #define icolor1 clues[255].dev_color 2647dd7cddfSDavid du Colombier }; 2657dd7cddfSDavid du Colombier 2667dd7cddfSDavid du Colombier /* Enumerate the pointers in an image enumerator. */ 2677dd7cddfSDavid du Colombier #define gx_image_enum_do_ptrs(m)\ 2687dd7cddfSDavid du Colombier m(0,pis) m(1,pcs) m(2,dev) m(3,buffer) m(4,line)\ 2697dd7cddfSDavid du Colombier m(5,clip_dev) m(6,rop_dev) m(7,scaler) 2707dd7cddfSDavid du Colombier #define gx_image_enum_num_ptrs 8 2717dd7cddfSDavid du Colombier #define private_st_gx_image_enum() /* in gsimage.c */\ 2727dd7cddfSDavid du Colombier gs_private_st_composite(st_gx_image_enum, gx_image_enum, "gx_image_enum",\ 2737dd7cddfSDavid du Colombier image_enum_enum_ptrs, image_enum_reloc_ptrs) 2747dd7cddfSDavid du Colombier 2757dd7cddfSDavid du Colombier /* Compare two device colors for equality. */ 2767dd7cddfSDavid du Colombier /* We can special-case this for speed later if we care. */ 2777dd7cddfSDavid du Colombier #define dev_color_eq(devc1, devc2)\ 2787dd7cddfSDavid du Colombier gx_device_color_equal(&(devc1), &(devc2)) 2797dd7cddfSDavid du Colombier 2807dd7cddfSDavid du Colombier /* 2817dd7cddfSDavid du Colombier * Scale a pair of mask_color values to match the scaling of each sample to 2827dd7cddfSDavid du Colombier * a full byte, and complement and swap them if the map incorporates 2837dd7cddfSDavid du Colombier * a Decode = [1 0] inversion. 2847dd7cddfSDavid du Colombier */ 285*593dc095SDavid du Colombier void gx_image_scale_mask_colors(gx_image_enum *penum, 286*593dc095SDavid du Colombier int component_index); 2877dd7cddfSDavid du Colombier 2887dd7cddfSDavid du Colombier /* 2897dd7cddfSDavid du Colombier * Do common initialization for processing an ImageType 1 or 4 image. 2907dd7cddfSDavid du Colombier * Allocate the enumerator and fill in the following members: 2917dd7cddfSDavid du Colombier * rect 2927dd7cddfSDavid du Colombier */ 2937dd7cddfSDavid du Colombier int 294*593dc095SDavid du Colombier gx_image_enum_alloc(const gs_image_common_t * pic, 2957dd7cddfSDavid du Colombier const gs_int_rect * prect, 296*593dc095SDavid du Colombier gs_memory_t * mem, gx_image_enum **ppenum); 2977dd7cddfSDavid du Colombier 2987dd7cddfSDavid du Colombier /* 2997dd7cddfSDavid du Colombier * Finish initialization for processing an ImageType 1 or 4 image. 3007dd7cddfSDavid du Colombier * Assumes the following members of *penum are set in addition to those 3017dd7cddfSDavid du Colombier * set by gx_image_enum_alloc: 3027dd7cddfSDavid du Colombier * alpha, use_mask_color, mask_color (if use_mask_color is true), 3037dd7cddfSDavid du Colombier * masked, adjust 3047dd7cddfSDavid du Colombier */ 3057dd7cddfSDavid du Colombier int 306*593dc095SDavid du Colombier gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis, 3077dd7cddfSDavid du Colombier const gs_matrix *pmat, const gs_image_common_t * pic, 3087dd7cddfSDavid du Colombier const gx_drawing_color * pdcolor, 3097dd7cddfSDavid du Colombier const gx_clip_path * pcpath, 310*593dc095SDavid du Colombier gs_memory_t * mem, gx_image_enum *penum); 311*593dc095SDavid du Colombier 312*593dc095SDavid du Colombier /* 313*593dc095SDavid du Colombier * Clear the relevant clues. Exported for use by image_render_* 314*593dc095SDavid du Colombier * when ht_tile cache is invalidated. 315*593dc095SDavid du Colombier */ 316*593dc095SDavid du Colombier void 317*593dc095SDavid du Colombier image_init_clues(gx_image_enum * penum, int bps, int spp); 3187dd7cddfSDavid du Colombier 3197dd7cddfSDavid du Colombier #endif /* gximage_INCLUDED */ 320