Coverage Report

Created: 2025-06-10 07:15

/src/ghostpdl/base/gscencs.c
Line
Count
Source
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
/* Compact C representation of built-in encodings */
18
19
#include "memory_.h"
20
#include "gscedata.h"
21
#include "gscencs.h"
22
#include "gserrors.h"
23
24
/*
25
 * The actual encoding data tables in gscedata.c, and the internal
26
 * interface definitions in gscedata.h, are generated by toolbin/encs2c.ps,
27
 * q.v.
28
 *
29
 * In the encoding tables in gscedata.c, each glyph is represented by a
30
 * ushort (16-bit) value.  A bias of gs_c_min_std_encoding_glyph is added
31
 * or subtracted to form a gs_glyph value.
32
 */
33
34
/*
35
 * gscedata.[hc] defines the following tables:
36
 *  const char gs_c_known_encoding_chars[NUM_CHARS] --
37
 *    the character table.
38
 *  const int gs_c_known_encoding_offsets[NUM_INDIRECT_LEN] --
39
 *    the starting offsets of the names of a given length in the
40
 *    character table.
41
 *  const ushort *const gs_c_known_encodings[] --
42
 *    pointers to the encodings per se.
43
 *  const ushort gs_c_known_encoding_lengths[] --
44
 *    lengths of the encodings.
45
 */
46
47
const gs_glyph gs_c_min_std_encoding_glyph = GS_MIN_CID_GLYPH - 0x10000;
48
49
/*
50
 * Encode a character in a known encoding.  The only use for glyph numbers
51
 * returned by this procedure is to pass them to gs_c_glyph_name or gs_c_decode.
52
 */
53
gs_glyph
54
gs_c_known_encode(gs_char ch, int ei)
55
14.8M
{
56
14.8M
    if (ei < 0 || ei >= gs_c_known_encoding_count ||
57
14.8M
        ch >= gs_c_known_encoding_lengths[ei]
58
14.8M
        )
59
1.05k
        return GS_NO_GLYPH;
60
14.8M
    return gs_c_min_std_encoding_glyph + gs_c_known_encodings[ei][ch];
61
14.8M
}
62
63
/*
64
 * Decode a gs_c_glyph_name glyph with a known encoding.
65
 */
66
gs_char
67
gs_c_decode(gs_glyph glyph, int ei)
68
84.4k
{
69
    /* Do a binary search for glyph, using gx_c_known_encodings_reverse */
70
84.4k
    const ushort *const encoding = gs_c_known_encodings[ei];
71
84.4k
    const ushort *const reverse = gs_c_known_encodings_reverse[ei];
72
84.4k
    int first_index = 0;
73
84.4k
    int last_index = gs_c_known_encoding_reverse_lengths[ei];
74
577k
    while (first_index < last_index) {
75
575k
        const int test_index = (first_index + last_index) / 2;
76
575k
        const gs_glyph test_glyph =
77
575k
         gs_c_min_std_encoding_glyph + encoding[reverse[test_index]];
78
575k
        if (glyph < test_glyph)
79
282k
            last_index = test_index;
80
292k
        else if (glyph > test_glyph)
81
210k
            first_index = test_index + 1;
82
82.3k
        else
83
82.3k
            return reverse[test_index];
84
575k
    }
85
2.17k
    return GS_NO_CHAR;
86
84.4k
}
87
88
/*
89
 * Convert a glyph number returned by gs_c_known_encode to a string.
90
 */
91
int
92
gs_c_glyph_name(gs_glyph glyph, gs_const_string *pstr)
93
18.1M
{
94
18.1M
    uint n = (uint)(glyph - gs_c_min_std_encoding_glyph);
95
18.1M
    uint len = N_LEN(n);
96
18.1M
    uint off = N_OFFSET(n);
97
98
#ifdef DEBUG
99
    if (len == 0 || len > gs_c_known_encoding_max_length ||
100
        off >= gs_c_known_encoding_offsets[len + 1] -
101
          gs_c_known_encoding_offsets[len] ||
102
        off % len != 0
103
        )
104
        return_error(gs_error_rangecheck);
105
#endif
106
18.1M
    pstr->data = (const byte *)
107
18.1M
        &gs_c_known_encoding_chars[gs_c_known_encoding_offsets[len] + off];
108
18.1M
    pstr->size = len;
109
18.1M
    return 0;
110
18.1M
}
111
112
/*
113
 * Test whether a string is one that was returned by gs_c_glyph_name.
114
 */
115
bool
116
gs_is_c_glyph_name(const byte *str, uint len)
117
20.3M
{
118
20.3M
    return str >= (const byte *)gs_c_known_encoding_chars &&
119
20.3M
           str <  (const byte *)gs_c_known_encoding_chars + gs_c_known_encoding_total_chars;
120
20.3M
}
121
122
/*
123
 * Return the glyph number corresponding to a string (the inverse of
124
 * gs_c_glyph_name), or GS_NO_GLYPH if the glyph name is not known.
125
 */
126
gs_glyph
127
gs_c_name_glyph(const byte *str, uint len)
128
6.72M
{
129
6.72M
    if (len == 0 || len > gs_c_known_encoding_max_length)
130
9.52k
        return GS_NO_GLYPH;
131
    /* Binary search the character table. */
132
6.71M
    {
133
6.71M
        uint base = gs_c_known_encoding_offsets[len];
134
6.71M
        const byte *bot = (const byte *)&gs_c_known_encoding_chars[base];
135
6.71M
        uint count = (gs_c_known_encoding_offsets[len + 1] - base) / len;
136
6.71M
        uint a = 0, b = count;  /* know b > 0 */
137
6.71M
        const byte *probe;
138
139
39.7M
        while (a < b) {   /* know will execute at least once */
140
36.5M
            uint m = (a + b) >> 1;
141
36.5M
            int cmp;
142
143
36.5M
            probe = bot + m * len;
144
36.5M
            cmp = memcmp(str, probe, len);
145
36.5M
            if (cmp == 0)
146
3.56M
                return gs_c_min_std_encoding_glyph + N(len, probe - bot);
147
32.9M
            else if (cmp > 0)
148
15.7M
                a = m + 1;
149
17.2M
            else
150
17.2M
                b = m;
151
36.5M
        }
152
6.71M
    }
153
154
3.14M
    return GS_NO_GLYPH;
155
6.71M
}