summaryrefslogtreecommitdiff
path: root/Build/source/libs/gd/gdkanji.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/gd/gdkanji.c')
-rw-r--r--Build/source/libs/gd/gdkanji.c662
1 files changed, 662 insertions, 0 deletions
diff --git a/Build/source/libs/gd/gdkanji.c b/Build/source/libs/gd/gdkanji.c
new file mode 100644
index 00000000000..7319337752d
--- /dev/null
+++ b/Build/source/libs/gd/gdkanji.c
@@ -0,0 +1,662 @@
+/* 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"
+
+#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)
+{
+ return (iconv_t) (-1);
+}
+
+size_t
+iconv (iconv_t cd, ICONV_CONST char **inbuf, size_t * inbytesleft,
+ char **outbuf, size_t * outbytesleft)
+{
+ return 0;
+}
+
+int
+iconv_close (iconv_t 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
+
+static void
+debug (const char *format, ...)
+{
+#ifdef DEBUG
+ va_list args;
+
+ va_start (args, format);
+ fprintf (stdout, "%s: ", LIBNAME);
+ vfprintf (stdout, format, args);
+ fprintf (stdout, "\n");
+ va_end (args);
+#endif
+}
+
+static void
+error (const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ fprintf (stderr, "%s: ", LIBNAME);
+ vfprintf (stderr, format, args);
+ fprintf (stderr, "\n");
+ va_end (args);
+}
+
+/* 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)
+ debug ("Kanji code not included.");
+ else if (whatcode == EUCORSJIS)
+ debug ("Kanji code not detected.");
+ else
+ 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)
+ {
+ error ("iconv_open() error");
+#ifdef HAVE_ERRNO_H
+ if (errno == EINVAL)
+ 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)
+ error ("invalid end of input string");
+ else if (errno == EILSEQ)
+ error ("invalid code in input string");
+ else if (errno == E2BIG)
+ error ("output buffer overflow at do_convert()");
+ else
+#endif
+ error ("something happen");
+ ustrcpy (to, from);
+ return;
+ }
+
+ if (iconv_close (cd) != 0)
+ {
+ 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
+ {
+ error ("invalid code specification: \"%s\"", code);
+ return;
+ }
+
+ if (j >= BUFSIZ)
+ {
+ 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:
+ debug ("Kanji code is New JIS.");
+ do_convert (&tmp_p, &from, NEWJISSTR);
+ break;
+ case OLD:
+ debug ("Kanji code is Old JIS.");
+ do_convert (&tmp_p, &from, OLDJISSTR);
+ break;
+ case ESCI:
+ debug
+ ("This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I.");
+ do_convert (&tmp_p, &from, NEWJISSTR);
+ break;
+ case NEC:
+ debug ("Kanji code is NEC Kanji.");
+ error ("cannot convert NEC Kanji.");
+ ustrcpy (tmp, from);
+ kanji = FALSE;
+ break;
+ case EUC:
+ debug ("Kanji code is EUC.");
+ ustrcpy (tmp, from);
+ break;
+ case SJIS:
+ debug ("Kanji code is SJIS.");
+ do_convert (&tmp_p, &from, SJISSTR);
+ break;
+ case EUCORSJIS:
+ debug ("Kanji code is EUC or SJIS.");
+ ustrcpy (tmp, from);
+ kanji = FALSE;
+ break;
+ case ASCII:
+ debug ("This is ASCII string.");
+ ustrcpy (tmp, from);
+ kanji = FALSE;
+ break;
+ default:
+ 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)
+ {
+ 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)
+ {
+ error ("input string too large");
+ return -1;
+ }
+ if (dest_max > BUFSIZ)
+ {
+ 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)
+ {
+ 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