Annotation of embedaddon/php/ext/gd/libgd/gdkanji.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /* gdkanji.c (Kanji code converter)                            */
                      3: /*                 written by Masahito Yamaga (ma@yama-ga.com) */
                      4: 
                      5: #include <stdio.h>
                      6: #include <stdlib.h>
                      7: #include <string.h>
                      8: #include "gd.h"
                      9: #include "gdhelpers.h"
                     10: 
                     11: #include <stdarg.h>
                     12: #if defined(HAVE_ICONV_H) || defined(HAVE_ICONV)
                     13: #include <iconv.h>
                     14: #ifdef HAVE_ERRNO_H
                     15: #include <errno.h>
                     16: #endif
                     17: #endif
                     18: 
                     19: #if defined(HAVE_ICONV_H) && !defined(HAVE_ICONV)
                     20: #define HAVE_ICONV 1
                     21: #endif
                     22: 
                     23: #define LIBNAME "any2eucjp()"
                     24: 
                     25: #if defined(__MSC__) || defined(__BORLANDC__) || defined(__TURBOC__) || defined(_Windows) || defined(MSDOS)
                     26: #ifndef SJISPRE
                     27: #define SJISPRE 1
                     28: #endif
                     29: #endif
                     30: 
                     31: #ifdef TRUE
                     32: #undef TRUE
                     33: #endif
                     34: #ifdef FALSE
                     35: #undef FALSE
                     36: #endif
                     37: 
                     38: #define TRUE  1
                     39: #define FALSE 0
                     40: 
                     41: #define NEW 1
                     42: #define OLD 2
                     43: #define ESCI 3
                     44: #define NEC 4
                     45: #define EUC 5
                     46: #define SJIS 6
                     47: #define EUCORSJIS 7
                     48: #define ASCII 8
                     49: 
                     50: #define NEWJISSTR "JIS7"
                     51: #define OLDJISSTR "jis"
                     52: #define EUCSTR    "eucJP"
                     53: #define SJISSTR   "SJIS"
                     54: 
                     55: #define ESC 27
                     56: #define SS2 142
                     57: 
                     58: static void
                     59: debug (const char *format,...)
                     60: {
                     61: #ifdef DEBUG
                     62:   va_list args;
                     63: 
                     64:   va_start (args, format);
                     65:   fprintf (stdout, "%s: ", LIBNAME);
                     66:   vfprintf (stdout, format, args);
                     67:   fprintf (stdout, "\n");
                     68:   va_end (args);
                     69: #endif
                     70: }
                     71: 
                     72: static void
                     73: error (const char *format,...)
                     74: {
                     75:        va_list args;
                     76:        char *tmp;
                     77:        TSRMLS_FETCH();
                     78: 
                     79:        va_start(args, format);
                     80:        vspprintf(&tmp, 0, format, args);
                     81:        va_end(args);
                     82:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: %s", LIBNAME, tmp);
                     83:        efree(tmp);
                     84: }
                     85: 
                     86: /* DetectKanjiCode() derived from DetectCodeType() by Ken Lunde. */
                     87: 
                     88: static int
                     89: DetectKanjiCode (unsigned char *str)
                     90: {
                     91:   static int whatcode = ASCII;
                     92:   int oldcode = ASCII;
                     93:   int c, i;
                     94:   char *lang = NULL;
                     95: 
                     96:   c = '\1';
                     97:   i = 0;
                     98: 
                     99:   if (whatcode != EUCORSJIS && whatcode != ASCII)
                    100:     {
                    101:       oldcode = whatcode;
                    102:       whatcode = ASCII;
                    103:     }
                    104: 
                    105:   while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0')
                    106:     {
                    107:       if ((c = str[i++]) != '\0')
                    108:        {
                    109:          if (c == ESC)
                    110:            {
                    111:              c = str[i++];
                    112:              if (c == '$')
                    113:                {
                    114:                  c = str[i++];
                    115:                  if (c == 'B')
                    116:                    whatcode = NEW;
                    117:                  else if (c == '@')
                    118:                    whatcode = OLD;
                    119:                }
                    120:              else if (c == '(')
                    121:                {
                    122:                  c = str[i++];
                    123:                  if (c == 'I')
                    124:                    whatcode = ESCI;
                    125:                }
                    126:              else if (c == 'K')
                    127:                whatcode = NEC;
                    128:            }
                    129:          else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159))
                    130:            whatcode = SJIS;
                    131:          else if (c == SS2)
                    132:            {
                    133:              c = str[i++];
                    134:              if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252))
                    135:                whatcode = SJIS;
                    136:              else if (c >= 161 && c <= 223)
                    137:                whatcode = EUCORSJIS;
                    138:            }
                    139:          else if (c >= 161 && c <= 223)
                    140:            {
                    141:              c = str[i++];
                    142:              if (c >= 240 && c <= 254)
                    143:                whatcode = EUC;
                    144:              else if (c >= 161 && c <= 223)
                    145:                whatcode = EUCORSJIS;
                    146:              else if (c >= 224 && c <= 239)
                    147:                {
                    148:                  whatcode = EUCORSJIS;
                    149:                  while (c >= 64 && c != '\0' && whatcode == EUCORSJIS)
                    150:                    {
                    151:                      if (c >= 129)
                    152:                        {
                    153:                          if (c <= 141 || (c >= 143 && c <= 159))
                    154:                            whatcode = SJIS;
                    155:                          else if (c >= 253 && c <= 254)
                    156:                            whatcode = EUC;
                    157:                        }
                    158:                      c = str[i++];
                    159:                    }
                    160:                }
                    161:              else if (c <= 159)
                    162:                whatcode = SJIS;
                    163:            }
                    164:          else if (c >= 240 && c <= 254)
                    165:            whatcode = EUC;
                    166:          else if (c >= 224 && c <= 239)
                    167:            {
                    168:              c = str[i++];
                    169:              if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160))
                    170:                whatcode = SJIS;
                    171:              else if (c >= 253 && c <= 254)
                    172:                whatcode = EUC;
                    173:              else if (c >= 161 && c <= 252)
                    174:                whatcode = EUCORSJIS;
                    175:            }
                    176:        }
                    177:     }
                    178: 
                    179: #ifdef DEBUG
                    180:   if (whatcode == ASCII)
                    181:     debug ("Kanji code not included.");
                    182:   else if (whatcode == EUCORSJIS)
                    183:     debug ("Kanji code not detected.");
                    184:   else
                    185:     debug ("Kanji code detected at %d byte.", i);
                    186: #endif
                    187: 
                    188:   if (whatcode == EUCORSJIS && oldcode != ASCII)
                    189:     whatcode = oldcode;
                    190: 
                    191:   if (whatcode == EUCORSJIS)
                    192:     {
                    193:       if (getenv ("LC_ALL"))
                    194:        lang = getenv ("LC_ALL");
                    195:       else if (getenv ("LC_CTYPE"))
                    196:        lang = getenv ("LC_CTYPE");
                    197:       else if (getenv ("LANG"))
                    198:        lang = getenv ("LANG");
                    199: 
                    200:       if (lang)
                    201:        {
                    202:          if (strcmp (lang, "ja_JP.SJIS") == 0 ||
                    203: #ifdef hpux
                    204:              strcmp (lang, "japanese") == 0 ||
                    205: #endif
                    206:              strcmp (lang, "ja_JP.mscode") == 0 ||
                    207:              strcmp (lang, "ja_JP.PCK") == 0)
                    208:            whatcode = SJIS;
                    209:          else if (strncmp (lang, "ja", 2) == 0)
                    210: #ifdef SJISPRE
                    211:            whatcode = SJIS;
                    212: #else
                    213:            whatcode = EUC;
                    214: #endif
                    215:        }
                    216:     }
                    217: 
                    218:   if (whatcode == EUCORSJIS)
                    219: #ifdef SJISPRE
                    220:     whatcode = SJIS;
                    221: #else
                    222:     whatcode = EUC;
                    223: #endif
                    224: 
                    225:   return whatcode;
                    226: }
                    227: 
                    228: /* SJIStoJIS() is sjis2jis() by Ken Lunde. */
                    229: 
                    230: static void
                    231: SJIStoJIS (int *p1, int *p2)
                    232: {
                    233:   register unsigned char c1 = *p1;
                    234:   register unsigned char c2 = *p2;
                    235:   register int adjust = c2 < 159;
                    236:   register int rowOffset = c1 < 160 ? 112 : 176;
                    237:   register int cellOffset = adjust ? (31 + (c2 > 127)) : 126;
                    238: 
                    239:   *p1 = ((c1 - rowOffset) << 1) - adjust;
                    240:   *p2 -= cellOffset;
                    241: }
                    242: 
                    243: /* han2zen() was derived from han2zen() written by Ken Lunde. */
                    244: 
                    245: #define IS_DAKU(c) ((c >= 182 && c <= 196) || (c >= 202 && c <= 206) || (c == 179))
                    246: #define IS_HANDAKU(c) (c >= 202 && c <= 206)
                    247: 
                    248: static void
                    249: han2zen (int *p1, int *p2)
                    250: {
                    251:   int c = *p1;
                    252:   int daku = FALSE;
                    253:   int handaku = FALSE;
                    254:   int mtable[][2] =
                    255:   {
                    256:     {129, 66},
                    257:     {129, 117},
                    258:     {129, 118},
                    259:     {129, 65},
                    260:     {129, 69},
                    261:     {131, 146},
                    262:     {131, 64},
                    263:     {131, 66},
                    264:     {131, 68},
                    265:     {131, 70},
                    266:     {131, 72},
                    267:     {131, 131},
                    268:     {131, 133},
                    269:     {131, 135},
                    270:     {131, 98},
                    271:     {129, 91},
                    272:     {131, 65},
                    273:     {131, 67},
                    274:     {131, 69},
                    275:     {131, 71},
                    276:     {131, 73},
                    277:     {131, 74},
                    278:     {131, 76},
                    279:     {131, 78},
                    280:     {131, 80},
                    281:     {131, 82},
                    282:     {131, 84},
                    283:     {131, 86},
                    284:     {131, 88},
                    285:     {131, 90},
                    286:     {131, 92},
                    287:     {131, 94},
                    288:     {131, 96},
                    289:     {131, 99},
                    290:     {131, 101},
                    291:     {131, 103},
                    292:     {131, 105},
                    293:     {131, 106},
                    294:     {131, 107},
                    295:     {131, 108},
                    296:     {131, 109},
                    297:     {131, 110},
                    298:     {131, 113},
                    299:     {131, 116},
                    300:     {131, 119},
                    301:     {131, 122},
                    302:     {131, 125},
                    303:     {131, 126},
                    304:     {131, 128},
                    305:     {131, 129},
                    306:     {131, 130},
                    307:     {131, 132},
                    308:     {131, 134},
                    309:     {131, 136},
                    310:     {131, 137},
                    311:     {131, 138},
                    312:     {131, 139},
                    313:     {131, 140},
                    314:     {131, 141},
                    315:     {131, 143},
                    316:     {131, 147},
                    317:     {129, 74},
                    318:     {129, 75}
                    319:   };
                    320: 
                    321:   if (*p2 == 222 && IS_DAKU (*p1))
                    322:     daku = TRUE;               /* Daku-ten */
                    323:   else if (*p2 == 223 && IS_HANDAKU (*p1))
                    324:     handaku = TRUE;            /* Han-daku-ten */
                    325: 
                    326:   *p1 = mtable[c - 161][0];
                    327:   *p2 = mtable[c - 161][1];
                    328: 
                    329:   if (daku)
                    330:     {
                    331:       if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122))
                    332:        (*p2)++;
                    333:       else if (*p2 == 131 && *p2 == 69)
                    334:        *p2 = 148;
                    335:     }
                    336:   else if (handaku && *p2 >= 110 && *p2 <= 122)
                    337:     (*p2) += 2;
                    338: }
                    339: 
                    340: /* Recast strcpy to handle unsigned chars used below. */
                    341: #define ustrcpy(A,B) (strcpy((char*)(A),(const char*)(B)))
                    342: 
                    343: static void
                    344: do_convert (unsigned char *to, unsigned char *from, const char *code)
                    345: {
                    346: #ifdef HAVE_ICONV
                    347:   iconv_t cd;
                    348:   size_t from_len, to_len;
                    349: 
                    350:   if ((cd = iconv_open (EUCSTR, code)) == (iconv_t) - 1)
                    351:     {
                    352:       error ("iconv_open() error");
                    353: #ifdef HAVE_ERRNO_H
                    354:       if (errno == EINVAL)
                    355:        error ("invalid code specification: \"%s\" or \"%s\"",
                    356:               EUCSTR, code);
                    357: #endif
                    358:       strcpy ((char *) to, (const char *) from);
                    359:       return;
                    360:     }
                    361: 
                    362:   from_len = strlen ((const char *) from) + 1;
                    363:   to_len = BUFSIZ;
                    364: 
                    365:   if ((int) iconv(cd, (char **) &from, &from_len, (char **) &to, &to_len) == -1)
                    366:     {
                    367: #ifdef HAVE_ERRNO_H
                    368:       if (errno == EINVAL)
                    369:        error ("invalid end of input string");
                    370:       else if (errno == EILSEQ)
                    371:        error ("invalid code in input string");
                    372:       else if (errno == E2BIG)
                    373:        error ("output buffer overflow at do_convert()");
                    374:       else
                    375: #endif
                    376:        error ("something happen");
                    377:       strcpy ((char *) to, (const char *) from);
                    378:       return;
                    379:     }
                    380: 
                    381:   if (iconv_close (cd) != 0)
                    382:     {
                    383:       error ("iconv_close() error");
                    384:     }
                    385: #else
                    386:   int p1, p2, i, j;
                    387:   int jisx0208 = FALSE;
                    388:   int hankaku = FALSE;
                    389: 
                    390:   j = 0;
                    391:   if (strcmp (code, NEWJISSTR) == 0 || strcmp (code, OLDJISSTR) == 0)
                    392:     {
                    393:       for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
                    394:        {
                    395:          if (from[i] == ESC)
                    396:            {
                    397:              i++;
                    398:              if (from[i] == '$')
                    399:                {
                    400:                  jisx0208 = TRUE;
                    401:                  hankaku = FALSE;
                    402:                  i++;
                    403:                }
                    404:              else if (from[i] == '(')
                    405:                {
                    406:                  jisx0208 = FALSE;
                    407:                  i++;
                    408:                  if (from[i] == 'I')   /* Hankaku Kana */
                    409:                    hankaku = TRUE;
                    410:                  else
                    411:                    hankaku = FALSE;
                    412:                }
                    413:            }
                    414:          else
                    415:            {
                    416:              if (jisx0208)
                    417:                to[j++] = from[i] + 128;
                    418:              else if (hankaku)
                    419:                {
                    420:                  to[j++] = SS2;
                    421:                  to[j++] = from[i] + 128;
                    422:                }
                    423:              else
                    424:                to[j++] = from[i];
                    425:            }
                    426:        }
                    427:     }
                    428:   else if (strcmp (code, SJISSTR) == 0)
                    429:     {
                    430:       for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
                    431:        {
                    432:          p1 = from[i];
                    433:          if (p1 < 127)
                    434:            to[j++] = p1;
                    435:          else if ((p1 >= 161) && (p1 <= 223))
                    436:            {                   /* Hankaku Kana */
                    437:              to[j++] = SS2;
                    438:              to[j++] = p1;
                    439:            }
                    440:          else
                    441:            {
                    442:              p2 = from[++i];
                    443:              SJIStoJIS (&p1, &p2);
                    444:              to[j++] = p1 + 128;
                    445:              to[j++] = p2 + 128;
                    446:            }
                    447:        }
                    448:     }
                    449:   else
                    450:     {
                    451:       error ("invalid code specification: \"%s\"", code);
                    452:       return;
                    453:     }
                    454: 
                    455:   if (j >= BUFSIZ)
                    456:     {
                    457:       error ("output buffer overflow at do_convert()");
                    458:       ustrcpy (to, from);
                    459:     }
                    460:   else
                    461:     to[j] = '\0';
                    462: #endif /* HAVE_ICONV */
                    463: }
                    464: 
                    465: static int
                    466: do_check_and_conv (unsigned char *to, unsigned char *from)
                    467: {
                    468:   static unsigned char tmp[BUFSIZ];
                    469:   int p1, p2, i, j;
                    470:   int kanji = TRUE;
                    471: 
                    472:   switch (DetectKanjiCode (from))
                    473:     {
                    474:     case NEW:
                    475:       debug ("Kanji code is New JIS.");
                    476:       do_convert (tmp, from, NEWJISSTR);
                    477:       break;
                    478:     case OLD:
                    479:       debug ("Kanji code is Old JIS.");
                    480:       do_convert (tmp, from, OLDJISSTR);
                    481:       break;
                    482:     case ESCI:
                    483:       debug ("This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I.");
                    484:       do_convert (tmp, from, NEWJISSTR);
                    485:       break;
                    486:     case NEC:
                    487:       debug ("Kanji code is NEC Kanji.");
                    488:       error ("cannot convert NEC Kanji.");
                    489:       ustrcpy (tmp, from);
                    490:       kanji = FALSE;
                    491:       break;
                    492:     case EUC:
                    493:       debug ("Kanji code is EUC.");
                    494:       ustrcpy (tmp, from);
                    495:       break;
                    496:     case SJIS:
                    497:       debug ("Kanji code is SJIS.");
                    498:       do_convert (tmp, from, SJISSTR);
                    499:       break;
                    500:     case EUCORSJIS:
                    501:       debug ("Kanji code is EUC or SJIS.");
                    502:       ustrcpy (tmp, from);
                    503:       kanji = FALSE;
                    504:       break;
                    505:     case ASCII:
                    506:       debug ("This is ASCII string.");
                    507:       ustrcpy (tmp, from);
                    508:       kanji = FALSE;
                    509:       break;
                    510:     default:
                    511:       debug ("This string includes unknown code.");
                    512:       ustrcpy (tmp, from);
                    513:       kanji = FALSE;
                    514:       break;
                    515:     }
                    516: 
                    517:   /* Hankaku Kana ---> Zenkaku Kana */
                    518:   if (kanji)
                    519:     {
                    520:       j = 0;
                    521:       for (i = 0; tmp[i] != '\0' && j < BUFSIZ; i++)
                    522:        {
                    523:          if (tmp[i] == SS2)
                    524:            {
                    525:              p1 = tmp[++i];
                    526:              if (tmp[i + 1] == SS2)
                    527:                {
                    528:                  p2 = tmp[i + 2];
                    529:                  if (p2 == 222 || p2 == 223)
                    530:                    i += 2;
                    531:                  else
                    532:                    p2 = 0;
                    533:                }
                    534:              else
                    535:                p2 = 0;
                    536:              han2zen (&p1, &p2);
                    537:              SJIStoJIS (&p1, &p2);
                    538:              to[j++] = p1 + 128;
                    539:              to[j++] = p2 + 128;
                    540:            }
                    541:          else
                    542:            to[j++] = tmp[i];
                    543:        }
                    544: 
                    545:       if (j >= BUFSIZ)
                    546:        {
                    547:          error ("output buffer overflow at Hankaku --> Zenkaku");
                    548:          ustrcpy (to, tmp);
                    549:        }
                    550:       else
                    551:        to[j] = '\0';
                    552:     }
                    553:   else
                    554:     ustrcpy (to, tmp);
                    555: 
                    556:   return kanji;
                    557: }
                    558: 
                    559: int
                    560: any2eucjp (unsigned char *dest, unsigned char *src, unsigned int dest_max)
                    561: {
                    562:   static unsigned char tmp_dest[BUFSIZ];
                    563:   int ret;
                    564: 
                    565:   if (strlen ((const char *) src) >= BUFSIZ)
                    566:     {
                    567:       error ("input string too large");
                    568:       return -1;
                    569:     }
                    570:   if (dest_max > BUFSIZ)
                    571:     {
                    572:       error ("invalid maximum size of destination\nit should be less than %d.", BUFSIZ);
                    573:       return -1;
                    574:     }
                    575:   ret = do_check_and_conv (tmp_dest, src);
                    576:   if (strlen ((const char *) tmp_dest) >= dest_max)
                    577:     {
                    578:       error ("output buffer overflow");
                    579:       ustrcpy (dest, src);
                    580:       return -1;
                    581:     }
                    582:   ustrcpy (dest, tmp_dest);
                    583:   return ret;
                    584: }
                    585: 
                    586: #if 0
                    587: unsigned int
                    588: strwidth (unsigned char *s)
                    589: {
                    590:   unsigned char *t;
                    591:   unsigned int i;
                    592: 
                    593:   t = (unsigned char *) gdMalloc (BUFSIZ);
                    594:   any2eucjp (t, s, BUFSIZ);
                    595:   i = strlen (t);
                    596:   gdFree (t);
                    597:   return i;
                    598: }
                    599: 
                    600: #ifdef DEBUG
                    601: int
                    602: main ()
                    603: {
                    604:   unsigned char input[BUFSIZ];
                    605:   unsigned char *output;
                    606:   unsigned char *str;
                    607:   int c, i = 0;
                    608: 
                    609:   while ((c = fgetc (stdin)) != '\n' && i < BUFSIZ)
                    610:     input[i++] = c;
                    611:   input[i] = '\0';
                    612: 
                    613:   printf ("input : %d bytes\n", strlen ((const char *) input));
                    614:   printf ("output: %d bytes\n", strwidth (input));
                    615: 
                    616:   output = (unsigned char *) gdMalloc (BUFSIZ);
                    617:   any2eucjp (output, input, BUFSIZ);
                    618:   str = output;
                    619:   while (*str != '\0')
                    620:     putchar (*(str++));
                    621:   putchar ('\n');
                    622:   gdFree (output);
                    623: 
                    624:   return 0;
                    625: }
                    626: #endif
                    627: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>