From 26036033027b092a462717c3950dc869095717ed Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Sat, 26 Dec 2015 04:23:33 +0000 Subject: texk/dvipdfm-x: png, and unocode patch from S. Hirata. git-svn-id: svn://tug.org/texlive/trunk@39201 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/dvipdfm-x/ChangeLog | 8 ++ Build/source/texk/dvipdfm-x/agl.c | 8 +- Build/source/texk/dvipdfm-x/pdffont.c | 1 - Build/source/texk/dvipdfm-x/pngimage.c | 6 +- Build/source/texk/dvipdfm-x/spc_pdfm.c | 91 +++++++----------- Build/source/texk/dvipdfm-x/tt_cmap.c | 8 +- Build/source/texk/dvipdfm-x/unicode.c | 168 +++++++++++++++++++++++++++------ Build/source/texk/dvipdfm-x/unicode.h | 12 ++- 8 files changed, 202 insertions(+), 100 deletions(-) (limited to 'Build') 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 + + * 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 * 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 @@ -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_ */ -- cgit v1.2.3