diff options
Diffstat (limited to 'Build/source/libs/gd/libgd-2.1.0/src/gdkanji.c')
-rw-r--r-- | Build/source/libs/gd/libgd-2.1.0/src/gdkanji.c | 587 |
1 files changed, 587 insertions, 0 deletions
diff --git a/Build/source/libs/gd/libgd-2.1.0/src/gdkanji.c b/Build/source/libs/gd/libgd-2.1.0/src/gdkanji.c new file mode 100644 index 00000000000..ab8c0df82df --- /dev/null +++ b/Build/source/libs/gd/libgd-2.1.0/src/gdkanji.c @@ -0,0 +1,587 @@ +/* gdkanji.c (Kanji code converter) */ +/* written by Masahito Yamaga (ma@yama-ga.com) */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "gd.h" +#include "gdhelpers.h" +#include "gd_errors.h" + +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif + +#include <stdarg.h> +#if defined(HAVE_ICONV_H) +#include <iconv.h> +#endif + +#ifndef HAVE_ICONV_T_DEF +typedef void *iconv_t; +#endif + +#ifndef HAVE_ICONV +#define ICONV_CONST /**/ +iconv_t iconv_open (const char *, const char *); +size_t iconv (iconv_t, ICONV_CONST char **, size_t *, char **, size_t *); +int iconv_close (iconv_t); + +iconv_t +iconv_open (const char *tocode, const char *fromcode) +{ + (void)tocode; + (void)fromcode; + return (iconv_t) (-1); +} + +size_t +iconv (iconv_t cd, ICONV_CONST char **inbuf, size_t * inbytesleft, + char **outbuf, size_t * outbytesleft) +{ + (void)cd; + (void)inbuf; + (void)inbytesleft; + (void)outbuf; + (void)outbytesleft; + return 0; +} + +int +iconv_close (iconv_t cd) +{ + (void)cd; + return 0; +} + +#endif /* !HAVE_ICONV */ + +#define LIBNAME "any2eucjp()" + +#if defined(__MSC__) || defined(__BORLANDC__) || defined(__TURBOC__) || defined(_Windows) || defined(MSDOS) +#ifndef SJISPRE +#define SJISPRE 1 +#endif +#endif + +#ifdef TRUE +#undef TRUE +#endif +#ifdef FALSE +#undef FALSE +#endif + +#define TRUE 1 +#define FALSE 0 + +#define NEW 1 +#define OLD 2 +#define ESCI 3 +#define NEC 4 +#define EUC 5 +#define SJIS 6 +#define EUCORSJIS 7 +#define ASCII 8 + +#define NEWJISSTR "JIS7" +#define OLDJISSTR "jis" +#define EUCSTR "eucJP" +#define SJISSTR "SJIS" + +#define ESC 27 +#define SS2 142 + +/* DetectKanjiCode() derived from DetectCodeType() by Ken Lunde. */ + +static int +DetectKanjiCode (unsigned char *str) +{ + static int whatcode = ASCII; + int oldcode = ASCII; + int c, i; + char *lang = NULL; + + c = '\1'; + i = 0; + + if (whatcode != EUCORSJIS && whatcode != ASCII) { + oldcode = whatcode; + whatcode = ASCII; + } + + while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0') { + if ((c = str[i++]) != '\0') { + if (c == ESC) { + c = str[i++]; + if (c == '$') { + c = str[i++]; + if (c == 'B') + whatcode = NEW; + else if (c == '@') + whatcode = OLD; + } else if (c == '(') { + c = str[i++]; + if (c == 'I') + whatcode = ESCI; + } else if (c == 'K') + whatcode = NEC; + } else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159)) + whatcode = SJIS; + else if (c == SS2) { + c = str[i++]; + if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) + || (c >= 224 && c <= 252)) + whatcode = SJIS; + else if (c >= 161 && c <= 223) + whatcode = EUCORSJIS; + } else if (c >= 161 && c <= 223) { + c = str[i++]; + if (c >= 240 && c <= 254) + whatcode = EUC; + else if (c >= 161 && c <= 223) + whatcode = EUCORSJIS; + else if (c >= 224 && c <= 239) { + whatcode = EUCORSJIS; + while (c >= 64 && c != '\0' && whatcode == EUCORSJIS) { + if (c >= 129) { + if (c <= 141 || (c >= 143 && c <= 159)) + whatcode = SJIS; + else if (c >= 253 && c <= 254) + whatcode = EUC; + } + c = str[i++]; + } + } else if (c <= 159) + whatcode = SJIS; + } else if (c >= 240 && c <= 254) + whatcode = EUC; + else if (c >= 224 && c <= 239) { + c = str[i++]; + if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160)) + whatcode = SJIS; + else if (c >= 253 && c <= 254) + whatcode = EUC; + else if (c >= 161 && c <= 252) + whatcode = EUCORSJIS; + } + } + } + +#ifdef DEBUG + if (whatcode == ASCII) + gd_error_ex(GD_DEBUG, "Kanji code not included."); + else if (whatcode == EUCORSJIS) + gd_error_ex(GD_DEBUG, "Kanji code not detected."); + else + gd_error_ex(GD_DEBUG, "Kanji code detected at %d byte.", i); +#endif + + if (whatcode == EUCORSJIS && oldcode != ASCII) + whatcode = oldcode; + + if (whatcode == EUCORSJIS) { + if (getenv ("LC_ALL")) + lang = getenv ("LC_ALL"); + else if (getenv ("LC_CTYPE")) + lang = getenv ("LC_CTYPE"); + else if (getenv ("LANG")) + lang = getenv ("LANG"); + + if (lang) { + if (strcmp (lang, "ja_JP.SJIS") == 0 || +#ifdef hpux + strcmp (lang, "japanese") == 0 || +#endif + strcmp (lang, "ja_JP.mscode") == 0 || + strcmp (lang, "ja_JP.PCK") == 0) + whatcode = SJIS; + else if (strncmp (lang, "ja", 2) == 0) +#ifdef SJISPRE + whatcode = SJIS; +#else + whatcode = EUC; +#endif + } + } + + if (whatcode == EUCORSJIS) +#ifdef SJISPRE + whatcode = SJIS; +#else + whatcode = EUC; +#endif + + return whatcode; +} + +/* SJIStoJIS() is sjis2jis() by Ken Lunde. */ + +static void +SJIStoJIS (int *p1, int *p2) +{ + register unsigned char c1 = *p1; + register unsigned char c2 = *p2; + register int adjust = c2 < 159; + register int rowOffset = c1 < 160 ? 112 : 176; + register int cellOffset = adjust ? (31 + (c2 > 127)) : 126; + + *p1 = ((c1 - rowOffset) << 1) - adjust; + *p2 -= cellOffset; +} + +/* han2zen() was derived from han2zen() written by Ken Lunde. */ + +#define IS_DAKU(c) ((c >= 182 && c <= 196) || (c >= 202 && c <= 206) || (c == 179)) +#define IS_HANDAKU(c) (c >= 202 && c <= 206) + +static void +han2zen (int *p1, int *p2) +{ + int c = *p1; + int daku = FALSE; + int handaku = FALSE; + int mtable[][2] = { + {129, 66}, + {129, 117}, + {129, 118}, + {129, 65}, + {129, 69}, + {131, 146}, + {131, 64}, + {131, 66}, + {131, 68}, + {131, 70}, + {131, 72}, + {131, 131}, + {131, 133}, + {131, 135}, + {131, 98}, + {129, 91}, + {131, 65}, + {131, 67}, + {131, 69}, + {131, 71}, + {131, 73}, + {131, 74}, + {131, 76}, + {131, 78}, + {131, 80}, + {131, 82}, + {131, 84}, + {131, 86}, + {131, 88}, + {131, 90}, + {131, 92}, + {131, 94}, + {131, 96}, + {131, 99}, + {131, 101}, + {131, 103}, + {131, 105}, + {131, 106}, + {131, 107}, + {131, 108}, + {131, 109}, + {131, 110}, + {131, 113}, + {131, 116}, + {131, 119}, + {131, 122}, + {131, 125}, + {131, 126}, + {131, 128}, + {131, 129}, + {131, 130}, + {131, 132}, + {131, 134}, + {131, 136}, + {131, 137}, + {131, 138}, + {131, 139}, + {131, 140}, + {131, 141}, + {131, 143}, + {131, 147}, + {129, 74}, + {129, 75} + }; + + if (*p2 == 222 && IS_DAKU (*p1)) + daku = TRUE; /* Daku-ten */ + else if (*p2 == 223 && IS_HANDAKU (*p1)) + handaku = TRUE; /* Han-daku-ten */ + + *p1 = mtable[c - 161][0]; + *p2 = mtable[c - 161][1]; + + if (daku) { + if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122)) + (*p2)++; + else if (*p2 == 131 && *p2 == 69) + *p2 = 148; + } else if (handaku && *p2 >= 110 && *p2 <= 122) + (*p2) += 2; +} + +/* Recast strcpy to handle unsigned chars used below. */ +#define ustrcpy(A,B) (strcpy((char*)(A),(const char*)(B))) + +static void +do_convert (unsigned char **to_p, unsigned char **from_p, const char *code) +{ + unsigned char *to = *to_p; + unsigned char *from = *from_p; +#ifdef HAVE_ICONV + iconv_t cd; + size_t from_len, to_len; + + if ((cd = iconv_open (EUCSTR, code)) == (iconv_t) - 1) { + gd_error ("iconv_open() error"); +#ifdef HAVE_ERRNO_H + if (errno == EINVAL) + gd_error ("invalid code specification: \"%s\" or \"%s\"", EUCSTR, code); +#endif + ustrcpy (to, from); + return; + } + + from_len = strlen ((const char *)from) + 1; + to_len = BUFSIZ; + + if ((int) (iconv (cd, (char **)from_p, &from_len, (char **)to_p, &to_len)) + == -1) { +#ifdef HAVE_ERRNO_H + if (errno == EINVAL) + gd_error ("invalid end of input string"); + else if (errno == EILSEQ) + gd_error ("invalid code in input string"); + else if (errno == E2BIG) + gd_error ("output buffer overflow at do_convert()"); + else +#endif + gd_error ("something happen"); + ustrcpy (to, from); + return; + } + + if (iconv_close (cd) != 0) { + gd_error ("iconv_close() error"); + } +#else + int p1, p2, i, j; + int jisx0208 = FALSE; + int hankaku = FALSE; + + j = 0; + if (strcmp (code, NEWJISSTR) == 0 || strcmp (code, OLDJISSTR) == 0) { + for (i = 0; from[i] != '\0' && j < BUFSIZ; i++) { + if (from[i] == ESC) { + i++; + if (from[i] == '$') { + jisx0208 = TRUE; + hankaku = FALSE; + i++; + } else if (from[i] == '(') { + jisx0208 = FALSE; + i++; + if (from[i] == 'I') /* Hankaku Kana */ + hankaku = TRUE; + else + hankaku = FALSE; + } + } else { + if (jisx0208) + to[j++] = from[i] + 128; + else if (hankaku) { + to[j++] = SS2; + to[j++] = from[i] + 128; + } else + to[j++] = from[i]; + } + } + } else if (strcmp (code, SJISSTR) == 0) { + for (i = 0; from[i] != '\0' && j < BUFSIZ; i++) { + p1 = from[i]; + if (p1 < 127) + to[j++] = p1; + else if ((p1 >= 161) && (p1 <= 223)) { + /* Hankaku Kana */ + to[j++] = SS2; + to[j++] = p1; + } else { + p2 = from[++i]; + SJIStoJIS (&p1, &p2); + to[j++] = p1 + 128; + to[j++] = p2 + 128; + } + } + } else { + gd_error ("invalid code specification: \"%s\"", code); + return; + } + + if (j >= BUFSIZ) { + gd_error ("output buffer overflow at do_convert()"); + ustrcpy (to, from); + } else + to[j] = '\0'; +#endif /* HAVE_ICONV */ +} + +static int +do_check_and_conv (unsigned char *to, unsigned char *from) +{ + static unsigned char tmp[BUFSIZ]; + unsigned char *tmp_p = &tmp[0]; + int p1, p2, i, j; + int kanji = TRUE; + + switch (DetectKanjiCode (from)) { + case NEW: + gd_error_ex(GD_DEBUG, "Kanji code is New JIS."); + do_convert (&tmp_p, &from, NEWJISSTR); + break; + case OLD: + gd_error_ex(GD_DEBUG, "Kanji code is Old JIS."); + do_convert (&tmp_p, &from, OLDJISSTR); + break; + case ESCI: + gd_error_ex(GD_DEBUG, "This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I."); + do_convert (&tmp_p, &from, NEWJISSTR); + break; + case NEC: + gd_error_ex(GD_DEBUG, "Kanji code is NEC Kanji."); + gd_error("cannot convert NEC Kanji."); + ustrcpy (tmp, from); + kanji = FALSE; + break; + case EUC: + gd_error_ex(GD_DEBUG, "Kanji code is EUC."); + ustrcpy (tmp, from); + break; + case SJIS: + gd_error_ex(GD_DEBUG, "Kanji code is SJIS."); + do_convert (&tmp_p, &from, SJISSTR); + break; + case EUCORSJIS: + gd_error_ex(GD_DEBUG, "Kanji code is EUC or SJIS."); + ustrcpy (tmp, from); + kanji = FALSE; + break; + case ASCII: + gd_error_ex(GD_DEBUG, "This is ASCII string."); + ustrcpy (tmp, from); + kanji = FALSE; + break; + default: + gd_error_ex(GD_DEBUG, "This string includes unknown code."); + ustrcpy (tmp, from); + kanji = FALSE; + break; + } + + /* Hankaku Kana ---> Zenkaku Kana */ + if (kanji) { + j = 0; + for (i = 0; tmp[i] != '\0' && j < BUFSIZ; i++) { + if (tmp[i] == SS2) { + p1 = tmp[++i]; + if (tmp[i + 1] == SS2) { + p2 = tmp[i + 2]; + if (p2 == 222 || p2 == 223) + i += 2; + else + p2 = 0; + } else + p2 = 0; + han2zen (&p1, &p2); + SJIStoJIS (&p1, &p2); + to[j++] = p1 + 128; + to[j++] = p2 + 128; + } else + to[j++] = tmp[i]; + } + + if (j >= BUFSIZ) { + gd_error("output buffer overflow at Hankaku --> Zenkaku"); + ustrcpy (to, tmp); + } else + to[j] = '\0'; + } else + ustrcpy (to, tmp); + + return kanji; +} + +int +any2eucjp (unsigned char *dest, unsigned char *src, unsigned int dest_max) +{ + static unsigned char tmp_dest[BUFSIZ]; + int ret; + + if (strlen ((const char *) src) >= BUFSIZ) { + gd_error("input string too large"); + return -1; + } + if (dest_max > BUFSIZ) { + gd_error + ("invalid maximum size of destination\nit should be less than %d.", + BUFSIZ); + return -1; + } + ret = do_check_and_conv (tmp_dest, src); + if (strlen ((const char *) tmp_dest) >= dest_max) { + gd_error("output buffer overflow"); + ustrcpy (dest, src); + return -1; + } + ustrcpy (dest, tmp_dest); + return ret; +} + +#if 0 +unsigned int +strwidth (unsigned char *s) +{ + unsigned char *t; + unsigned int i; + + t = (unsigned char *) gdMalloc (BUFSIZ); + any2eucjp (t, s, BUFSIZ); + i = strlen (t); + gdFree (t); + return i; +} + +#ifdef DEBUG +int +main () +{ + unsigned char input[BUFSIZ]; + unsigned char *output; + unsigned char *str; + int c, i = 0; + + while ((c = fgetc (stdin)) != '\n' && i < BUFSIZ) + input[i++] = c; + input[i] = '\0'; + + printf ("input : %d bytes\n", strlen ((const char *) input)); + printf ("output: %d bytes\n", strwidth (input)); + + output = (unsigned char *) gdMalloc (BUFSIZ); + any2eucjp (output, input, BUFSIZ); + str = output; + while (*str != '\0') + putchar (*(str++)); + putchar ('\n'); + gdFree (output); + + return 0; +} +#endif +#endif |