MagickCore 6.9.13
Loading...
Searching...
No Matches
token-private.h
1/*
2 Copyright 1999 ImageMagick Studio LLC, a non-profit organization
3 dedicated to making software imaging solutions freely available.
4
5 You may not use this file except in compliance with the License. You may
6 obtain a copy of the License at
7
8 https://imagemagick.org/license/
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15
16 MagickCore private token methods.
17*/
18#ifndef MAGICKCORE_TOKEN_PRIVATE_H
19#define MAGICKCORE_TOKEN_PRIVATE_H
20
21#if defined(__cplusplus) || defined(c_plusplus)
22extern "C" {
23#endif
24
25#ifndef EILSEQ
26 #define EILSEQ ENOENT
27#endif
28
29#define MaxMultibyteCodes 6
30
31typedef struct
32{
33 int
34 code_mask,
35 code_value,
36 utf_mask,
37 utf_value;
38} UTFInfo;
39
40static UTFInfo
41 utf_info[MaxMultibyteCodes] =
42 {
43 { 0x80, 0x00, 0x000007f, 0x0000000 }, /* 1 byte sequence */
44 { 0xE0, 0xC0, 0x00007ff, 0x0000080 }, /* 2 byte sequence */
45 { 0xF0, 0xE0, 0x000ffff, 0x0000800 }, /* 3 byte sequence */
46 { 0xF8, 0xF0, 0x01fffff, 0x0010000 }, /* 4 byte sequence */
47 { 0xFC, 0xF8, 0x03fffff, 0x0200000 }, /* 5 byte sequence */
48 { 0xFE, 0xFC, 0x7ffffff, 0x4000000 }, /* 6 byte sequence */
49 };
50
51static inline unsigned char *ConvertLatin1ToUTF8(
52 const unsigned char *magick_restrict content)
53{
54 const unsigned char
55 *magick_restrict p;
56
57 int
58 c;
59
60 size_t
61 length;
62
63 unsigned char
64 *magick_restrict q,
65 *utf8;
66
67 length=0;
68 for (p=content; *p != '\0'; p++)
69 length+=(*p & 0x80) != 0 ? 2 : 1;
70 utf8=(unsigned char *) NULL;
71 if (~length >= 1)
72 utf8=(unsigned char *) AcquireQuantumMemory(length+1UL,sizeof(*utf8));
73 if (utf8 == (unsigned char *) NULL)
74 return((unsigned char *) NULL);
75 q=utf8;
76 for (p=content; *p != '\0'; p++)
77 {
78 c=(*p);
79 if ((c & 0x80) == 0)
80 *q++=c;
81 else
82 {
83 *q++=0xc0 | ((c >> 6) & 0x3f);
84 *q++=0x80 | (c & 0x3f);
85 }
86 }
87 *q='\0';
88 return(utf8);
89}
90
91static inline unsigned char *ConvertMacRomanToUTF8(
92 const unsigned char *magick_restrict content)
93{
94 static const uint16_t macroman_unicode[128] = {
95 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
96 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
97 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
98 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
99 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
100 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
101 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
102 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
103 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
104 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
105 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
106 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
107 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
108 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
109 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
110 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7
111 };
112
113 int
114 c;
115
116 const unsigned char
117 *magick_restrict p;
118
119 size_t
120 length;
121
122 unsigned char
123 *magick_restrict q,
124 *utf8;
125
126 length=0;
127 for (p=content; *p != '\0'; p++)
128 length+=(*p & 0x80) != 0 ? 4 : 1;
129 utf8=(unsigned char *) NULL;
130 if (~length >= 1)
131 utf8=(unsigned char *) AcquireQuantumMemory(length+1UL,sizeof(*utf8));
132 if (utf8 == (unsigned char *) NULL)
133 return((unsigned char *) NULL);
134 q=utf8;
135 for (p=content; *p != '\0'; p++)
136 {
137 c=(*p);
138 if (c > 128)
139 c=macroman_unicode[c-128];
140 if ((c & 0x80) == 0)
141 *q++=(unsigned char) c;
142 else
143 if (c <= 0x7ff)
144 {
145 *q++=(unsigned char) (0xc0 | ((c >> 6) & 0x3f));
146 *q++=(unsigned char) (0x80 | (c & 0x3f));
147 }
148 else
149 if (c <= 0xffff)
150 {
151 *q++=(unsigned char) (0xe0 | (c >> 12));
152 *q++=(unsigned char) (0x80 | ((c >> 6) & 0x3f));
153 *q++=(unsigned char) (0x80 | (c & 0x3f));
154 }
155 else
156 {
157 *q++=(unsigned char) (0xf0 | (c >> 18));
158 *q++=(unsigned char) (0x80 | ((c >> 12) & 0x3f));
159 *q++=(unsigned char) (0x80 | ((c >> 6) & 0x3f));
160 *q++=(unsigned char) (0x80 | (c & 0x3f));
161 }
162 }
163 *q='\0';
164 return(utf8);
165}
166
167static inline int GetNextUTFCode(const char *magick_restrict text,
168 unsigned int *magick_restrict octets)
169{
170 int
171 code;
172
173 ssize_t
174 i;
175
176 int
177 c,
178 unicode;
179
180 *octets=1;
181 if (text == (const char *) NULL)
182 {
183 errno=EINVAL;
184 return(-1);
185 }
186 code=(int) (*text++) & 0xff;
187 unicode=code;
188 for (i=0; i < MaxMultibyteCodes; i++)
189 {
190 if ((code & utf_info[i].code_mask) == utf_info[i].code_value)
191 {
192 unicode&=utf_info[i].utf_mask;
193 if (unicode < utf_info[i].utf_value)
194 break;
195 *octets=(unsigned int) (i+1);
196 return(unicode);
197 }
198 c=(int) (*text++ ^ 0x80) & 0xff;
199 if ((c & 0xc0) != 0)
200 break;
201 if (unicode > 0x10FFFF)
202 break;
203 unicode=(unicode << 6) | c;
204 }
205 errno=EILSEQ;
206 return(-1);
207}
208
209static inline int GetUTFCode(const char *magick_restrict text)
210{
211 unsigned int
212 octets;
213
214 return(GetNextUTFCode(text,&octets));
215}
216
217static inline unsigned int GetUTFOctets(const char *magick_restrict text)
218{
219 unsigned int
220 octets;
221
222 (void) GetNextUTFCode(text,&octets);
223 return(octets);
224}
225
226static inline MagickBooleanType IsNonBreakingUTFSpace(const int code)
227{
228 if (code == 0x00a0)
229 return(MagickTrue);
230 return(MagickFalse);
231}
232
233static inline MagickBooleanType IsUTFSpace(int code)
234{
235 if (((code >= 0x0009) && (code <= 0x000d)) || (code == 0x0020) ||
236 (code == 0x0085) || (code == 0x00a0) || (code == 0x1680) ||
237 (code == 0x180e) || ((code >= 0x2000) && (code <= 0x200a)) ||
238 (code == 0x2028) || (code == 0x2029) || (code == 0x202f) ||
239 (code == 0x205f) || (code == 0x3000))
240 return(MagickTrue);
241 return(MagickFalse);
242}
243
244static inline MagickBooleanType IsUTFValid(const int code)
245{
246 int
247 mask;
248
249 mask=(int) 0x7fffffff;
250 if (((code & ~mask) != 0) && ((code < 0xd800) || (code > 0xdfff)) &&
251 (code != 0xfffe) && (code != 0xffff))
252 return(MagickFalse);
253 return(MagickTrue);
254}
255
256static inline MagickBooleanType IsUTFAscii(int code)
257{
258 int
259 mask;
260
261 mask=(int) 0x7f;
262 if ((code & ~mask) != 0)
263 return(MagickFalse);
264 return(MagickTrue);
265}
266
267#if defined(__cplusplus) || defined(c_plusplus)
268}
269#endif
270
271#endif