MagickCore  7.1.2-29
Convert, Edit, Or Compose Bitmap Images
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)
22 extern "C" {
23 #endif
24 
25 #ifndef EILSEQ
26  #define EILSEQ ENOENT
27 #endif
28 
29 #define MaxMultibyteCodes 6
30 
31 extern MagickPrivate MagickBooleanType
32  IsGlob(const char *) magick_attribute((__pure__));
33 
34 typedef struct
35 {
36  int
37  code_mask,
38  code_value,
39  utf_mask,
40  utf_value;
41 } UTFInfo;
42 
43 static 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 
54 static 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 
94 static 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=(int) 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 
170 static 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 
212 static inline int GetUTFCode(const char *magick_restrict text)
213 {
214  unsigned int
215  octets;
216 
217  return(GetNextUTFCode(text,&octets));
218 }
219 
220 static 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 
229 static inline MagickBooleanType IsNonBreakingUTFSpace(const int code)
230 {
231  if (code == 0x00a0)
232  return(MagickTrue);
233  return(MagickFalse);
234 }
235 
236 static 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 
247 static 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 
259 static 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