Home | History | Annotate | Download | only in psaux
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  psconv.c                                                               */
      4 /*                                                                         */
      5 /*    Some convenience conversions (body).                                 */
      6 /*                                                                         */
      7 /*  Copyright 2006, 2008, 2009, 2012 by                                    */
      8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
      9 /*                                                                         */
     10 /*  This file is part of the FreeType project, and may only be used,       */
     11 /*  modified, and distributed under the terms of the FreeType project      */
     12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
     13 /*  this file you indicate that you have read the license and              */
     14 /*  understand and accept it fully.                                        */
     15 /*                                                                         */
     16 /***************************************************************************/
     17 
     18 
     19 #include <ft2build.h>
     20 #include FT_INTERNAL_POSTSCRIPT_AUX_H
     21 
     22 #include "psconv.h"
     23 #include "psauxerr.h"
     24 
     25 
     26   /* The following array is used by various functions to quickly convert */
     27   /* digits (both decimal and non-decimal) into numbers.                 */
     28 
     29 #if 'A' == 65
     30   /* ASCII */
     31 
     32   static const FT_Char  ft_char_table[128] =
     33   {
     34     /* 0x00 */
     35     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     36     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     37     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     38      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
     39     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
     40     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
     41     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
     42     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
     43   };
     44 
     45   /* no character >= 0x80 can represent a valid number */
     46 #define OP  >=
     47 
     48 #endif /* 'A' == 65 */
     49 
     50 #if 'A' == 193
     51   /* EBCDIC */
     52 
     53   static const FT_Char  ft_char_table[128] =
     54   {
     55     /* 0x80 */
     56     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
     57     -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
     58     -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
     59     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     60     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
     61     -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
     62     -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
     63      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
     64   };
     65 
     66   /* no character < 0x80 can represent a valid number */
     67 #define OP  <
     68 
     69 #endif /* 'A' == 193 */
     70 
     71 
     72   FT_LOCAL_DEF( FT_Int )
     73   PS_Conv_Strtol( FT_Byte**  cursor,
     74                   FT_Byte*   limit,
     75                   FT_Int     base )
     76   {
     77     FT_Byte*  p = *cursor;
     78     FT_Int    num = 0;
     79     FT_Bool   sign = 0;
     80 
     81 
     82     if ( p >= limit || base < 2 || base > 36 )
     83       return 0;
     84 
     85     if ( *p == '-' || *p == '+' )
     86     {
     87       sign = FT_BOOL( *p == '-' );
     88 
     89       p++;
     90       if ( p == limit )
     91         return 0;
     92     }
     93 
     94     for ( ; p < limit; p++ )
     95     {
     96       FT_Char  c;
     97 
     98 
     99       if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
    100         break;
    101 
    102       c = ft_char_table[*p & 0x7f];
    103 
    104       if ( c < 0 || c >= base )
    105         break;
    106 
    107       num = num * base + c;
    108     }
    109 
    110     if ( sign )
    111       num = -num;
    112 
    113     *cursor = p;
    114 
    115     return num;
    116   }
    117 
    118 
    119   FT_LOCAL_DEF( FT_Int )
    120   PS_Conv_ToInt( FT_Byte**  cursor,
    121                  FT_Byte*   limit )
    122 
    123   {
    124     FT_Byte*  p;
    125     FT_Int    num;
    126 
    127 
    128     num = PS_Conv_Strtol( cursor, limit, 10 );
    129     p   = *cursor;
    130 
    131     if ( p < limit && *p == '#' )
    132     {
    133       *cursor = p + 1;
    134 
    135       return PS_Conv_Strtol( cursor, limit, num );
    136     }
    137     else
    138       return num;
    139   }
    140 
    141 
    142   FT_LOCAL_DEF( FT_Fixed )
    143   PS_Conv_ToFixed( FT_Byte**  cursor,
    144                    FT_Byte*   limit,
    145                    FT_Int     power_ten )
    146   {
    147     FT_Byte*  p = *cursor;
    148     FT_Fixed  integral;
    149     FT_Long   decimal = 0, divider = 1;
    150     FT_Bool   sign = 0;
    151 
    152 
    153     if ( p >= limit )
    154       return 0;
    155 
    156     if ( *p == '-' || *p == '+' )
    157     {
    158       sign = FT_BOOL( *p == '-' );
    159 
    160       p++;
    161       if ( p == limit )
    162         return 0;
    163     }
    164 
    165     if ( *p != '.' )
    166       integral = PS_Conv_ToInt( &p, limit ) << 16;
    167     else
    168       integral = 0;
    169 
    170     /* read the decimal part */
    171     if ( p < limit && *p == '.' )
    172     {
    173       p++;
    174 
    175       for ( ; p < limit; p++ )
    176       {
    177         FT_Char  c;
    178 
    179 
    180         if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
    181           break;
    182 
    183         c = ft_char_table[*p & 0x7f];
    184 
    185         if ( c < 0 || c >= 10 )
    186           break;
    187 
    188         if ( !integral && power_ten > 0 )
    189         {
    190           power_ten--;
    191           decimal = decimal * 10 + c;
    192         }
    193         else
    194         {
    195           if ( divider < 10000000L )
    196           {
    197             decimal = decimal * 10 + c;
    198             divider *= 10;
    199           }
    200         }
    201       }
    202     }
    203 
    204     /* read exponent, if any */
    205     if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
    206     {
    207       p++;
    208       power_ten += PS_Conv_ToInt( &p, limit );
    209     }
    210 
    211     while ( power_ten > 0 )
    212     {
    213       integral *= 10;
    214       decimal  *= 10;
    215       power_ten--;
    216     }
    217 
    218     while ( power_ten < 0 )
    219     {
    220       integral /= 10;
    221       divider  *= 10;
    222       power_ten++;
    223     }
    224 
    225     if ( decimal )
    226       integral += FT_DivFix( decimal, divider );
    227 
    228     if ( sign )
    229       integral = -integral;
    230 
    231     *cursor = p;
    232 
    233     return integral;
    234   }
    235 
    236 
    237 #if 0
    238   FT_LOCAL_DEF( FT_UInt )
    239   PS_Conv_StringDecode( FT_Byte**  cursor,
    240                         FT_Byte*   limit,
    241                         FT_Byte*   buffer,
    242                         FT_Offset  n )
    243   {
    244     FT_Byte*  p;
    245     FT_UInt   r = 0;
    246 
    247 
    248     for ( p = *cursor; r < n && p < limit; p++ )
    249     {
    250       FT_Byte  b;
    251 
    252 
    253       if ( *p != '\\' )
    254       {
    255         buffer[r++] = *p;
    256 
    257         continue;
    258       }
    259 
    260       p++;
    261 
    262       switch ( *p )
    263       {
    264       case 'n':
    265         b = '\n';
    266         break;
    267       case 'r':
    268         b = '\r';
    269         break;
    270       case 't':
    271         b = '\t';
    272         break;
    273       case 'b':
    274         b = '\b';
    275         break;
    276       case 'f':
    277         b = '\f';
    278         break;
    279       case '\r':
    280         p++;
    281         if ( *p != '\n' )
    282         {
    283           b = *p;
    284 
    285           break;
    286         }
    287         /* no break */
    288       case '\n':
    289         continue;
    290         break;
    291       default:
    292         if ( IS_PS_DIGIT( *p ) )
    293         {
    294           b = *p - '0';
    295 
    296           p++;
    297 
    298           if ( IS_PS_DIGIT( *p ) )
    299           {
    300             b = b * 8 + *p - '0';
    301 
    302             p++;
    303 
    304             if ( IS_PS_DIGIT( *p ) )
    305               b = b * 8 + *p - '0';
    306             else
    307             {
    308               buffer[r++] = b;
    309               b = *p;
    310             }
    311           }
    312           else
    313           {
    314             buffer[r++] = b;
    315             b = *p;
    316           }
    317         }
    318         else
    319           b = *p;
    320         break;
    321       }
    322 
    323       buffer[r++] = b;
    324     }
    325 
    326     *cursor = p;
    327 
    328     return r;
    329   }
    330 #endif /* 0 */
    331 
    332 
    333   FT_LOCAL_DEF( FT_UInt )
    334   PS_Conv_ASCIIHexDecode( FT_Byte**  cursor,
    335                           FT_Byte*   limit,
    336                           FT_Byte*   buffer,
    337                           FT_Offset  n )
    338   {
    339     FT_Byte*  p;
    340     FT_UInt   r   = 0;
    341     FT_UInt   w   = 0;
    342     FT_UInt   pad = 0x01;
    343 
    344 
    345     n *= 2;
    346 
    347 #if 1
    348 
    349     p = *cursor;
    350 
    351     if ( p >= limit )
    352       return 0;
    353 
    354     if ( n > (FT_UInt)( limit - p ) )
    355       n = (FT_UInt)( limit - p );
    356 
    357     /* we try to process two nibbles at a time to be as fast as possible */
    358     for ( ; r < n; r++ )
    359     {
    360       FT_UInt  c = p[r];
    361 
    362 
    363       if ( IS_PS_SPACE( c ) )
    364         continue;
    365 
    366       if ( c OP 0x80 )
    367         break;
    368 
    369       c = ft_char_table[c & 0x7F];
    370       if ( (unsigned)c >= 16 )
    371         break;
    372 
    373       pad = ( pad << 4 ) | c;
    374       if ( pad & 0x100 )
    375       {
    376         buffer[w++] = (FT_Byte)pad;
    377         pad         = 0x01;
    378       }
    379     }
    380 
    381     if ( pad != 0x01 )
    382       buffer[w++] = (FT_Byte)( pad << 4 );
    383 
    384     *cursor = p + r;
    385 
    386     return w;
    387 
    388 #else /* 0 */
    389 
    390     for ( r = 0; r < n; r++ )
    391     {
    392       FT_Char  c;
    393 
    394 
    395       if ( IS_PS_SPACE( *p ) )
    396         continue;
    397 
    398       if ( *p OP 0x80 )
    399         break;
    400 
    401       c = ft_char_table[*p & 0x7f];
    402 
    403       if ( (unsigned)c >= 16 )
    404         break;
    405 
    406       if ( r & 1 )
    407       {
    408         *buffer = (FT_Byte)(*buffer + c);
    409         buffer++;
    410       }
    411       else
    412         *buffer = (FT_Byte)(c << 4);
    413 
    414       r++;
    415     }
    416 
    417     *cursor = p;
    418 
    419     return ( r + 1 ) / 2;
    420 
    421 #endif /* 0 */
    422 
    423   }
    424 
    425 
    426   FT_LOCAL_DEF( FT_UInt )
    427   PS_Conv_EexecDecode( FT_Byte**   cursor,
    428                        FT_Byte*    limit,
    429                        FT_Byte*    buffer,
    430                        FT_Offset   n,
    431                        FT_UShort*  seed )
    432   {
    433     FT_Byte*  p;
    434     FT_UInt   r;
    435     FT_UInt   s = *seed;
    436 
    437 
    438 #if 1
    439 
    440     p = *cursor;
    441 
    442     if ( p >= limit )
    443       return 0;
    444 
    445     if ( n > (FT_UInt)(limit - p) )
    446       n = (FT_UInt)(limit - p);
    447 
    448     for ( r = 0; r < n; r++ )
    449     {
    450       FT_UInt  val = p[r];
    451       FT_UInt  b   = ( val ^ ( s >> 8 ) );
    452 
    453 
    454       s         = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
    455       buffer[r] = (FT_Byte) b;
    456     }
    457 
    458     *cursor = p + n;
    459     *seed   = (FT_UShort)s;
    460 
    461 #else /* 0 */
    462 
    463     for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
    464     {
    465       FT_Byte  b = (FT_Byte)( *p ^ ( s >> 8 ) );
    466 
    467 
    468       s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
    469       *buffer++ = b;
    470     }
    471     *cursor = p;
    472     *seed   = s;
    473 
    474 #endif /* 0 */
    475 
    476     return r;
    477   }
    478 
    479 
    480 /* END */
    481