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