summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2015-12-26 04:23:33 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2015-12-26 04:23:33 +0000
commit26036033027b092a462717c3950dc869095717ed (patch)
tree389aa07cdd3c369f8b8370921e6a47924f0c4d95 /Build
parentfa5fc01573824dc8ce0d249d12b223a29b589364 (diff)
texk/dvipdfm-x: png, and unocode patch from S. Hirata.
git-svn-id: svn://tug.org/texlive/trunk@39201 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rw-r--r--Build/source/texk/dvipdfm-x/ChangeLog8
-rw-r--r--Build/source/texk/dvipdfm-x/agl.c8
-rw-r--r--Build/source/texk/dvipdfm-x/pdffont.c1
-rw-r--r--Build/source/texk/dvipdfm-x/pngimage.c6
-rw-r--r--Build/source/texk/dvipdfm-x/spc_pdfm.c91
-rw-r--r--Build/source/texk/dvipdfm-x/tt_cmap.c8
-rw-r--r--Build/source/texk/dvipdfm-x/unicode.c168
-rw-r--r--Build/source/texk/dvipdfm-x/unicode.h12
8 files changed, 202 insertions, 100 deletions
diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog
index 941631a3930..6b441147289 100644
--- a/Build/source/texk/dvipdfm-x/ChangeLog
+++ b/Build/source/texk/dvipdfm-x/ChangeLog
@@ -1,3 +1,11 @@
+2015-12-26 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * pngimage.c: Workaround for Adobe Potoshop generated PNGs which have
+ cHRM chunk but not gAMA chunk.
+ * agl.c, spc_pdfm.c, unicode.c, unicode.h: Addition of some
+ Unicode related functions. Try conversion to UTF16BE only for string
+ objects which can be considered as a valid Unicode text.
+
2015-12-24 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
* t1_load.c: Support for get/putinterval and get/put in encoding
diff --git a/Build/source/texk/dvipdfm-x/agl.c b/Build/source/texk/dvipdfm-x/agl.c
index 3517a3e8c47..31117d1ed1c 100644
--- a/Build/source/texk/dvipdfm-x/agl.c
+++ b/Build/source/texk/dvipdfm-x/agl.c
@@ -1,6 +1,6 @@
/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2007-2014 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2007-2015 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team.
Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
@@ -636,12 +636,12 @@ put_unicode_glyph (const char *name,
if (p[1] != 'n') {
p += 1;
ucv = xtol(p, strlen(p));
- len += UC_sput_UTF16BE (ucv, dstpp, limptr);
+ len += UC_UTF16BE_encode_char(ucv, dstpp, limptr);
} else {
p += 3;
while (*p != '\0') {
ucv = xtol(p, 4);
- len += UC_sput_UTF16BE (ucv, dstpp, limptr);
+ len += UC_UTF16BE_encode_char(ucv, dstpp, limptr);
p += 4;
}
}
@@ -715,7 +715,7 @@ agl_sput_UTF16BE (const char *glyphstr,
}
if (agln1) {
for (i = 0; i < agln1->n_components; i++) {
- len += UC_sput_UTF16BE (agln1->unicodes[i], dstpp, limptr);
+ len += UC_UTF16BE_encode_char(agln1->unicodes[i], dstpp, limptr);
}
} else {
if (verbose) {
diff --git a/Build/source/texk/dvipdfm-x/pdffont.c b/Build/source/texk/dvipdfm-x/pdffont.c
index 9dc400700f3..d3fdf09d40a 100644
--- a/Build/source/texk/dvipdfm-x/pdffont.c
+++ b/Build/source/texk/dvipdfm-x/pdffont.c
@@ -66,7 +66,6 @@ pdf_font_set_verbose (void)
Type0Font_set_verbose();
CIDFont_set_verbose ();
pdf_encoding_set_verbose();
- UC_set_verbose ();
agl_set_verbose();
otl_conf_set_verbose();
otf_cmap_set_verbose ();
diff --git a/Build/source/texk/dvipdfm-x/pngimage.c b/Build/source/texk/dvipdfm-x/pngimage.c
index 609cfab7166..7ccec5b91fe 100644
--- a/Build/source/texk/dvipdfm-x/pngimage.c
+++ b/Build/source/texk/dvipdfm-x/pngimage.c
@@ -63,6 +63,8 @@
#include "pdfximage.h"
+#define DPX_PNG_DEFAULT_GAMMA 2.2
+
#define PDF_TRANS_TYPE_NONE 0
#define PDF_TRANS_TYPE_BINARY 1
#define PDF_TRANS_TYPE_ALPHA 2
@@ -668,7 +670,7 @@ create_cspace_CalRGB (png_structp png_ptr, png_infop info_ptr)
}
G = 1.0 / G; /* Gamma is inverted. */
} else {
- G = 1.0;
+ G = DPX_PNG_DEFAULT_GAMMA;
}
cal_param = make_param_Cal(PNG_COLOR_TYPE_RGB, G, xw, yw, xr, yr, xg, yg, xb, yb);
@@ -709,7 +711,7 @@ create_cspace_CalGray (png_structp png_ptr, png_infop info_ptr)
}
G = 1.0 / G; /* Gamma is inverted. */
} else {
- G = 1.0;
+ G = DPX_PNG_DEFAULT_GAMMA;
}
cal_param = make_param_Cal(PNG_COLOR_TYPE_GRAY, G, xw, yw, xr, yr, xg, yg, xb, yb);
diff --git a/Build/source/texk/dvipdfm-x/spc_pdfm.c b/Build/source/texk/dvipdfm-x/spc_pdfm.c
index 019230ca15d..1b12dd966eb 100644
--- a/Build/source/texk/dvipdfm-x/spc_pdfm.c
+++ b/Build/source/texk/dvipdfm-x/spc_pdfm.c
@@ -37,6 +37,8 @@
#include "dpxfile.h"
#include "dpxutil.h"
+#include "unicode.h"
+
#include "pdfobj.h"
#include "pdfparse.h"
@@ -126,6 +128,9 @@ static int
spc_handler_pdfm__init (void *dp)
{
struct spc_pdf_ *sd = dp;
+ /* The folllowing dictionary entry keys are considered as keys for
+ * text strings. Be sure that string object is NOT always a text string.
+ */
static const char *default_taintkeys[] = {
"Title", "Author", "Subject", "Keywords",
"Creator", "Producer", "Contents", "Subj",
@@ -399,31 +404,6 @@ reencodestring (CMap *cmap, pdf_obj *instring)
return 0;
}
-/* tables/values used in UTF-8 interpretation -
- code is based on ConvertUTF.[ch] sample code
- published by the Unicode consortium */
-static uint32_t
-offsetsFromUTF8[6] = {
- 0x00000000U,
- 0x00003080U,
- 0x000E2080U,
- 0x03C82080U,
- 0xFA082080U,
- 0x82082080U
-};
-
-static unsigned char
-bytesFromUTF8[256] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
-};
-
static int
maybe_reencode_utf8(pdf_obj *instring)
{
@@ -449,7 +429,15 @@ maybe_reencode_utf8(pdf_obj *instring)
if (non_ascii == 0)
return 0; /* no need to reencode ASCII strings */
- if (inbuf[0] == 0xfe && inbuf[1] == 0xff)
+ /* Check if the input string is valid UTF8 string
+ * This routine may be called against non-text strings.
+ * We need to re-encode string only when string is a text string
+ * endcoded in UTF8.
+ */
+ if (!UC_UTF8_is_valid_string(inbuf, inbuf + inlen))
+ return 0;
+ else if (inbuf[0] == 0xfe && inbuf[1] == 0xff &&
+ UC_UTF16BE_is_valid_string(inbuf + 2, inbuf + inlen))
return 0; /* no need to reencode UTF16BE with BOM */
cp = inbuf;
@@ -457,35 +445,15 @@ maybe_reencode_utf8(pdf_obj *instring)
*op++ = 0xfe;
*op++ = 0xff;
while (cp < inbuf + inlen) {
- uint32_t usv = *cp++;
- int extraBytes = bytesFromUTF8[usv];
- if (cp + extraBytes > inbuf + inlen)
- return -1; /* ill-formed, so give up reencoding */
- switch (extraBytes) { /* note: code falls through cases! */
- case 5: usv <<= 6; usv += *cp++;
- case 4: usv <<= 6; usv += *cp++;
- case 3: usv <<= 6; usv += *cp++;
- case 2: usv <<= 6; usv += *cp++;
- case 1: usv <<= 6; usv += *cp++;
- case 0: ;
- };
- usv -= offsetsFromUTF8[extraBytes];
- if (usv > 0x10FFFF)
- return -1; /* out of valid Unicode range, give up */
- if (usv > 0xFFFF) {
- /* supplementary-plane character: generate high surrogate */
- uint32_t hi = 0xdc00 + (usv - 0x10000) % 0x0400;
- if (op > wbuf + WBUF_SIZE - 2)
- return -1; /* out of space */
- *op++ = hi / 256;
- *op++ = hi % 256;
- usv = 0xd800 + (usv - 0x10000) / 0x0400;
- /* remaining value in usv is the low surrogate */
- }
- if (op > wbuf + WBUF_SIZE - 2)
- return -1; /* out of space */
- *op++ = usv / 256;
- *op++ = usv % 256;
+ int32_t usv;
+ int len;
+
+ usv = UC_UTF8_decode_char((const unsigned char **)&cp, inbuf + inlen);
+ if (!UC_is_valid(usv))
+ return -1; /* out of valid Unicode range, give up (redundant) */
+ len = UC_UTF16BE_encode_char(usv, &op, wbuf + WBUF_SIZE);
+ if (len == 0)
+ return -1;
}
pdf_set_string(instring, wbuf, op - wbuf);
@@ -493,6 +461,11 @@ maybe_reencode_utf8(pdf_obj *instring)
return 0;
}
+/* The purpose of this routine is to check if given string object is
+ * surely an object for *text* strings. It does not do a complete check
+ * but does a quick check. Please add entries for taintkeys if you have found
+ * additional dictionary entries which is considered as a text string.
+ */
static int
needreencode (pdf_obj *kp, pdf_obj *vp, struct tounicode *cd)
{
@@ -535,8 +508,13 @@ modstrings (pdf_obj *kp, pdf_obj *vp, void *dp)
CMap *cmap = CMap_cache_get(cd->cmap_id);
if (needreencode(kp, vp, cd))
r = reencodestring(cmap, vp);
- } else if (is_xdv)
+ } else if (is_xdv) {
+ /* Please fix this... PDF string object is not always a text string.
+ * needreencode() is assumed to do a simple check if given string
+ * object is actually a text string.
+ */
r = maybe_reencode_utf8(vp);
+ }
if (r < 0) /* error occured... */
WARN("Failed to convert input string to UTF16...");
break;
@@ -2063,4 +2041,3 @@ spc_pdfm_setup_handler (struct spc_handler *sph,
return error;
}
-
diff --git a/Build/source/texk/dvipdfm-x/tt_cmap.c b/Build/source/texk/dvipdfm-x/tt_cmap.c
index 62fadc59fce..7f74f9ea24d 100644
--- a/Build/source/texk/dvipdfm-x/tt_cmap.c
+++ b/Build/source/texk/dvipdfm-x/tt_cmap.c
@@ -913,7 +913,7 @@ handle_subst_glyphs (CMap *cmap,
int k;
len = 0;
for (k = 0; k < unicode_count; ++k) {
- len += UC_sput_UTF16BE(unicodes[k], &p, wbuf+WBUF_SIZE);
+ len += UC_UTF16BE_encode_char(unicodes[k], &p, wbuf+WBUF_SIZE);
}
wbuf[0] = (gid >> 8) & 0xff;
wbuf[1] = gid & 0xff;
@@ -994,7 +994,7 @@ add_to_cmap_if_used (CMap *cmap,
wbuf[0] = (cid >> 8) & 0xff;
wbuf[1] = (cid & 0xff);
- len = UC_sput_UTF16BE(ch, &p, wbuf + WBUF_SIZE);
+ len = UC_UTF16BE_encode_char((int32_t) ch, &p, wbuf + WBUF_SIZE);
CMap_add_bfchar(cmap, wbuf, 2, wbuf + 2, len);
/* Skip PUA characters and alphabetic presentation forms, allowing
@@ -1109,7 +1109,7 @@ create_ToUnicode_cmap (tt_cmap *ttcmap,
unsigned char *p = wbuf + 2;
wbuf[0] = (cid >> 8) & 0xff;
wbuf[1] = cid & 0xff;
- len = UC_sput_UTF16BE(ch, &p, wbuf + WBUF_SIZE);
+ len = UC_UTF16BE_encode_char(ch, &p, wbuf + WBUF_SIZE);
CMap_add_bfchar(cmap, wbuf, 2, wbuf + 2, len);
count++;
}
@@ -1340,7 +1340,7 @@ create_cmaps (CMap *cmap, CMap *tounicode,
endptr = wbuf + WBUF_SIZE;
len = 0;
for (i = 0; i < glyph->num_unicodes; i++) {
- len += UC_sput_UTF16BE(glyph->unicodes[i], &p, endptr);
+ len += UC_UTF16BE_encode_char(glyph->unicodes[i], &p, endptr);
}
CMap_add_bfchar(tounicode, wbuf, 2, wbuf + 2, len);
}
diff --git a/Build/source/texk/dvipdfm-x/unicode.c b/Build/source/texk/dvipdfm-x/unicode.c
index 09e35ce34c6..682202906a5 100644
--- a/Build/source/texk/dvipdfm-x/unicode.c
+++ b/Build/source/texk/dvipdfm-x/unicode.c
@@ -26,6 +26,8 @@
* ToUnicode CMap
*
* Normalization?
+ *
+ * I made some unused functions here for completeness and FUTURE USE.
*/
#ifdef HAVE_CONFIG_H
@@ -40,42 +42,98 @@
#include "unicode.h"
-static int __verbose = 0;
-
#define UC_DEBUG 3
#define UC_DEBUG_STR "UC"
-void
-UC_set_verbose (void)
+#define UC_REPLACEMENT_CHAR 0x0000FFFD
+
+#define UC_SUR_SHIFT 10
+#define UC_SUR_MASK 0x03FFU
+#define UC_SUR_LOW_START 0xDC00U
+#define UC_SUR_HIGH_START 0xD800U
+#define UC_SUR_END 0xE000U
+
+int
+UC_is_valid (int32_t ucv)
{
- __verbose++;
+ if ( ucv < 0 || ucv > 0x10FFFFL ||
+ (ucv >= 0x0000D800L && ucv <= 0x0000DFFFL))
+ return 0;
+ return 1;
}
-#define UC_REPLACEMENT_CHAR 0x0000FFFDL
-
-#define UC_SUR_SHIFT 10
-#define UC_SUR_MASK 0x3FFUL
-#define UC_SUR_LOW_START 0xDC00UL
-#define UC_SUR_HIGH_START 0xD800UL
+int
+UC_UTF16BE_is_valid_string (const unsigned char *p, const unsigned char *endptr)
+{
+ if (p + 1 >= endptr)
+ return 0;
+ while (p < endptr) {
+ int32_t ucv = UC_UTF16BE_decode_char(&p, endptr);
+ if (!UC_is_valid(ucv))
+ return 0;
+ }
+ return 1;
+}
int
-UC_sput_UTF16BE (int32_t ucv, unsigned char **pp, unsigned char *limptr)
+UC_UTF8_is_valid_string (const unsigned char *p, const unsigned char *endptr)
+{
+ if (p + 1 >= endptr)
+ return 0;
+ while (p < endptr) {
+ int32_t ucv = UC_UTF8_decode_char(&p, endptr);
+ if (!UC_is_valid(ucv))
+ return 0;
+ }
+ return 1;
+}
+
+int32_t
+UC_UTF16BE_decode_char (const unsigned char **pp, const unsigned char *endptr)
+{
+ const unsigned char *p = *pp;
+ int32_t ucv = -1;
+ uint16_t first, second;
+
+ if (p + 1 >= endptr)
+ return -1;
+
+ first = ((p[0]) << 8|p[1]); p += 2;
+ if (first >= UC_SUR_HIGH_START && first < UC_SUR_LOW_START) {
+ if (p + 1 >= endptr)
+ return -1;
+ second = (p[0] << 8|p[1]); p += 2;
+ ucv = second & UC_SUR_MASK;
+ ucv |= (first & UC_SUR_MASK) << UC_SUR_SHIFT;
+ ucv += 0x00010000;
+ } else if (first >= UC_SUR_LOW_START && first < UC_SUR_END) {
+ return -1;
+ } else {
+ ucv = first;
+ }
+
+ *pp = p;
+ return ucv;
+}
+
+size_t
+UC_UTF16BE_encode_char (int32_t ucv, unsigned char **pp, unsigned char *endptr)
{
int count = 0;
unsigned char *p = *pp;
if (ucv >= 0 && ucv <= 0xFFFF) {
- if (p + 2 >= limptr)
- ERROR("Not enough space available...");
+ if (p + 2 >= endptr)
+ return 0;
p[0] = (ucv >> 8) & 0xff;
p[1] = ucv & 0xff;
count = 2;
- } else if (ucv >= 0x010000L && ucv <= 0x10FFFFL) {
+ } else if (ucv >= 0x010000 && ucv <= 0x10FFFF) {
unsigned short high, low;
- if (p + 4 >= limptr)
- ERROR("Not enough space available...");
- ucv -= 0x00010000L;
+ if (p + 4 >= endptr)
+ return 0;
+ ucv -= 0x00010000;
high = (ucv >> UC_SUR_SHIFT) + UC_SUR_HIGH_START;
low = (ucv & UC_SUR_MASK) + UC_SUR_LOW_START;
p[0] = (high >> 8) & 0xff;
@@ -84,8 +142,8 @@ UC_sput_UTF16BE (int32_t ucv, unsigned char **pp, unsigned char *limptr)
p[3] = (low & 0xff);
count = 4;
} else {
- if (p + 2 >= limptr)
- ERROR("Not enough space available...");
+ if (p + 2 >= endptr)
+ return 0;
p[0] = (UC_REPLACEMENT_CHAR >> 8) & 0xff;
p[1] = (UC_REPLACEMENT_CHAR & 0xff);
count = 2;
@@ -95,14 +153,6 @@ UC_sput_UTF16BE (int32_t ucv, unsigned char **pp, unsigned char *limptr)
return count;
}
-int
-UC_is_valid (int32_t ucv)
-{
- if (ucv < 0 || (ucv >= 0x0000D800L && ucv <= 0x0000DFFFL))
- return 0;
- return 1;
-}
-
int32_t
UC_UTF8_decode_char (const unsigned char **pp, const unsigned char *endptr)
{
@@ -144,3 +194,65 @@ UC_UTF8_decode_char (const unsigned char **pp, const unsigned char *endptr)
*pp = p;
return ucv;
}
+
+size_t
+UC_UTF8_encode_char (int32_t ucv, unsigned char **pp, unsigned char *endptr)
+{
+ int count = 0;
+ unsigned char *p = *pp;
+
+ ASSERT( pp && *pp && endptr );
+
+ if (!UC_is_valid(ucv))
+ return 0;
+
+ if (ucv < 0x7f) {
+ if (p >= endptr - 1)
+ return 0;
+ p[0] = (unsigned char) ucv;
+ count = 1;
+ } else if (ucv <= 0x7ff) {
+ if (p >= endptr -2)
+ return 0;
+ p[0] = (unsigned char) (0xc0 | (ucv >> 6));
+ p[1] = (unsigned char) (0x80 | (ucv & 0x3f));
+ count = 2;
+ } else if (ucv <= 0xffff) {
+ if (p >= endptr - 3)
+ return 0;
+ p[0] = (unsigned char) (0xe0 | (ucv >> 12));
+ p[1] = (unsigned char) (0x80 | ((ucv >> 6) & 0x3f));
+ p[2] = (unsigned char) (0x80 | (ucv & 0x3f));
+ count = 3;
+ } else if (ucv <= 0x1fffff) {
+ if (p >= endptr - 4)
+ return 0;
+ p[0] = (unsigned char) (0xf0 | (ucv >> 18));
+ p[1] = (unsigned char) (0x80 | ((ucv >> 12) & 0x3f));
+ p[2] = (unsigned char) (0x80 | ((ucv >> 6) & 0x3f));
+ p[3] = (unsigned char) (0x80 | (ucv & 0x3f));
+ count = 4;
+ } else if (ucv <= 0x3ffffff) {
+ if (p >= endptr - 5)
+ return 0;
+ p[0] = (unsigned char) (0xf8 | (ucv >> 24));
+ p[1] = (unsigned char) (0x80 | ((ucv >> 18) & 0x3f));
+ p[2] = (unsigned char) (0x80 | ((ucv >> 12) & 0x3f));
+ p[3] = (unsigned char) (0x80 | ((ucv >> 6) & 0x3f));
+ p[4] = (unsigned char) (0x80 | (ucv & 0x3f));
+ count = 5;
+ } else if (ucv <= 0x7fffffff) {
+ if (p >= endptr - 6)
+ return 0;
+ p[0] = (unsigned char) (0xfc | (ucv >> 30));
+ p[1] = (unsigned char) (0x80 | ((ucv >> 24) & 0x3f));
+ p[2] = (unsigned char) (0x80 | ((ucv >> 18) & 0x3f));
+ p[3] = (unsigned char) (0x80 | ((ucv >> 12) & 0x3f));
+ p[4] = (unsigned char) (0x80 | ((ucv >> 6) & 0x3f));
+ p[5] = (unsigned char) (0x80 | (ucv & 0x3f));
+ count = 6;
+ }
+
+ *pp += count;
+ return count;
+}
diff --git a/Build/source/texk/dvipdfm-x/unicode.h b/Build/source/texk/dvipdfm-x/unicode.h
index 94bbc719994..0c9df5b5e2c 100644
--- a/Build/source/texk/dvipdfm-x/unicode.h
+++ b/Build/source/texk/dvipdfm-x/unicode.h
@@ -23,9 +23,13 @@
#ifndef _UNICODE_H_
#define _UNICODE_H_
-extern void UC_set_verbose (void);
-
-extern int UC_sput_UTF16BE (int32_t ucv, unsigned char **dstpp, unsigned char *endptr);
extern int UC_is_valid (int32_t ucv);
-extern int32_t UC_UTF8_decode_char(const unsigned char **pp, const unsigned char *endptr);
+extern int UC_UTF16BE_is_valid_string (const unsigned char *p, const unsigned char *endptr);
+extern int UC_UTF8_is_valid_string (const unsigned char *p, const unsigned char *endptr);
+
+extern size_t UC_UTF16BE_encode_char (int32_t ucv, unsigned char **dstpp, unsigned char *endptr);
+extern int32_t UC_UTF16BE_decode_char (const unsigned char **pp, const unsigned char *endptr);
+extern int32_t UC_UTF8_decode_char (const unsigned char **pp, const unsigned char *endptr);
+extern size_t UC_UTF8_encode_char (int32_t ucv, unsigned char **dstpp, unsigned char *endptr);
+
#endif /* _UNICODE_H_ */