Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/pdf/pdf_misc.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2019-2022 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
/* Miscellaneous routines */
17
18
#include "pdf_int.h"
19
#include "pdf_stack.h"
20
#include "pdf_misc.h"
21
#include "pdf_font_types.h"
22
#include "pdf_gstate.h"
23
#include "gspath.h"             /* For gs_strokepath() */
24
#include "gspaint.h"            /* For gs_erasepage() */
25
#include "gsicc_manage.h"       /* For gsicc_get_default_type() */
26
#include "gsstate.h"            /* for gs_setrenderingintent() */
27
28
/* Get current bbox, possibly from stroking current path (utility function) */
29
int pdfi_get_current_bbox(pdf_context *ctx, gs_rect *bbox, bool stroked)
30
3.04k
{
31
3.04k
    int code, code1;
32
33
3.04k
    if (stroked) {
34
40
        code = pdfi_gsave(ctx);
35
40
        if (code < 0)
36
0
            return code;
37
40
        code = gs_strokepath(ctx->pgs);
38
40
        if (code < 0)
39
0
            goto exit;
40
40
    }
41
3.04k
    code = gs_upathbbox(ctx->pgs, bbox, false);
42
43
3.04k
 exit:
44
3.04k
    if (stroked) {
45
40
        code1 = pdfi_grestore(ctx);
46
40
        if (code == 0)
47
23
            code = code1;
48
40
    }
49
3.04k
    return code;
50
3.04k
}
51
52
/* Get the current color space (the base one) from a color space
53
 */
54
gs_color_space_index pdfi_get_color_space_index(pdf_context *ctx, const gs_color_space *pcs)
55
142k
{
56
142k
    gs_color_space_index csi;
57
58
    /* Get the color space index */
59
142k
    csi = gs_color_space_get_index(pcs);
60
61
    /* If its an Indexed space, then use the base space */
62
142k
    if (csi == gs_color_space_index_Indexed)
63
27
        csi = gs_color_space_get_index(pcs->base_space);
64
65
    /* If its ICC, see if its a substitution for one of the device
66
     * spaces. If so then we will want to behave as if we were using the
67
     * device space.
68
     */
69
142k
    if (csi == gs_color_space_index_ICC && pcs->cmm_icc_profile_data)
70
139k
        csi = gsicc_get_default_type(pcs->cmm_icc_profile_data);
71
72
142k
    return csi;
73
142k
}
74
75
/* Get the current color space (the base one) from current graphics state.
76
 * index -- tells whether to pull from 0 or 1 (probably 0)
77
 */
