Coverage Report

Created: 2025-06-10 07:06

/src/ghostpdl/base/gxmclip.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Mask clipping support */
18
#include "gx.h"
19
#include "gserrors.h"
20
#include "gxdevice.h"
21
#include "gxdevmem.h"
22
#include "gxmclip.h"
23
24
/* Structure descriptor */
25
public_st_device_mask_clip();
26
27
/* GC procedures */
28
0
static ENUM_PTRS_WITH(device_mask_clip_enum_ptrs, gx_device_mask_clip *mcdev)
29
0
{
30
0
    if (index < st_gx_strip_bitmap_max_ptrs) {
31
0
        return ENUM_USING(st_gx_strip_bitmap, &mcdev->tiles,
32
0
                          sizeof(mcdev->tiles), index);
33
0
    }
34
0
    index -= st_gx_strip_bitmap_max_ptrs;
35
0
    if (index < st_device_memory_max_ptrs) {
36
0
        return ENUM_USING(st_device_memory, &mcdev->mdev,
37
0
                          sizeof(mcdev->mdev), index);
38
0
    }
39
0
    ENUM_PREFIX(st_device_forward, st_device_memory_max_ptrs);
40
0
}
41
0
ENUM_PTRS_END
42
0
static RELOC_PTRS_WITH(device_mask_clip_reloc_ptrs, gx_device_mask_clip *mcdev)
43
0
{
44
0
    RELOC_PREFIX(st_device_forward);
45
0
    RELOC_USING(st_gx_strip_bitmap, &mcdev->tiles, sizeof(mcdev->tiles));
46
0
    RELOC_USING(st_device_memory, &mcdev->mdev, sizeof(mcdev->mdev));
47
0
    if (mcdev->mdev.base != 0) {
48
        /*
49
         * Update the line pointers specially, since they point into the
50
         * buffer that is part of the mask clipping device itself.
51
         */
52
0
        long diff = (char *)RELOC_OBJ(mcdev) - (char *)mcdev;
53
0
        int i;
54
55
0
        for (i = 0; i < mcdev->mdev.height; ++i)
56
0
            mcdev->mdev.line_ptrs[i] += diff;
57
0
        mcdev->mdev.base = mcdev->mdev.line_ptrs[0];
58
0
        mcdev->mdev.line_ptrs =
59
0
            (void *)((char *)(mcdev->mdev.line_ptrs) + diff);
60
0
    }
61
0
}
62
0
RELOC_PTRS_END
63
64
/* Initialize a mask clipping device. */
65
int
66
gx_mask_clip_initialize(gx_device_mask_clip * cdev,
67
                        const gx_device_mask_clip * proto,
68
                        const gx_bitmap * bits, gx_device * tdev,
69
                        int tx, int ty, gs_memory_t *mem)
70
21.3k
{
71
21.3k
    int buffer_width = bits->size.x;
72
21.3k
    int buffer_height =
73
21.3k
        tile_clip_buffer_size / (bits->raster + sizeof(byte *));
74
75
21.3k
    if (mem == NULL)
76
21.3k
        gx_device_init_on_stack((gx_device *)cdev,
77
21.3k
                                (const gx_device *)proto,
78
21.3k
                                tdev->memory);
79
17
    else
80
17
        (void)gx_device_init((gx_device *)cdev,
81
17
                             (const gx_device *)proto,
82
17
                             mem, true);
83
21.3k
    cdev->width = tdev->width;
84
21.3k
    cdev->height = tdev->height;
85
21.3k
    cdev->color_info = tdev->color_info;
86
21.3k
    gx_device_set_target((gx_device_forward *)cdev, tdev);
87
21.3k
    cdev->phase.x = -tx;
88
21.3k
    cdev->phase.y = -ty;
89
21.3k
    if (buffer_height > bits->size.y)
90
18.5k
        buffer_height = bits->size.y;
91
21.3k
    gs_make_mem_mono_device(&cdev->mdev, 0, 0);
92
21.3k
    for (;;) {
93
21.3k
        size_t bitmap_size = max_ulong;
94
95
        /* Bug 702124: Allow for the case when size.y == 0 - then
96
         * buffer_height will be zero, and it's not a VMerror. */
97
21.3k
        if (bits->size.y > 0 && buffer_height <= 0) {
98
            /*
99
             * The tile is too wide to buffer even one scan line.
100
             * We could do copy_mono in chunks, but for now, we punt.
101
             */
102
0
            cdev->mdev.base = 0;
103
0
            return_error(gs_error_VMerror);
104
0
        }
105
21.3k
        cdev->mdev.width = buffer_width;
106
21.3k
        cdev->mdev.height = buffer_height;
107
21.3k
        gdev_mem_bitmap_size(&cdev->mdev, &bitmap_size);
108
21.3k
        if (bitmap_size <= tile_clip_buffer_size)
109
21.3k
            break;
110
0
        buffer_height--;
111
0
    }
112
21.3k
    cdev->mdev.base = cdev->buffer.bytes;
113
21.3k
    return (*dev_proc(&cdev->mdev, open_device))((gx_device *)&cdev->mdev);
114
21.3k
}