Home | History | Annotate | Download | only in sfnt
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  ttsbit0.c                                                              */
      4 /*                                                                         */
      5 /*    TrueType and OpenType embedded bitmap support (body).                */
      6 /*    This is a heap-optimized version.                                    */
      7 /*                                                                         */
      8 /*  Copyright 2005, 2006, 2007, 2008, 2009 by                              */
      9 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
     10 /*                                                                         */
     11 /*  This file is part of the FreeType project, and may only be used,       */
     12 /*  modified, and distributed under the terms of the FreeType project      */
     13 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
     14 /*  this file you indicate that you have read the license and              */
     15 /*  understand and accept it fully.                                        */
     16 /*                                                                         */
     17 /***************************************************************************/
     18 
     19 
     20 /* This file is included by ttsbit.c */
     21 
     22 
     23 #include <ft2build.h>
     24 #include FT_INTERNAL_DEBUG_H
     25 #include FT_INTERNAL_STREAM_H
     26 #include FT_TRUETYPE_TAGS_H
     27 #include "ttsbit.h"
     28 
     29 #include "sferrors.h"
     30 
     31 
     32   /*************************************************************************/
     33   /*                                                                       */
     34   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     35   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     36   /* messages during execution.                                            */
     37   /*                                                                       */
     38 #undef  FT_COMPONENT
     39 #define FT_COMPONENT  trace_ttsbit
     40 
     41 
     42   FT_LOCAL_DEF( FT_Error )
     43   tt_face_load_eblc( TT_Face    face,
     44                      FT_Stream  stream )
     45   {
     46     FT_Error  error = SFNT_Err_Ok;
     47     FT_Fixed  version;
     48     FT_ULong  num_strikes, table_size;
     49     FT_Byte*  p;
     50     FT_Byte*  p_limit;
     51     FT_UInt   count;
     52 
     53 
     54     face->sbit_num_strikes = 0;
     55 
     56     /* this table is optional */
     57     error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
     58     if ( error )
     59       error = face->goto_table( face, TTAG_bloc, stream, &table_size );
     60     if ( error )
     61       goto Exit;
     62 
     63     if ( table_size < 8 )
     64     {
     65       FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
     66       error = SFNT_Err_Invalid_File_Format;
     67       goto Exit;
     68     }
     69 
     70     if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
     71       goto Exit;
     72 
     73     face->sbit_table_size = table_size;
     74 
     75     p       = face->sbit_table;
     76     p_limit = p + table_size;
     77 
     78     version     = FT_NEXT_ULONG( p );
     79     num_strikes = FT_NEXT_ULONG( p );
     80 
     81     if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
     82     {
     83       FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
     84       error = SFNT_Err_Invalid_File_Format;
     85       goto Fail;
     86     }
     87 
     88     /*
     89      *  Count the number of strikes available in the table.  We are a bit
     90      *  paranoid there and don't trust the data.
     91      */
     92     count = (FT_UInt)num_strikes;
     93     if ( 8 + 48UL * count > table_size )
     94       count = (FT_UInt)( ( p_limit - p ) / 48 );
     95 
     96     face->sbit_num_strikes = count;
     97 
     98     FT_TRACE3(( "sbit_num_strikes: %u\n", count ));
     99   Exit:
    100     return error;
    101 
    102   Fail:
    103     FT_FRAME_RELEASE( face->sbit_table );
    104     face->sbit_table_size = 0;
    105     goto Exit;
    106   }
    107 
    108 
    109   FT_LOCAL_DEF( void )
    110   tt_face_free_eblc( TT_Face  face )
    111   {
    112     FT_Stream  stream = face->root.stream;
    113 
    114 
    115     FT_FRAME_RELEASE( face->sbit_table );
    116     face->sbit_table_size  = 0;
    117     face->sbit_num_strikes = 0;
    118   }
    119 
    120 
    121   FT_LOCAL_DEF( FT_Error )
    122   tt_face_set_sbit_strike( TT_Face          face,
    123                            FT_Size_Request  req,
    124                            FT_ULong*        astrike_index )
    125   {
    126     return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
    127   }
    128 
    129 
    130   FT_LOCAL_DEF( FT_Error )
    131   tt_face_load_strike_metrics( TT_Face           face,
    132                                FT_ULong          strike_index,
    133                                FT_Size_Metrics*  metrics )
    134   {
    135     FT_Byte*  strike;
    136 
    137 
    138     if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
    139       return SFNT_Err_Invalid_Argument;
    140 
    141     strike = face->sbit_table + 8 + strike_index * 48;
    142 
    143     metrics->x_ppem = (FT_UShort)strike[44];
    144     metrics->y_ppem = (FT_UShort)strike[45];
    145 
    146     metrics->ascender  = (FT_Char)strike[16] << 6;  /* hori.ascender  */
    147     metrics->descender = (FT_Char)strike[17] << 6;  /* hori.descender */
    148     metrics->height    = metrics->ascender - metrics->descender;
    149 
    150     /* XXX: Is this correct? */
    151     metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB  */
    152                                       strike[18] + /* max_width      */
    153                              (FT_Char)strike[23]   /* min_advance_SB */
    154                                                  ) << 6;
    155 
    156     return SFNT_Err_Ok;
    157   }
    158 
    159 
    160   typedef struct  TT_SBitDecoderRec_
    161   {
    162     TT_Face          face;
    163     FT_Stream        stream;
    164     FT_Bitmap*       bitmap;
    165     TT_SBit_Metrics  metrics;
    166     FT_Bool          metrics_loaded;
    167     FT_Bool          bitmap_allocated;
    168     FT_Byte          bit_depth;
    169 
    170     FT_ULong         ebdt_start;
    171     FT_ULong         ebdt_size;
    172 
    173     FT_ULong         strike_index_array;
    174     FT_ULong         strike_index_count;
    175     FT_Byte*         eblc_base;
    176     FT_Byte*         eblc_limit;
    177 
    178   } TT_SBitDecoderRec, *TT_SBitDecoder;
    179 
    180 
    181   static FT_Error
    182   tt_sbit_decoder_init( TT_SBitDecoder       decoder,
    183                         TT_Face              face,
    184                         FT_ULong             strike_index,
    185                         TT_SBit_MetricsRec*  metrics )
    186   {
    187     FT_Error   error;
    188     FT_Stream  stream = face->root.stream;
    189     FT_ULong   ebdt_size;
    190 
    191 
    192     error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
    193     if ( error )
    194       error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
    195     if ( error )
    196       goto Exit;
    197 
    198     decoder->face    = face;
    199     decoder->stream  = stream;
    200     decoder->bitmap  = &face->root.glyph->bitmap;
    201     decoder->metrics = metrics;
    202 
    203     decoder->metrics_loaded   = 0;
    204     decoder->bitmap_allocated = 0;
    205 
    206     decoder->ebdt_start = FT_STREAM_POS();
    207     decoder->ebdt_size  = ebdt_size;
    208 
    209     decoder->eblc_base  = face->sbit_table;
    210     decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
    211 
    212     /* now find the strike corresponding to the index */
    213     {
    214       FT_Byte*  p;
    215 
    216 
    217       if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
    218       {
    219         error = SFNT_Err_Invalid_File_Format;
    220         goto Exit;
    221       }
    222 
    223       p = decoder->eblc_base + 8 + 48 * strike_index;
    224 
    225       decoder->strike_index_array = FT_NEXT_ULONG( p );
    226       p                          += 4;
    227       decoder->strike_index_count = FT_NEXT_ULONG( p );
    228       p                          += 34;
    229       decoder->bit_depth          = *p;
    230 
    231       if ( decoder->strike_index_array > face->sbit_table_size             ||
    232            decoder->strike_index_array + 8 * decoder->strike_index_count >
    233              face->sbit_table_size                                         )
    234         error = SFNT_Err_Invalid_File_Format;
    235     }
    236 
    237   Exit:
    238     return error;
    239   }
    240 
    241 
    242   static void
    243   tt_sbit_decoder_done( TT_SBitDecoder  decoder )
    244   {
    245     FT_UNUSED( decoder );
    246   }
    247 
    248 
    249   static FT_Error
    250   tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder  decoder )
    251   {
    252     FT_Error    error = SFNT_Err_Ok;
    253     FT_UInt     width, height;
    254     FT_Bitmap*  map = decoder->bitmap;
    255     FT_Long     size;
    256 
    257 
    258     if ( !decoder->metrics_loaded )
    259     {
    260       error = SFNT_Err_Invalid_Argument;
    261       goto Exit;
    262     }
    263 
    264     width  = decoder->metrics->width;
    265     height = decoder->metrics->height;
    266 
    267     map->width = (int)width;
    268     map->rows  = (int)height;
    269 
    270     switch ( decoder->bit_depth )
    271     {
    272     case 1:
    273       map->pixel_mode = FT_PIXEL_MODE_MONO;
    274       map->pitch      = ( map->width + 7 ) >> 3;
    275       break;
    276 
    277     case 2:
    278       map->pixel_mode = FT_PIXEL_MODE_GRAY2;
    279       map->pitch      = ( map->width + 3 ) >> 2;
    280       break;
    281 
    282     case 4:
    283       map->pixel_mode = FT_PIXEL_MODE_GRAY4;
    284       map->pitch      = ( map->width + 1 ) >> 1;
    285       break;
    286 
    287     case 8:
    288       map->pixel_mode = FT_PIXEL_MODE_GRAY;
    289       map->pitch      = map->width;
    290       break;
    291 
    292     default:
    293       error = SFNT_Err_Invalid_File_Format;
    294       goto Exit;
    295     }
    296 
    297     size = map->rows * map->pitch;
    298 
    299     /* check that there is no empty image */
    300     if ( size == 0 )
    301       goto Exit;     /* exit successfully! */
    302 
    303     error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
    304     if ( error )
    305       goto Exit;
    306 
    307     decoder->bitmap_allocated = 1;
    308 
    309   Exit:
    310     return error;
    311   }
    312 
    313 
    314   static FT_Error
    315   tt_sbit_decoder_load_metrics( TT_SBitDecoder  decoder,
    316                                 FT_Byte*       *pp,
    317                                 FT_Byte*        limit,
    318                                 FT_Bool         big )
    319   {
    320     FT_Byte*         p       = *pp;
    321     TT_SBit_Metrics  metrics = decoder->metrics;
    322 
    323 
    324     if ( p + 5 > limit )
    325       goto Fail;
    326 
    327     metrics->height       = p[0];
    328     metrics->width        = p[1];
    329     metrics->horiBearingX = (FT_Char)p[2];
    330     metrics->horiBearingY = (FT_Char)p[3];
    331     metrics->horiAdvance  = p[4];
    332 
    333     p += 5;
    334     if ( big )
    335     {
    336       if ( p + 3 > limit )
    337         goto Fail;
    338 
    339       metrics->vertBearingX = (FT_Char)p[0];
    340       metrics->vertBearingY = (FT_Char)p[1];
    341       metrics->vertAdvance  = p[2];
    342 
    343       p += 3;
    344     }
    345 
    346     decoder->metrics_loaded = 1;
    347     *pp = p;
    348     return SFNT_Err_Ok;
    349 
    350   Fail:
    351     return SFNT_Err_Invalid_Argument;
    352   }
    353 
    354 
    355   /* forward declaration */
    356   static FT_Error
    357   tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
    358                               FT_UInt         glyph_index,
    359                               FT_Int          x_pos,
    360                               FT_Int          y_pos );
    361 
    362   typedef FT_Error  (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder  decoder,
    363                                                 FT_Byte*        p,
    364                                                 FT_Byte*        plimit,
    365                                                 FT_Int          x_pos,
    366                                                 FT_Int          y_pos );
    367 
    368 
    369   static FT_Error
    370   tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder  decoder,
    371                                      FT_Byte*        p,
    372                                      FT_Byte*        limit,
    373                                      FT_Int          x_pos,
    374                                      FT_Int          y_pos )
    375   {
    376     FT_Error    error = SFNT_Err_Ok;
    377     FT_Byte*    line;
    378     FT_Int      bit_height, bit_width, pitch, width, height, h;
    379     FT_Bitmap*  bitmap;
    380 
    381 
    382     if ( !decoder->bitmap_allocated )
    383     {
    384       error = tt_sbit_decoder_alloc_bitmap( decoder );
    385       if ( error )
    386         goto Exit;
    387     }
    388 
    389     /* check that we can write the glyph into the bitmap */
    390     bitmap     = decoder->bitmap;
    391     bit_width  = bitmap->width;
    392     bit_height = bitmap->rows;
    393     pitch      = bitmap->pitch;
    394     line       = bitmap->buffer;
    395 
    396     width  = decoder->metrics->width;
    397     height = decoder->metrics->height;
    398 
    399     if ( x_pos < 0 || x_pos + width > bit_width   ||
    400          y_pos < 0 || y_pos + height > bit_height )
    401     {
    402       error = SFNT_Err_Invalid_File_Format;
    403       goto Exit;
    404     }
    405 
    406     if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
    407     {
    408       error = SFNT_Err_Invalid_File_Format;
    409       goto Exit;
    410     }
    411 
    412     /* now do the blit */
    413     line  += y_pos * pitch + ( x_pos >> 3 );
    414     x_pos &= 7;
    415 
    416     if ( x_pos == 0 )  /* the easy one */
    417     {
    418       for ( h = height; h > 0; h--, line += pitch )
    419       {
    420         FT_Byte*  write = line;
    421         FT_Int    w;
    422 
    423 
    424         for ( w = width; w >= 8; w -= 8 )
    425         {
    426           write[0] = (FT_Byte)( write[0] | *p++ );
    427           write   += 1;
    428         }
    429 
    430         if ( w > 0 )
    431           write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );
    432       }
    433     }
    434     else  /* x_pos > 0 */
    435     {
    436       for ( h = height; h > 0; h--, line += pitch )
    437       {
    438         FT_Byte*  write = line;
    439         FT_Int    w;
    440         FT_UInt   wval = 0;
    441 
    442 
    443         for ( w = width; w >= 8; w -= 8 )
    444         {
    445           wval      = (FT_UInt)( wval | *p++ );
    446           write[0]  = (FT_Byte)( write[0] | ( wval >> x_pos ) );
    447           write    += 1;
    448           wval    <<= 8;
    449         }
    450 
    451         if ( w > 0 )
    452           wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
    453 
    454         /* all bits read and there are `x_pos + w' bits to be written */
    455 
    456         write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
    457 
    458         if ( x_pos + w > 8 )
    459         {
    460           write++;
    461           wval   <<= 8;
    462           write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
    463         }
    464       }
    465     }
    466 
    467   Exit:
    468     return error;
    469   }
    470 
    471 
    472   /*
    473    * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
    474    * (with pointer `write').  In the example below, the width is 3 pixel,
    475    * and `x_pos' is 1 pixel.
    476    *
    477    *       p                               p+1
    478    *     |                               |                               |
    479    *     | 7   6   5   4   3   2   1   0 | 7   6   5   4   3   2   1   0 |...
    480    *     |                               |                               |
    481    *       +-------+   +-------+   +-------+ ...
    482    *           .           .           .
    483    *           .           .           .
    484    *           v           .           .
    485    *       +-------+       .           .
    486    * |                               | .
    487    * | 7   6   5   4   3   2   1   0 | .
    488    * |                               | .
    489    *   write               .           .
    490    *                       .           .
    491    *                       v           .
    492    *                   +-------+       .
    493    *             |                               |
    494    *             | 7   6   5   4   3   2   1   0 |
    495    *             |                               |
    496    *               write+1             .
    497    *                                   .
    498    *                                   v
    499    *                               +-------+
    500    *                         |                               |
    501    *                         | 7   6   5   4   3   2   1   0 |
    502    *                         |                               |
    503    *                           write+2
    504    *
    505    */
    506 
    507   static FT_Error
    508   tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder  decoder,
    509                                     FT_Byte*        p,
    510                                     FT_Byte*        limit,
    511                                     FT_Int          x_pos,
    512                                     FT_Int          y_pos )
    513   {
    514     FT_Error    error = SFNT_Err_Ok;
    515     FT_Byte*    line;
    516     FT_Int      bit_height, bit_width, pitch, width, height, h, nbits;
    517     FT_Bitmap*  bitmap;
    518     FT_UShort   rval;
    519 
    520 
    521     if ( !decoder->bitmap_allocated )
    522     {
    523       error = tt_sbit_decoder_alloc_bitmap( decoder );
    524       if ( error )
    525         goto Exit;
    526     }
    527 
    528     /* check that we can write the glyph into the bitmap */
    529     bitmap     = decoder->bitmap;
    530     bit_width  = bitmap->width;
    531     bit_height = bitmap->rows;
    532     pitch      = bitmap->pitch;
    533     line       = bitmap->buffer;
    534 
    535     width  = decoder->metrics->width;
    536     height = decoder->metrics->height;
    537 
    538     if ( x_pos < 0 || x_pos + width  > bit_width  ||
    539          y_pos < 0 || y_pos + height > bit_height )
    540     {
    541       error = SFNT_Err_Invalid_File_Format;
    542       goto Exit;
    543     }
    544 
    545     if ( p + ( ( width * height + 7 ) >> 3 ) > limit )
    546     {
    547       error = SFNT_Err_Invalid_File_Format;
    548       goto Exit;
    549     }
    550 
    551     /* now do the blit */
    552 
    553     /* adjust `line' to point to the first byte of the bitmap */
    554     line  += y_pos * pitch + ( x_pos >> 3 );
    555     x_pos &= 7;
    556 
    557     /* the higher byte of `rval' is used as a buffer */
    558     rval  = 0;
    559     nbits = 0;
    560 
    561     for ( h = height; h > 0; h--, line += pitch )
    562     {
    563       FT_Byte*  write = line;
    564       FT_Int    w     = width;
    565 
    566 
    567       /* handle initial byte (in target bitmap) specially if necessary */
    568       if ( x_pos )
    569       {
    570         w = ( width < 8 - x_pos ) ? width : 8 - x_pos;
    571 
    572         if ( h == height )
    573         {
    574           rval  = *p++;
    575           nbits = x_pos;
    576         }
    577         else if ( nbits < w )
    578         {
    579           if ( p < limit )
    580             rval |= *p++;
    581           nbits += 8 - w;
    582         }
    583         else
    584         {
    585           rval  >>= 8;
    586           nbits  -= w;
    587         }
    588 
    589         *write++ |= ( ( rval >> nbits ) & 0xFF ) &
    590                     ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
    591         rval    <<= 8;
    592 
    593         w = width - w;
    594       }
    595 
    596       /* handle medial bytes */
    597       for ( ; w >= 8; w -= 8 )
    598       {
    599         rval     |= *p++;
    600         *write++ |= ( rval >> nbits ) & 0xFF;
    601 
    602         rval <<= 8;
    603       }
    604 
    605       /* handle final byte if necessary */
    606       if ( w > 0 )
    607       {
    608         if ( nbits < w )
    609         {
    610           if ( p < limit )
    611             rval |= *p++;
    612           *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
    613           nbits  += 8 - w;
    614 
    615           rval <<= 8;
    616         }
    617         else
    618         {
    619           *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
    620           nbits  -= w;
    621         }
    622       }
    623     }
    624 
    625   Exit:
    626     return error;
    627   }
    628 
    629 
    630   static FT_Error
    631   tt_sbit_decoder_load_compound( TT_SBitDecoder  decoder,
    632                                  FT_Byte*        p,
    633                                  FT_Byte*        limit,
    634                                  FT_Int          x_pos,
    635                                  FT_Int          y_pos )
    636   {
    637     FT_Error  error = SFNT_Err_Ok;
    638     FT_UInt   num_components, nn;
    639 
    640     FT_Char  horiBearingX = decoder->metrics->horiBearingX;
    641     FT_Char  horiBearingY = decoder->metrics->horiBearingY;
    642     FT_Byte  horiAdvance  = decoder->metrics->horiAdvance;
    643     FT_Char  vertBearingX = decoder->metrics->vertBearingX;
    644     FT_Char  vertBearingY = decoder->metrics->vertBearingY;
    645     FT_Byte  vertAdvance  = decoder->metrics->vertAdvance;
    646 
    647 
    648     if ( p + 2 > limit )
    649       goto Fail;
    650 
    651     num_components = FT_NEXT_USHORT( p );
    652     if ( p + 4 * num_components > limit )
    653       goto Fail;
    654 
    655     if ( !decoder->bitmap_allocated )
    656     {
    657       error = tt_sbit_decoder_alloc_bitmap( decoder );
    658       if ( error )
    659         goto Exit;
    660     }
    661 
    662     for ( nn = 0; nn < num_components; nn++ )
    663     {
    664       FT_UInt  gindex = FT_NEXT_USHORT( p );
    665       FT_Byte  dx     = FT_NEXT_BYTE( p );
    666       FT_Byte  dy     = FT_NEXT_BYTE( p );
    667 
    668 
    669       /* NB: a recursive call */
    670       error = tt_sbit_decoder_load_image( decoder, gindex,
    671                                           x_pos + dx, y_pos + dy );
    672       if ( error )
    673         break;
    674     }
    675 
    676     decoder->metrics->horiBearingX = horiBearingX;
    677     decoder->metrics->horiBearingY = horiBearingY;
    678     decoder->metrics->horiAdvance  = horiAdvance;
    679     decoder->metrics->vertBearingX = vertBearingX;
    680     decoder->metrics->vertBearingY = vertBearingY;
    681     decoder->metrics->vertAdvance  = vertAdvance;
    682     decoder->metrics->width        = (FT_UInt)decoder->bitmap->width;
    683     decoder->metrics->height       = (FT_UInt)decoder->bitmap->rows;
    684 
    685   Exit:
    686     return error;
    687 
    688   Fail:
    689     error = SFNT_Err_Invalid_File_Format;
    690     goto Exit;
    691   }
    692 
    693 
    694   static FT_Error
    695   tt_sbit_decoder_load_bitmap( TT_SBitDecoder  decoder,
    696                                FT_UInt         glyph_format,
    697                                FT_ULong        glyph_start,
    698                                FT_ULong        glyph_size,
    699                                FT_Int          x_pos,
    700                                FT_Int          y_pos )
    701   {
    702     FT_Error   error;
    703     FT_Stream  stream = decoder->stream;
    704     FT_Byte*   p;
    705     FT_Byte*   p_limit;
    706     FT_Byte*   data;
    707 
    708 
    709     /* seek into the EBDT table now */
    710     if ( glyph_start + glyph_size > decoder->ebdt_size )
    711     {
    712       error = SFNT_Err_Invalid_Argument;
    713       goto Exit;
    714     }
    715 
    716     if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
    717          FT_FRAME_EXTRACT( glyph_size, data )                )
    718       goto Exit;
    719 
    720     p       = data;
    721     p_limit = p + glyph_size;
    722 
    723     /* read the data, depending on the glyph format */
    724     switch ( glyph_format )
    725     {
    726     case 1:
    727     case 2:
    728     case 8:
    729       error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
    730       break;
    731 
    732     case 6:
    733     case 7:
    734     case 9:
    735       error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
    736       break;
    737 
    738     default:
    739       error = SFNT_Err_Ok;
    740     }
    741 
    742     if ( error )
    743       goto Fail;
    744 
    745     {
    746       TT_SBitDecoder_LoadFunc  loader;
    747 
    748 
    749       switch ( glyph_format )
    750       {
    751       case 1:
    752       case 6:
    753         loader = tt_sbit_decoder_load_byte_aligned;
    754         break;
    755 
    756       case 2:
    757       case 5:
    758       case 7:
    759         loader = tt_sbit_decoder_load_bit_aligned;
    760         break;
    761 
    762       case 8:
    763         if ( p + 1 > p_limit )
    764           goto Fail;
    765 
    766         p += 1;  /* skip padding */
    767         /* fall-through */
    768 
    769       case 9:
    770         loader = tt_sbit_decoder_load_compound;
    771         break;
    772 
    773       default:
    774         goto Fail;
    775       }
    776 
    777       error = loader( decoder, p, p_limit, x_pos, y_pos );
    778     }
    779 
    780   Fail:
    781     FT_FRAME_RELEASE( data );
    782 
    783   Exit:
    784     return error;
    785   }
    786 
    787 
    788   static FT_Error
    789   tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
    790                               FT_UInt         glyph_index,
    791                               FT_Int          x_pos,
    792                               FT_Int          y_pos )
    793   {
    794     /*
    795      *  First, we find the correct strike range that applies to this
    796      *  glyph index.
    797      */
    798 
    799     FT_Byte*  p          = decoder->eblc_base + decoder->strike_index_array;
    800     FT_Byte*  p_limit    = decoder->eblc_limit;
    801     FT_ULong  num_ranges = decoder->strike_index_count;
    802     FT_UInt   start, end, index_format, image_format;
    803     FT_ULong  image_start = 0, image_end = 0, image_offset;
    804 
    805 
    806     for ( ; num_ranges > 0; num_ranges-- )
    807     {
    808       start = FT_NEXT_USHORT( p );
    809       end   = FT_NEXT_USHORT( p );
    810 
    811       if ( glyph_index >= start && glyph_index <= end )
    812         goto FoundRange;
    813 
    814       p += 4;  /* ignore index offset */
    815     }
    816     goto NoBitmap;
    817 
    818   FoundRange:
    819     image_offset = FT_NEXT_ULONG( p );
    820 
    821     /* overflow check */
    822     if ( decoder->eblc_base + decoder->strike_index_array + image_offset <
    823            decoder->eblc_base )
    824       goto Failure;
    825 
    826     p = decoder->eblc_base + decoder->strike_index_array + image_offset;
    827     if ( p + 8 > p_limit )
    828       goto NoBitmap;
    829 
    830     /* now find the glyph's location and extend within the ebdt table */
    831     index_format = FT_NEXT_USHORT( p );
    832     image_format = FT_NEXT_USHORT( p );
    833     image_offset = FT_NEXT_ULONG ( p );
    834 
    835     switch ( index_format )
    836     {
    837     case 1: /* 4-byte offsets relative to `image_offset' */
    838       {
    839         p += 4 * ( glyph_index - start );
    840         if ( p + 8 > p_limit )
    841           goto NoBitmap;
    842 
    843         image_start = FT_NEXT_ULONG( p );
    844         image_end   = FT_NEXT_ULONG( p );
    845 
    846         if ( image_start == image_end )  /* missing glyph */
    847           goto NoBitmap;
    848       }
    849       break;
    850 
    851     case 2: /* big metrics, constant image size */
    852       {
    853         FT_ULong  image_size;
    854 
    855 
    856         if ( p + 12 > p_limit )
    857           goto NoBitmap;
    858 
    859         image_size = FT_NEXT_ULONG( p );
    860 
    861         if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
    862           goto NoBitmap;
    863 
    864         image_start = image_size * ( glyph_index - start );
    865         image_end   = image_start + image_size;
    866       }
    867       break;
    868 
    869     case 3: /* 2-byte offsets relative to 'image_offset' */
    870       {
    871         p += 2 * ( glyph_index - start );
    872         if ( p + 4 > p_limit )
    873           goto NoBitmap;
    874 
    875         image_start = FT_NEXT_USHORT( p );
    876         image_end   = FT_NEXT_USHORT( p );
    877 
    878         if ( image_start == image_end )  /* missing glyph */
    879           goto NoBitmap;
    880       }
    881       break;
    882 
    883     case 4: /* sparse glyph array with (glyph,offset) pairs */
    884       {
    885         FT_ULong  mm, num_glyphs;
    886 
    887 
    888         if ( p + 4 > p_limit )
    889           goto NoBitmap;
    890 
    891         num_glyphs = FT_NEXT_ULONG( p );
    892 
    893         /* overflow check */
    894         if ( p + ( num_glyphs + 1 ) * 4 < p )
    895           goto Failure;
    896 
    897         if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
    898           goto NoBitmap;
    899 
    900         for ( mm = 0; mm < num_glyphs; mm++ )
    901         {
    902           FT_UInt  gindex = FT_NEXT_USHORT( p );
    903 
    904 
    905           if ( gindex == glyph_index )
    906           {
    907             image_start = FT_NEXT_USHORT( p );
    908             p          += 2;
    909             image_end   = FT_PEEK_USHORT( p );
    910             break;
    911           }
    912           p += 2;
    913         }
    914 
    915         if ( mm >= num_glyphs )
    916           goto NoBitmap;
    917       }
    918       break;
    919 
    920     case 5: /* constant metrics with sparse glyph codes */
    921       {
    922         FT_ULong  image_size, mm, num_glyphs;
    923 
    924 
    925         if ( p + 16 > p_limit )
    926           goto NoBitmap;
    927 
    928         image_size = FT_NEXT_ULONG( p );
    929 
    930         if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
    931           goto NoBitmap;
    932 
    933         num_glyphs = FT_NEXT_ULONG( p );
    934 
    935         /* overflow check */
    936         if ( p + 2 * num_glyphs < p )
    937           goto Failure;
    938 
    939         if ( p + 2 * num_glyphs > p_limit )
    940           goto NoBitmap;
    941 
    942         for ( mm = 0; mm < num_glyphs; mm++ )
    943         {
    944           FT_UInt  gindex = FT_NEXT_USHORT( p );
    945 
    946 
    947           if ( gindex == glyph_index )
    948             break;
    949         }
    950 
    951         if ( mm >= num_glyphs )
    952           goto NoBitmap;
    953 
    954         image_start = image_size * mm;
    955         image_end   = image_start + image_size;
    956       }
    957       break;
    958 
    959     default:
    960       goto NoBitmap;
    961     }
    962 
    963     if ( image_start > image_end )
    964       goto NoBitmap;
    965 
    966     image_end  -= image_start;
    967     image_start = image_offset + image_start;
    968 
    969     return tt_sbit_decoder_load_bitmap( decoder,
    970                                         image_format,
    971                                         image_start,
    972                                         image_end,
    973                                         x_pos,
    974                                         y_pos );
    975 
    976   Failure:
    977     return SFNT_Err_Invalid_Table;
    978 
    979   NoBitmap:
    980     return SFNT_Err_Invalid_Argument;
    981   }
    982 
    983 
    984   FT_LOCAL( FT_Error )
    985   tt_face_load_sbit_image( TT_Face              face,
    986                            FT_ULong             strike_index,
    987                            FT_UInt              glyph_index,
    988                            FT_UInt              load_flags,
    989                            FT_Stream            stream,
    990                            FT_Bitmap           *map,
    991                            TT_SBit_MetricsRec  *metrics )
    992   {
    993     TT_SBitDecoderRec  decoder[1];
    994     FT_Error           error;
    995 
    996     FT_UNUSED( load_flags );
    997     FT_UNUSED( stream );
    998     FT_UNUSED( map );
    999 
   1000 
   1001     error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
   1002     if ( !error )
   1003     {
   1004       error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 );
   1005       tt_sbit_decoder_done( decoder );
   1006     }
   1007 
   1008     return error;
   1009   }
   1010 
   1011 /* EOF */
   1012