Annotation of embedaddon/php/ext/gd/libgd/gdkanji.c, revision 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>