1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 #ifndef gxdownscale_INCLUDED
18 #define gxdownscale_INCLUDED
19 
20 #include "ctype_.h"
21 #include "gsmemory.h"
22 #include "gstypes.h"
23 #include "gxdevcli.h"
24 #include "gxgetbit.h"
25 
26 #include "claptrap.h"
27 
28 /* Function to apply color management to a rectangle of data.
29  *
30  * dst/src point to arrays of pointers, 1 per component.
31  * In the chunky case, only the first pointer is valid.
32  * In the planar case, with n planes, the first n pointers
33  * are valid.
34  * w and h are the width and height of the rectangle of
35  * data to be processed.
36  * raster is the number of bytes to offset from the start
37  * of one line to the next. This value should be ignored
38  * in chunky cases.
39  */
40 typedef int (gx_downscale_cm_fn)(void  *arg,
41                                  byte **dst,
42                                  byte **src,
43                                  int    w,
44                                  int    h,
45                                  int    raster);
46 
47 typedef struct gx_downscaler_ht_s
48 {
49     int w;
50     int h;
51     int stride;
52     int x_phase;
53     int y_phase;
54     byte *data;
55 } gx_downscaler_ht_t;
56 
57 /* The following structure definitions should really be considered
58  * private, and are exposed here only because it enables us to define
59  * gx_downscaler_t's on the stack, thus avoiding mallocs.
60  */
61 
62 typedef struct gx_downscaler_s gx_downscaler_t;
63 
64 /* Private function type for the core downscaler routines */
65 typedef void (gx_downscale_core)(gx_downscaler_t *ds,
66                                  byte            *out_buffer,
67                                  byte            *in_buffer,
68                                  int              row,
69                                  int              plane,
70                                  int              span);
71 
72 struct gx_downscaler_s {
73     gx_device            *dev;        /* Device */
74     int                   width;      /* Width (pixels) */
75     int                   awidth;     /* Adjusted width (pixels) */
76     int                   span;       /* Num bytes in unscaled scanline */
77     int                   factor;     /* Factor to downscale */
78     byte                 *mfs_data;   /* MinFeatureSize data */
79     int                   src_bpc;    /* Source bpc */
80     int                   dst_bpc;    /* Destination bpc */
81     int                  *errors;     /* Error diffusion table */
82     byte                 *scaled_data;/* Downscaled data (only used for non
83                                        * integer downscales). */
84     int                   scaled_span;/* Num bytes in scaled scanline */
85     gx_downscale_core    *down_core;  /* Core downscaling function */
86     gs_get_bits_params_t  params;     /* Params if in planar mode */
87     int                   num_comps;  /* Number of components as rendered */
88     int                   num_planes; /* Number of planes if planar, 0 otherwise */
89 
90     ClapTrap             *claptrap;   /* ClapTrap pointer (if trapping) */
91     int                   claptrap_y; /* y pointer (if trapping) */
92     gs_get_bits_params_t *claptrap_params; /* params (if trapping) */
93 
94     int                   early_cm;
95     gx_downscale_cm_fn   *apply_cm;
96     void                 *apply_cm_arg;
97     int                   post_cm_num_comps;
98 
99     void                 *ets_config;
100     gx_downscale_core    *ets_downscale;
101 
102     byte                 *pre_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
103     byte                 *post_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
104 
105     gx_downscaler_ht_t   *ht;
106     byte                 *htrow;
107     byte                 *htrow_alloc;
108     byte                 *inbuf;
109     byte                 *inbuf_alloc;
110 };
111 
112 /* To use the downscaler:
113  *
114  *  + define a gx_downscaler_t on the stack.
115  *  + initialise it with gx_downscaler_init or gx_downscaler_init_planar
116  *  + repeatedly call gx_downscaler_get_lines (or
117  *    gx_downscaler_copy_scan_lines) (for chunky mode) or
118  *    gx_downscaler_get_bits_rectangle (for planar mode)
119  *  + finalise with gx_downscaler_fin
120  */
121 
122 /* For chunky mode, currently only:
123  *   src_bpc ==  8 && dst_bpc ==  1 && num_comps == 1
124  *   src_bpc ==  8 && dst_bpc ==  8 && num_comps == 1
125  *   src_bpc ==  8 && dst_bpc ==  8 && num_comps == 3
126  *   src_bpc == 16 && dst_bpc == 16 && num_comps == 1
127  * are supported. mfs is ignored for all except the first of these.
128  * For planar mode, currently only:
129  *   src_bpp ==  8 && dst_bpp ==  1
130  *   src_bpp ==  8 && dst_bpp ==  8
131  *   src_bpp == 16 && dst_bpp == 16
132  * are supported.
133  */
134 int gx_downscaler_init(gx_downscaler_t   *ds,
135                        gx_device         *dev,
136                        int                src_bpc,
137                        int                dst_bpc,
138                        int                num_comps,
139                        int                factor,
140                        int                mfs,
141                        int              (*adjust_width_proc)(int, int),
142                        int                adjust_width);
143 
144 int gx_downscaler_init_ets(gx_downscaler_t   *ds,
145                            gx_device         *dev,
146                            int                src_bpc,
147                            int                dst_bpc,
148                            int                num_comps,
149                            int                factor,
150                            int                mfs,
151                            int              (*adjust_width_proc)(int, int),
152                            int                adjust_width,
153                            int                ets);
154 
155 int gx_downscaler_init_trapped(gx_downscaler_t   *ds,
156                                gx_device         *dev,
157                                int                src_bpc,
158                                int                dst_bpc,
159                                int                num_comps,
160                                int                factor,
161                                int                mfs,
162                                int              (*adjust_width_proc)(int, int),
163                                int                adjust_width,
164                                int                trap_w,
165                                int                trap_h,
166                                const int         *comp_order);
167 
168 int gx_downscaler_init_trapped_ets(gx_downscaler_t   *ds,
169                                    gx_device         *dev,
170                                    int                src_bpc,
171                                    int                dst_bpc,
172                                    int                num_comps,
173                                    int                factor,
174                                    int                mfs,
175                                    int              (*adjust_width_proc)(int, int),
176                                    int                adjust_width,
177                                    int                trap_w,
178                                    int                trap_h,
179                                    const int         *comp_order,
180                                    int                ets);
181 
182 int gx_downscaler_init_cm(gx_downscaler_t    *ds,
183                           gx_device          *dev,
184                           int                 src_bpc,
185                           int                 dst_bpc,
186                           int                 num_comps,
187                           int                 factor,
188                           int                 mfs,
189                           int               (*adjust_width_proc)(int, int),
190                           int                 adjust_width,
191                           gx_downscale_cm_fn *apply_cm,
192                           void               *apply_cm_arg,
193                           int                 post_cm_num_comps);
194 
195 int gx_downscaler_init_cm_ets(gx_downscaler_t    *ds,
196                               gx_device          *dev,
197                               int                 src_bpc,
198                               int                 dst_bpc,
199                               int                 num_comps,
200                               int                 factor,
201                               int                 mfs,
202                               int               (*adjust_width_proc)(int, int),
203                               int                 adjust_width,
204                               gx_downscale_cm_fn *apply_cm,
205                               void               *apply_cm_arg,
206                               int                 post_cm_num_comps,
207                               int                 ets);
208 
209 int gx_downscaler_init_trapped_cm(gx_downscaler_t    *ds,
210                                   gx_device          *dev,
211                                   int                 src_bpc,
212                                   int                 dst_bpc,
213                                   int                 num_comps,
214                                   int                 factor,
215                                   int                 mfs,
216                                   int               (*adjust_width_proc)(int, int),
217                                   int                 adjust_width,
218                                   int                 trap_w,
219                                   int                 trap_h,
220                                   const int          *comp_order,
221                                   gx_downscale_cm_fn *apply_cm,
222                                   void               *apply_cm_arg,
223                                   int                 post_cm_num_comps);
224 
225 int gx_downscaler_init_trapped_cm_ets(gx_downscaler_t    *ds,
226                                       gx_device          *dev,
227                                       int                 src_bpc,
228                                       int                 dst_bpc,
229                                       int                 num_comps,
230                                       int                 factor,
231                                       int                 mfs,
232                                       int               (*adjust_width_proc)(int, int),
233                                       int                 adjust_width,
234                                       int                 trap_w,
235                                       int                 trap_h,
236                                       const int          *comp_order,
237                                       gx_downscale_cm_fn *apply_cm,
238                                       void               *apply_cm_arg,
239                                       int                 post_cm_num_comps,
240                                       int                 ets);
241 
242 int gx_downscaler_init_trapped_cm_halftone(gx_downscaler_t    *ds,
243                                            gx_device          *dev,
244                                            int                 src_bpc,
245                                            int                 dst_bpc,
246                                            int                 num_comps,
247                                            int                 factor,
248                                            int                 mfs,
249                                            int               (*adjust_width_proc)(int, int),
250                                            int                 adjust_width,
251                                            int                 trap_w,
252                                            int                 trap_h,
253                                            const int          *comp_order,
254                                            gx_downscale_cm_fn *apply_cm,
255                                            void               *apply_cm_arg,
256                                            int                 post_cm_num_comps,
257                                            gx_downscaler_ht_t *ht);
258 
259 int gx_downscaler_init_planar(gx_downscaler_t      *ds,
260                               gx_device            *dev,
261                               gs_get_bits_params_t *params,
262                               int                   num_comps,
263                               int                   factor,
264                               int                   mfs,
265                               int                   src_bpc,
266                               int                   dst_bpc);
267 
268 int gx_downscaler_init_planar_trapped(gx_downscaler_t      *ds,
269                                       gx_device            *dev,
270                                       gs_get_bits_params_t *params,
271                                       int                   num_comps,
272                                       int                   factor,
273                                       int                   mfs,
274                                       int                   src_bpc,
275                                       int                   dst_bpc,
276                                       int                   trap_w,
277                                       int                   trap_h,
278                                       const int            *comp_order);
279 
280 int gx_downscaler_init_planar_cm(gx_downscaler_t      *ds,
281                                  gx_device            *dev,
282                                  gs_get_bits_params_t *params,
283                                  int                   num_comps,
284                                  int                   factor,
285                                  int                   mfs,
286                                  int                   src_bpc,
287                                  int                   dst_bpc,
288                                  gx_downscale_cm_fn   *apply_cm,
289                                  void                 *apply_cm_arg,
290                                  int                   post_cm_num_comps);
291 
292 int gx_downscaler_init_planar_trapped_cm(gx_downscaler_t      *ds,
293                                          gx_device            *dev,
294                                          gs_get_bits_params_t *params,
295                                          int                   num_comps,
296                                          int                   factor,
297                                          int                   mfs,
298                                          int                   src_bpc,
299                                          int                   dst_bpc,
300                                          int                   trap_w,
301                                          int                   trap_h,
302                                          const int            *comp_order,
303                                          gx_downscale_cm_fn   *apply_cm,
304                                          void                 *apply_cm_arg,
305                                          int                   post_cm_num_comps);
306 
307 int gx_downscaler_getbits(gx_downscaler_t *ds,
308                           byte            *out_data,
309                           int              row);
310 
311 int gx_downscaler_get_bits_rectangle(gx_downscaler_t      *ds,
312                                      gs_get_bits_params_t *params,
313                                      int                   row);
314 
315 /* Must only fin a device that has been inited (though you can safely
316  * fin several times) */
317 void gx_downscaler_fin(gx_downscaler_t *ds);
318 
319 int
320 gx_downscaler_scale(int width, int factor);
321 
322 int
323 gx_downscaler_scale_rounded(int width, int factor);
324 
325 int gx_downscaler_adjust_bandheight(int factor, int band_height);
326 
327 /* Downscaling call to the process_page (downscaler also works on the
328  * rendering threads and chains calls through to supplied options functions).
329  */
330 int gx_downscaler_process_page(gx_device                 *dev,
331                                gx_process_page_options_t *options,
332                                int                        factor);
333 
334 /* The following structure is used to hold the configuration
335  * parameters for the downscaler.
336  */
337 typedef struct gx_downscaler_params_s
338 {
339     int downscale_factor;
340     int min_feature_size;
341     int trap_w;
342     int trap_h;
343     int trap_order[GS_CLIENT_COLOR_MAX_COMPONENTS];
344     int ets;
345 } gx_downscaler_params;
346 
347 #define GX_DOWNSCALER_PARAMS_DEFAULTS \
348 { 1, 0, 0, 0, { 3, 1, 0, 2 } }
349 
350 enum {
351     GX_DOWNSCALER_PARAMS_MFS = 1,
352     GX_DOWNSCALER_PARAMS_TRAP = 2,
353     GX_DOWNSCALER_PARAMS_ETS = 4
354 };
355 
356 int gx_downscaler_read_params(gs_param_list        *plist,
357                               gx_downscaler_params *params,
358                               int                   features);
359 
360 int gx_downscaler_write_params(gs_param_list        *plist,
361                                gx_downscaler_params *params,
362                                int                   features);
363 
364 #endif
365