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