Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gdevppla.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2021 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
/* Support for printer devices with planar buffering. */
18
#include "gdevprn.h"
19
#include "gdevmpla.h"
20
#include "gdevppla.h"
21
#include "gxdevsop.h"
22
23
/* Set the buf_procs in a printer device to planar mode. */
24
int
25
gdev_prn_set_procs_planar(gx_device *dev)
26
14.2k
{
27
14.2k
    gx_device_printer * const pdev = (gx_device_printer *)dev;
28
29
14.2k
    pdev->printer_procs.buf_procs.create_buf_device =
30
14.2k
        gdev_prn_create_buf_planar;
31
14.2k
    pdev->printer_procs.buf_procs.size_buf_device =
32
14.2k
        gdev_prn_size_buf_planar;
33
14.2k
    if (dev_proc(pdev, dev_spec_op) == gx_default_dev_spec_op)
34
0
        set_dev_proc(pdev, dev_spec_op, gdev_prn_dev_spec_op);
35
14.2k
    return 0;
36
14.2k
}
37
38
/* Open a printer device, conditionally setting it to be planar. */
39
int
40
gdev_prn_open_planar(gx_device *dev, bool upb)
41
22.1k
{
42
22.1k
    if (upb) {
43
14.2k
        gdev_prn_set_procs_planar(dev);
44
14.2k
        dev->is_planar = 1;
45
14.2k
    }
46
22.1k
    return gdev_prn_open(dev);
47
22.1k
}
48
49
/* Augment get/put_params to add UsePlanarBuffer. */
50
int
51
gdev_prn_get_params_planar(gx_device * pdev, gs_param_list * plist,
52
                           bool *pupb)
53
0
{
54
0
    int ecode = gdev_prn_get_params(pdev, plist);
55
56
0
    if (ecode < 0)
57
0
        return ecode;
58
0
    return param_write_bool(plist, "UsePlanarBuffer", pupb);
59
0
}
60
int
61
gdev_prn_put_params_planar(gx_device * pdev, gs_param_list * plist,
62
                           bool *pupb)
63
19.6k
{
64
19.6k
    bool upb = *pupb;
65
19.6k
    int ecode = 0, code;
66
67
19.6k
    if (pdev->color_info.num_components > 1)
68
0
        ecode = param_read_bool(plist, "UsePlanarBuffer", &upb);
69
19.6k
    code = gdev_prn_put_params(pdev, plist);
70
19.6k
    if (ecode >= 0)
71
19.6k
        ecode = code;
72
19.6k
    if (ecode >= 0)
73
19.6k
        *pupb = upb;
74
19.6k
    return ecode;
75
19.6k
}
76
77
/* Set the buffer device to planar mode. */
78
static int
79
gdev_prn_set_planar(gx_device_memory *mdev, const gx_device *tdev)
80
592k
{
81
592k
    int num_comp = tdev->color_info.num_components;
82
592k
    gx_render_plane_t planes[GX_DEVICE_COLOR_MAX_COMPONENTS];
83
592k
    int depth = tdev->color_info.depth / num_comp;
84
592k
    int k;
85
86
592k
    if (num_comp < 1 || num_comp > GX_DEVICE_COLOR_MAX_COMPONENTS)
87
0
        return_error(gs_error_rangecheck);
88
    /* Round up the depth per plane to a power of 2. */
89
592k
    while (depth & (depth - 1))
90
0
        --depth, depth = (depth | (depth >> 1)) + 1;
91
92
    /* We want the most significant plane to come out first. */
93
592k
    planes[num_comp-1].shift = 0;
94
592k
    planes[num_comp-1].depth = depth;
95
3.53M
    for (k = (num_comp - 2); k >= 0; k--) {
96
2.94M
        planes[k].depth = depth;
97
2.94M
        planes[k].shift = planes[k + 1].shift + depth;
98
2.94M
    }
99
592k
    return gdev_mem_set_planar(mdev, num_comp, planes);
100
592k
}
101
102
/* Create a planar buffer device. */
103
int
104
gdev_prn_create_buf_planar(gx_device **pbdev, gx_device *target, int y,
105
                           const gx_render_plane_t *render_plane,
106
                           gs_memory_t *mem, gx_color_usage_t *for_band)
107
568k
{
108
568k
    int code = gx_default_create_buf_device(pbdev, target, y, render_plane, mem,
109
568k
                                            for_band);
110
111
568k
    if (code < 0)
112
0
        return code;
113
568k
    if (gs_device_is_memory(*pbdev) /* == render_plane->index < 0 */) {
114
568k
        code = gdev_prn_set_planar((gx_device_memory *)*pbdev, *pbdev);
115
568k
    }
116
568k
    return code;
117
568k
}
118
119
/* Determine the space needed by a planar buffer device. */
120
int
121
gdev_prn_size_buf_planar(gx_device_buf_space_t *space, gx_device *target,
122
                         const gx_render_plane_t *render_plane,
123
                         int height, bool for_band)
124
23.9k
{
125
23.9k
    gx_device_memory mdev;
126
23.9k
    int code;
127
128
23.9k
    if (render_plane && render_plane->index >= 0)
129
0
        return gx_default_size_buf_device(space, target, render_plane,
130
0
                                          height, for_band);
131
23.9k
    mdev.color_info = target->color_info;
132
23.9k
    mdev.pad = target->pad;
133
23.9k
    mdev.log2_align_mod = target->log2_align_mod;
134
23.9k
    mdev.is_planar = target->is_planar;
135
23.9k
    mdev.graphics_type_tag = target->graphics_type_tag;
136
23.9k
    code = gdev_prn_set_planar(&mdev, target);
137
23.9k
    if (code < 0)
138
0
        return code;
139
23.9k
    if (gdev_mem_bits_size(&mdev, target->width, height, &(space->bits)) < 0)
140
0
        return_error(gs_error_VMerror);
141
23.9k
    space->line_ptrs = gdev_mem_line_ptrs_size(&mdev, target->width, height);
142
23.9k
    space->raster = bitmap_raster_pad_align(target->width * mdev.planes[0].depth, mdev.pad, mdev.log2_align_mod);
143
23.9k
    return 0;
144
23.9k
}