Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/psi/zfunc3.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
/* PostScript language interface to LL3 Functions */
18
#include "memory_.h"
19
#include "ghost.h"
20
#include "oper.h"
21
#include "gsfunc3.h"
22
#include "gsstruct.h"
23
#include "stream.h"   /* for files.h */
24
#include "files.h"
25
#include "ialloc.h"
26
#include "idict.h"
27
#include "idparam.h"
28
#include "ifunc.h"
29
#include "store.h"
30
#include "igstate.h"
31
32
/* Check prototypes */
33
build_function_proc(gs_build_function_2);
34
build_function_proc(gs_build_function_3);
35
36
/* Finish building a FunctionType 2 (ExponentialInterpolation) function. */
37
int
38
gs_build_function_2(i_ctx_t *i_ctx_p, const ref *op, const gs_function_params_t * mnDR,
39
                    int depth, gs_function_t ** ppfn, gs_memory_t *mem)
40
0
{
41
0
    gs_function_ElIn_params_t params;
42
0
    int code, n0, n1;
43
44
0
    *(gs_function_params_t *)&params = *mnDR;
45
0
    params.C0 = 0;
46
0
    params.C1 = 0;
47
0
    if ((code = dict_float_param(op, "N", 0.0, &params.N)) != 0 ||
48
0
        (code = n0 = fn_build_float_array_forced(op, "C0", false, &params.C0, mem)) < 0 ||
49
0
        (code = n1 = fn_build_float_array_forced(op, "C1", false, &params.C1, mem)) < 0
50
0
        )
51
0
        goto fail;
52
0
    if (params.C0 == 0)
53
0
        n0 = 1;     /* C0 defaulted */
54
0
    if (params.C1 == 0)
55
0
        n1 = 1;     /* C1 defaulted */
56
0
    if (params.Range == 0)
57
0
        params.n = n0;   /* either one will do */
58
0
    if (n0 != n1 || n0 != params.n)
59
0
        goto fail;
60
0
    code = gs_function_ElIn_init(ppfn, &params, mem);
61
0
    if (code >= 0)
62
0
        return 0;
63
0
fail:
64
0
    gs_function_ElIn_free_params(&params, mem);
65
0
    return (code < 0 ? code : gs_note_error(gs_error_rangecheck));
66
0
}
67
68
/* Finish building a FunctionType 3 (1-Input Stitching) function. */
69
int
70
gs_build_function_3(i_ctx_t *i_ctx_p, const ref *op, const gs_function_params_t * mnDR,
71
                    int depth, gs_function_t ** ppfn, gs_memory_t *mem)
72
0
{
73
0
    gs_function_1ItSg_params_t params;
74
0
    int code;
75
76
0
    *(gs_function_params_t *) & params = *mnDR;
77
0
    params.Functions = 0;
78
0
    params.Bounds = 0;
79
0
    params.Encode = 0;
80
0
    {
81
0
        ref *pFunctions;
82
0
        gs_function_t **ptr;
83
0
        int i;
84
85
0
        if ((code = dict_find_string(op, "Functions", &pFunctions)) <= 0)
86
0
            return (code < 0 ? code : gs_note_error(gs_error_rangecheck));
87
0
        check_array_only(*pFunctions);
88
0
        params.k = r_size(pFunctions);
89
0
        code = alloc_function_array(params.k, &ptr, mem);
90
0
        if (code < 0)
91
0
            return code;
92
0
        params.Functions = (const gs_function_t * const *)ptr;
93
0
        for (i = 0; i < params.k; ++i) {
94
0
            ref subfn;
95
96
0
            array_get(mem, pFunctions, (long)i, &subfn);
97
0
            code = fn_build_sub_function(i_ctx_p, &subfn, &ptr[i], depth, mem, 0, 0);
98
0
            if (code < 0)
99
0
                goto fail;
100
0
        }
101
0
    }
102
0
    if ((code = fn_build_float_array(op, "Bounds", true, false, &params.Bounds, mem)) != params.k - 1)
103
0
        goto fail;
104
0
    if (gs_currentcpsimode(imemory)) {
105
        /* Adobe implementation doesn't check the Encode length. */
106
        /* Extra elements are ignored; missing elements are filled with 0. */
107
        /* CET 12-14m.ps depends on this bug */
108
0
        uint sz, k2 = 2 * params.k;
109
0
        ref *encode;
110
0
        float *p = (float *)gs_alloc_byte_array(mem, k2, sizeof(float), "Encode");
111
112
0
        params.Encode = p;
113
0
        if (p == 0) {
114
0
            code = gs_note_error(gs_error_VMerror);
115
0
            goto fail;
116
0
        }
117
0
        if (dict_find_string(op, "Encode", &encode) <= 0) {
118
0
            code = gs_note_error(gs_error_undefined);
119
0
            goto fail;
120
0
        }
121
0
        if (!r_is_array(encode)) {
122
0
            code = gs_note_error(gs_error_typecheck);
123
0
            goto fail;
124
0
        }
125
0
        sz =  min(k2, r_size(encode));
126
0
        code = process_float_array(mem, encode, sz, p);
127
0
        if (code < 0)
128
0
            goto fail;
129
0
        while (sz < k2)
130
0
            p[sz++] = 0.0;
131
0
    } else if ((code = fn_build_float_array(op, "Encode", true, true, &params.Encode, mem)) != 2 * params.k)
132
0
        goto fail;
133
0
    if (params.Range == 0)
134
0
        params.n = params.Functions[0]->params.n;
135
0
    code = gs_function_1ItSg_init(ppfn, &params, mem);
136
0
    if (code >= 0)
137
0
        return 0;
138
0
fail:
139
0
    gs_function_1ItSg_free_params(&params, mem);
140
0
    return (code < 0 ? code : gs_note_error(gs_error_rangecheck));
141
0
}