78
gs_color_space_index pdfi_currentcolorspace(pdf_context *ctx, int index)
79
142k
{
80
142k
    const gs_color_space *pcs;
81
82
142k
    pcs = ctx->pgs->color[index].color_space;
83
84
142k
    return pdfi_get_color_space_index(ctx, pcs);
85
142k
}
86
87
88
int
89
pdfi_name_strcmp(const pdf_name *n, const char *s)
90
13.7k
{
91
13.7k
    int len = strlen(s);
92
13.7k
    if (n->length == len)
93
13.6k
        return memcmp(n->data, s, len);
94
62
    return -1;
95
13.7k
}
96
97
bool
98
pdfi_string_is(const pdf_string *n, const char *s)
99
0
{
100
0
    int len = strlen(s);
101
0
    if (n->length == len)
102
0
        return (memcmp(n->data, s, len) == 0);
103
0
    return false;
104
0
}
105
106
bool
107
pdfi_name_is(const pdf_name *n, const char *s)
108
7.05G
{
109
7.05G
    int len = strlen(s);
110
7.05G
    if (n->length == len)
111
978M
        return (memcmp(n->data, s, len) == 0);
112
6.07G
    return false;
113
7.05G
}
114
115
int
116
pdfi_name_cmp(const pdf_name *n1, const pdf_name *n2)
117
60.3k
{
118
60.3k
    if (n1->length != n2->length)
119
206
        return -1;
120
60.1k
    return memcmp(n1->data, n2->data, n1->length);
121
60.3k
}
122
123
int
124
pdfi_string_cmp(const pdf_string *n1, const pdf_string *n2)
125
0
{
126
0
    if (n1->length != n2->length)
127
0
        return -1;
128
0
    return memcmp(n1->data, n2->data, n1->length);
129
0
}
130
131
/* Set rendering intent, translating from name to number */
132
int pdfi_setrenderingintent(pdf_context *ctx, pdf_name *n)
133
36.3k
{
134
36.3k
    int code = 0;
135
136
36.3k
    if (pdfi_name_is(n, "Perceptual")) {
137
28.1k
        code = gs_setrenderingintent(ctx->pgs, 0);
138
28.1k
    } else if (pdfi_name_is(n, "Saturation")) {
139
0
        code = gs_setrenderingintent(ctx->pgs, 2);
140
8.21k
    } else if (pdfi_name_is(n, "RelativeColorimetric")) {
141
7.78k
        code = gs_setrenderingintent(ctx->pgs, 1);
142
7.78k
    } else if (pdfi_name_is(n, "AbsoluteColorimetric")) {
143
0
        code = gs_setrenderingintent(ctx->pgs, 3);
144
430
    } else {
145
430
        code = gs_error_undefined;
146
430
    }
147
36.3k
    return code;
148
36.3k
}
149
150
int pdfi_string_from_name(pdf_context *ctx, pdf_name *n, char **str, int *len)
151
285k
{
152
285k
    if (pdfi_type_of(n) != PDF_NAME)
153
0
        return gs_note_error(gs_error_typecheck);
154
155
285k
    *str = NULL;
156
285k
    *len = 0;
157
158
285k
    *str = (char *)gs_alloc_bytes(ctx->memory, n->length + 1, "pdfi_string_from_name");
159
285k
    if (*str == NULL)
160
0
        return gs_note_error(gs_error_VMerror);
161
162
285k
    memcpy(*str, n->data, n->length);
163
285k
    (*str)[n->length] = 0x00;
164
285k
    *len = n->length;
165
166
285k
    return 0;
167
285k
}
168
169
int pdfi_free_string_from_name(pdf_context *ctx, char *str)
170
339k
{
171
339k
    if (str != NULL)
172
285k
        gs_free_object(ctx->memory, str, "pdfi_free_string_from_name");
173
339k
    return 0;
174
339k
}
175
176
void normalize_rectangle(double *d)
177
43.1k
{
178
43.1k
    double d1[4];
179
43.1k
    int i;
180
181
43.1k
    if (d[0] < d[2]) {
182
43.1k
        d1[0] = d[0];
183
43.1k
        d1[2] = d[2];
184
43.1k
    } else {
185
25
        d1[0] = d[2];
186
25
        d1[2] = d[0];
187
25
    }
188
43.1k
    if (d[1] < d[3]) {
189
43.1k
        d1[1] = d[1];
190
43.1k
        d1[3] = d[3];
191
43.1k
    } else {
192
2
        d1[1] = d[3];
193
2
        d1[3] = d[1];
194
2
    }
195
215k
    for (i=0;i<=3;i++){
196
172k
        d[i] = d1[i];
197
172k
    }
198
43.1k
}
199
200
/* Free an array of cstrings, sets the pointer to null */
201
void pdfi_free_cstring_array(pdf_context *ctx, char ***pstrlist)
202
81.7k
{
203
81.7k
    char **ptr = *pstrlist;
204
205
81.7k
    if (ptr == NULL)
206
81.7k
        return;
207
208
0
    while (*ptr) {
209
0
        gs_free_object(ctx->memory, *ptr, "pdfi_free_cstring_array(item)");
210
0
        ptr ++;
211
0
    }
212
0
    gs_free_object(ctx->memory, *pstrlist, "pdfi_free_cstring_array(array)");
213
0
    *pstrlist = NULL;
214
0
}
215
216
/* Parse an argument string of names into an array of cstrings */
217
/* Format: /Item1,/Item2,/Item3 (no white space) */
218
int pdfi_parse_name_cstring_array(pdf_context *ctx, char *data, uint64_t size, char ***pstrlist)
219
0
{
220
0
    char **strlist = NULL;
221
0
    char **templist = NULL;
222
0
    int numitems = 0, item;
223
0
    int strnum;
224
0
    uint64_t i;
225
0
    char *strptr;
226
0
    int code = 0;
227
228
    /* Free it if it already exists */
229
0
    if (*pstrlist != NULL)
230
0
        pdfi_free_cstring_array(ctx, pstrlist);
231
232
    /* find out how many '/' characters there are -- this is the max possible number
233
     * of items in the list
234
     */
235
0
    for (i=0, strptr = data; i<size; i++,strptr++) {
236
0
        if (*strptr == '/')
237
0
            numitems ++;
238
        /* early exit if we hit a null */
239
0
        if (*strptr == 0)
240
0
            break;
241
0
    }
242
243
    /* Allocate space for the array of char * (plus one extra for null termination) */
244
0
    strlist = (char **)gs_alloc_bytes(ctx->memory, (numitems+1)*sizeof(char *),
245
0
                                       "pdfi_parse_cstring_array(strlist)");
246
0
    if (strlist == NULL)
247
0
        return_error(gs_error_VMerror);
248
249
0
    memset(strlist, 0, (numitems+1)*sizeof(char *));
250
251
    /* Allocate a temp array */
252
0
    templist = (char **)gs_alloc_bytes(ctx->memory, (numitems+1)*sizeof(char *),
253
0
                                       "pdfi_parse_cstring_array(templist)");
254
0
    if (templist == NULL) {
255
0
        code = gs_note_error(gs_error_VMerror);
256
0
        goto exit;
257
0
    }
258
259
0
    memset(templist, 0, (numitems+1)*sizeof(char *));
260
261
    /* Find start ptr of each string */
262
0
    item = 0;
263
0
    for (i=0, strptr = data; i<size; i++,strptr++) {
264
0
        if (*strptr == '/') {
265
0
            templist[item] = strptr+1;
266
0
            item++;
267
0
        }
268
0
    }
269
270
    /* Find each substring, alloc, copy into string array */
271
0
    strnum = 0;
272
0
    for (i=0; i<numitems; i++) {
273
0
        char *curstr, *nextstr;
274
0
        int length;
275
0
        char *newstr;
276
277
0
        curstr = templist[i];
278
0
        nextstr = templist[i+1];
279
0
        if (!curstr)
280
0
            break;
281
0
        if (*curstr == '/' || *curstr == ',') {
282
            /* Empty string, skip it */
283
0
            continue;
284
0
        }
285
0
        if (nextstr == NULL) {
286
0
            length = size-(curstr-data);
287
0
        } else {
288
0
            length = nextstr - curstr - 1;
289
0
        }
290
0
        if (curstr[length-1] == ',')
291
0
            length --;
292
293
        /* Allocate the string and copy it */
294
0
        newstr = (char *)gs_alloc_bytes(ctx->memory, length+1,
295
0
                                       "pdfi_parse_cstring_array(newstr)");
296
0
        if (newstr == NULL) {
297
0
            code = gs_note_error(gs_error_VMerror);
298
0
            goto exit;
299
0
        }
300
0
        memcpy(newstr, curstr, length);
301
0
        newstr[length+1] = 0; /* Null terminate */
302
0
        strlist[strnum] = newstr;
303
0
        strnum ++;
304
0
    }
305
306
0
    *pstrlist = strlist;
307
308
0
 exit:
309
0
    if (code < 0)
310
0
        pdfi_free_cstring_array(ctx, &strlist);
311
0
    if (templist)
312
0
        gs_free_object(ctx->memory, templist, "pdfi_parse_cstring_array(templist(array))");
313
0
    return code;
314
0
}