MagickCore  6.9.13-46
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 typedef struct
32 {
33  int
34  code_mask,
35  code_value,
36  utf_mask,
37  utf_value;
38 } UTFInfo;
39 
40 static 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 
51 static 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 
91 static 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 
167 static 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 
209 static inline int GetUTFCode(const char *magick_restrict text)
210 {
211  unsigned int
212  octets;
213 
214  return(GetNextUTFCode(text,&octets));
215 }
216 
217 static 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 
226 static inline MagickBooleanType IsNonBreakingUTFSpace(const int code)
227 {
228  if (code == 0x00a0)
229  return(MagickTrue);
230  return(MagickFalse);
231 }
232 
233 static 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 
244 static 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 
256 static 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