]> mj.ucw.cz Git - libucw.git/blob - lib/ff-utf8.c
bugfix in image scaling (select the correct strategy)
[libucw.git] / lib / ff-utf8.c
1 /*
2  *      UCW Library: Reading and writing of UTF-8 on Fastbuf Streams
3  *
4  *      (c) 2001--2004 Martin Mares <mj@ucw.cz>
5  *      (c) 2004 Robert Spalek <robert@ucw.cz>
6  *
7  *      This software may be freely distributed and used according to the terms
8  *      of the GNU Lesser General Public License.
9  */
10
11 #include "lib/lib.h"
12 #include "lib/fastbuf.h"
13 #include "lib/unicode.h"
14 #include "lib/ff-utf8.h"
15
16 int
17 bget_utf8_slow(struct fastbuf *b)
18 {
19   int c = bgetc(b);
20   int code;
21
22   if (c < 0x80)                         /* Includes EOF */
23     return c;
24   if (c < 0xc0)                         /* Incorrect combination */
25     return UNI_REPLACEMENT;
26   if (c >= 0xf0)                        /* Too large, skip it */
27     {
28       while ((c = bgetc(b)) >= 0x80 && c < 0xc0)
29         ;
30       goto wrong;
31     }
32   if (c >= 0xe0)                        /* 3 bytes */
33     {
34       code = c & 0x0f;
35       if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
36         goto wrong;
37       code = (code << 6) | (c & 0x3f);
38       if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
39         goto wrong;
40       code = (code << 6) | (c & 0x3f);
41     }
42   else                                  /* 2 bytes */
43     {
44       code = c & 0x1f;
45       if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
46         goto wrong;
47       code = (code << 6) | (c & 0x3f);
48     }
49   return code;
50
51  wrong:
52   if (c >= 0)
53     bungetc(b);
54   return UNI_REPLACEMENT;
55 }
56
57 int
58 bget_utf8_32_slow(struct fastbuf *b)
59 {
60   int c = bgetc(b);
61   int code;
62   int nr;
63
64   if (c < 0x80)                         /* Includes EOF */
65     return c;
66   if (c < 0xc0)                         /* Incorrect combination */
67     return UNI_REPLACEMENT;
68   if (c < 0xe0)
69     {
70       code = c & 0x1f;
71       nr = 1;
72     }
73   else if (c < 0xf0)
74     {
75       code = c & 0x0f;
76       nr = 2;
77     }
78   else if (c < 0xf8)
79     {
80       code = c & 0x07;
81       nr = 3;
82     }
83   else if (c < 0xfc)
84     {
85       code = c & 0x03;
86       nr = 4;
87     }
88   else if (c < 0xfe)
89     {
90       code = c & 0x01;
91       nr = 5;
92     }
93   else                                  /* Too large, skip it */
94     {
95       while ((c = bgetc(b)) >= 0x80 && c < 0xc0)
96         ;
97       goto wrong;
98     }
99   while (nr-- > 0)
100     {
101       if ((c = bgetc(b)) < 0x80 || c >= 0xc0)
102         goto wrong;
103       code = (code << 6) | (c & 0x3f);
104     }
105   return code;
106
107  wrong:
108   if (c >= 0)
109     bungetc(b);
110   return UNI_REPLACEMENT;
111 }
112
113 void
114 bput_utf8_slow(struct fastbuf *b, uns u)
115 {
116   ASSERT(u < 65536);
117   if (u < 0x80)
118     bputc(b, u);
119   else
120     {
121       if (u < 0x800)
122         bputc(b, 0xc0 | (u >> 6));
123       else
124         {
125           bputc(b, 0xe0 | (u >> 12));
126           bputc(b, 0x80 | ((u >> 6) & 0x3f));
127         }
128       bputc(b, 0x80 | (u & 0x3f));
129     }
130 }
131
132 void
133 bput_utf8_32_slow(struct fastbuf *b, uns u)
134 {
135   ASSERT(u < (1U<<31));
136   if (u < 0x80)
137     bputc(b, u);
138   else
139     {
140       if (u < 0x800)
141         bputc(b, 0xc0 | (u >> 6));
142       else
143         {
144           if (u < (1<<16))
145             bputc(b, 0xe0 | (u >> 12));
146           else
147             {
148               if (u < (1<<21))
149                 bputc(b, 0xf0 | (u >> 18));
150               else
151                 {
152                   if (u < (1<<26))
153                     bputc(b, 0xf8 | (u >> 24));
154                   else
155                     {
156                       bputc(b, 0xfc | (u >> 30));
157                       bputc(b, 0x80 | ((u >> 24) & 0x3f));
158                     }
159                   bputc(b, 0x80 | ((u >> 18) & 0x3f));
160                 }
161               bputc(b, 0x80 | ((u >> 12) & 0x3f));
162             }
163           bputc(b, 0x80 | ((u >> 6) & 0x3f));
164         }
165       bputc(b, 0x80 | (u & 0x3f));
166     }
167 }