Coverage Report

Created: 2025-06-24 07:01

/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
246k
{
71
246k
    int buffer_width = bits->size.x;
72
246k
    int buffer_height =
73
246k
        tile_clip_buffer_size / (bits->raster + sizeof(byte *));
74
75
246k
    if (mem == NULL)
76
246k
        gx_device_init_on_stack((gx_device *)cdev,
77
246k
                                (const gx_device *)proto,
78
246k
                                tdev->memory);
79
321
    else
80
321
        (void)gx_device_init((gx_device *)cdev,
81
321
                             (const gx_device *)proto,
82
321
                             mem, true);
83
246k
    cdev->width = tdev->width;
84
246k
    cdev->height = tdev->height;
85
246k
    cdev->color_info = tdev->color_info;
86
246k
    gx_device_set_target((gx_device_forward *)cdev, tdev);
87
246k
    cdev->phase.x = -tx;
88
246k
    cdev->phase.y = -ty;
89
246k
    if (buffer_height > bits->size.y)
90
174k
        buffer_height = bits->size.y;
91
246k
    gs_make_mem_mono_device(&cdev->mdev, 0, 0);
92
246k
    for (;;) {
93
246k
        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
246k
        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
1
            cdev->mdev.base = 0;
103
1
            return_error(gs_error_VMerror);
104
1
        }
105
246k
        cdev->mdev.width = buffer_width;
106
246k
        cdev->mdev.height = buffer_height;
107
246k
        gdev_mem_bitmap_size(&cdev->mdev, &bitmap_size);
108
246k
        if (bitmap_size <= tile_clip_buffer_size)
109
246k
            break;
110
0
        buffer_height--;
111
0
    }
112
246k
    cdev->mdev.base = cdev->buffer.bytes;
113
246k
    return (*dev_proc(&cdev->mdev, open_device))((gx_device *)&cdev->mdev);
114
246k
}