1/***************************************************************************/
2/*                                                                         */
3/*  ttsbit.c                                                               */
4/*                                                                         */
5/*    TrueType and OpenType embedded bitmap support (body).                */
6/*                                                                         */
7/*  Copyright 2005-2009, 2013, 2014 by                                     */
8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9/*                                                                         */
10/*  Copyright 2013 by Google, Inc.                                         */
11/*  Google Author(s): Behdad Esfahbod.                                     */
12/*                                                                         */
13/*  This file is part of the FreeType project, and may only be used,       */
14/*  modified, and distributed under the terms of the FreeType project      */
15/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
16/*  this file you indicate that you have read the license and              */
17/*  understand and accept it fully.                                        */
18/*                                                                         */
19/***************************************************************************/
20
21
22#include <ft2build.h>
23#include FT_INTERNAL_DEBUG_H
24#include FT_INTERNAL_STREAM_H
25#include FT_TRUETYPE_TAGS_H
26#include FT_BITMAP_H
27#include "ttsbit.h"
28
29#include "sferrors.h"
30
31#include "ttmtx.h"
32#include "pngshim.h"
33
34
35  /*************************************************************************/
36  /*                                                                       */
37  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
38  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
39  /* messages during execution.                                            */
40  /*                                                                       */
41#undef  FT_COMPONENT
42#define FT_COMPONENT  trace_ttsbit
43
44
45  FT_LOCAL_DEF( FT_Error )
46  tt_face_load_sbit( TT_Face    face,
47                     FT_Stream  stream )
48  {
49    FT_Error  error;
50    FT_ULong  table_size;
51
52
53    face->sbit_table       = NULL;
54    face->sbit_table_size  = 0;
55    face->sbit_table_type  = TT_SBIT_TABLE_TYPE_NONE;
56    face->sbit_num_strikes = 0;
57
58    error = face->goto_table( face, TTAG_CBLC, stream, &table_size );
59    if ( !error )
60      face->sbit_table_type = TT_SBIT_TABLE_TYPE_CBLC;
61    else
62    {
63      error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
64      if ( error )
65        error = face->goto_table( face, TTAG_bloc, stream, &table_size );
66      if ( !error )
67        face->sbit_table_type = TT_SBIT_TABLE_TYPE_EBLC;
68    }
69
70    if ( error )
71    {
72      error = face->goto_table( face, TTAG_sbix, stream, &table_size );
73      if ( !error )
74        face->sbit_table_type = TT_SBIT_TABLE_TYPE_SBIX;
75    }
76    if ( error )
77      goto Exit;
78
79    if ( table_size < 8 )
80    {
81      FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
82      error = FT_THROW( Invalid_File_Format );
83      goto Exit;
84    }
85
86    switch ( (FT_UInt)face->sbit_table_type )
87    {
88    case TT_SBIT_TABLE_TYPE_EBLC:
89    case TT_SBIT_TABLE_TYPE_CBLC:
90      {
91        FT_Byte*  p;
92        FT_Fixed  version;
93        FT_ULong  num_strikes;
94        FT_UInt   count;
95
96
97        if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
98          goto Exit;
99
100        face->sbit_table_size = table_size;
101
102        p = face->sbit_table;
103
104        version     = FT_NEXT_ULONG( p );
105        num_strikes = FT_NEXT_ULONG( p );
106
107        if ( ( version & 0xFFFF0000UL ) != 0x00020000UL )
108        {
109          error = FT_THROW( Unknown_File_Format );
110          goto Exit;
111        }
112
113        if ( num_strikes >= 0x10000UL )
114        {
115          error = FT_THROW( Invalid_File_Format );
116          goto Exit;
117        }
118
119        /*
120         *  Count the number of strikes available in the table.  We are a bit
121         *  paranoid there and don't trust the data.
122         */
123        count = (FT_UInt)num_strikes;
124        if ( 8 + 48UL * count > table_size )
125          count = (FT_UInt)( ( table_size - 8 ) / 48 );
126
127        face->sbit_num_strikes = count;
128      }
129      break;
130
131    case TT_SBIT_TABLE_TYPE_SBIX:
132      {
133        FT_UShort  version;
134        FT_UShort  flags;
135        FT_ULong   num_strikes;
136        FT_UInt    count;
137
138
139        if ( FT_FRAME_ENTER( 8 ) )
140          goto Exit;
141
142        version     = FT_GET_USHORT();
143        flags       = FT_GET_USHORT();
144        num_strikes = FT_GET_ULONG();
145
146        FT_FRAME_EXIT();
147
148        if ( version < 1 )
149        {
150          error = FT_THROW( Unknown_File_Format );
151          goto Exit;
152        }
153        if ( flags != 0x0001 || num_strikes >= 0x10000UL )
154        {
155          error = FT_THROW( Invalid_File_Format );
156          goto Exit;
157        }
158
159        /*
160         *  Count the number of strikes available in the table.  We are a bit
161         *  paranoid there and don't trust the data.
162         */
163        count = (FT_UInt)num_strikes;
164        if ( 8 + 4UL * count > table_size )
165          count = (FT_UInt)( ( table_size - 8 ) / 4 );
166
167        if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) )
168          goto Exit;
169
170        face->sbit_table_size = 8 + count * 4;
171        if ( FT_FRAME_EXTRACT( face->sbit_table_size, face->sbit_table ) )
172          goto Exit;
173
174        face->sbit_num_strikes = count;
175      }
176      break;
177
178    default:
179      error = FT_THROW( Unknown_File_Format );
180      break;
181    }
182
183    if ( !error )
184      FT_TRACE3(( "sbit_num_strikes: %u\n", face->sbit_num_strikes ));
185
186    return FT_Err_Ok;
187
188  Exit:
189    if ( error )
190    {
191      if ( face->sbit_table )
192        FT_FRAME_RELEASE( face->sbit_table );
193      face->sbit_table_size = 0;
194      face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE;
195    }
196
197    return error;
198  }
199
200
201  FT_LOCAL_DEF( void )
202  tt_face_free_sbit( TT_Face  face )
203  {
204    FT_Stream  stream = face->root.stream;
205
206
207    FT_FRAME_RELEASE( face->sbit_table );
208    face->sbit_table_size  = 0;
209    face->sbit_table_type  = TT_SBIT_TABLE_TYPE_NONE;
210    face->sbit_num_strikes = 0;
211  }
212
213
214  FT_LOCAL_DEF( FT_Error )
215  tt_face_set_sbit_strike( TT_Face          face,
216                           FT_Size_Request  req,
217                           FT_ULong*        astrike_index )
218  {
219    return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
220  }
221
222
223  FT_LOCAL_DEF( FT_Error )
224  tt_face_load_strike_metrics( TT_Face           face,
225                               FT_ULong          strike_index,
226                               FT_Size_Metrics*  metrics )
227  {
228    if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
229      return FT_THROW( Invalid_Argument );
230
231    switch ( (FT_UInt)face->sbit_table_type )
232    {
233    case TT_SBIT_TABLE_TYPE_EBLC:
234    case TT_SBIT_TABLE_TYPE_CBLC:
235      {
236        FT_Byte*  strike;
237
238
239        strike = face->sbit_table + 8 + strike_index * 48;
240
241        metrics->x_ppem = (FT_UShort)strike[44];
242        metrics->y_ppem = (FT_UShort)strike[45];
243
244        metrics->ascender  = (FT_Char)strike[16] << 6;  /* hori.ascender  */
245        metrics->descender = (FT_Char)strike[17] << 6;  /* hori.descender */
246        metrics->height    = metrics->ascender - metrics->descender;
247
248        /* Is this correct? */
249        metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB  */
250                                          strike[18] + /* max_width      */
251                                 (FT_Char)strike[23]   /* min_advance_SB */
252                                                     ) << 6;
253        return FT_Err_Ok;
254      }
255
256    case TT_SBIT_TABLE_TYPE_SBIX:
257      {
258        FT_Stream       stream = face->root.stream;
259        FT_UInt         offset, upem;
260        FT_UShort       ppem, resolution;
261        TT_HoriHeader  *hori;
262        FT_ULong        table_size;
263
264        FT_Error  error;
265        FT_Byte*  p;
266
267
268        p      = face->sbit_table + 8 + 4 * strike_index;
269        offset = FT_NEXT_ULONG( p );
270
271        error = face->goto_table( face, TTAG_sbix, stream, &table_size );
272        if ( error )
273          return error;
274
275        if ( offset + 4  > table_size )
276          return FT_THROW( Invalid_File_Format );
277
278        if ( FT_STREAM_SEEK( FT_STREAM_POS() + offset ) ||
279             FT_FRAME_ENTER( 4 )                        )
280          return error;
281
282        ppem       = FT_GET_USHORT();
283        resolution = FT_GET_USHORT();
284
285        FT_UNUSED( resolution ); /* What to do with this? */
286
287        FT_FRAME_EXIT();
288
289        upem = face->header.Units_Per_EM;
290        hori = &face->horizontal;
291
292        metrics->x_ppem = ppem;
293        metrics->y_ppem = ppem;
294
295        metrics->ascender    = ppem * hori->Ascender * 64 / upem;
296        metrics->descender   = ppem * hori->Descender * 64 / upem;
297        metrics->height      = ppem * ( hori->Ascender -
298                                        hori->Descender +
299                                        hori->Line_Gap ) * 64 / upem;
300        metrics->max_advance = ppem * hori->advance_Width_Max * 64 / upem;
301
302        return error;
303      }
304
305    default:
306      return FT_THROW( Unknown_File_Format );
307    }
308  }
309
310
311  typedef struct  TT_SBitDecoderRec_
312  {
313    TT_Face          face;
314    FT_Stream        stream;
315    FT_Bitmap*       bitmap;
316    TT_SBit_Metrics  metrics;
317    FT_Bool          metrics_loaded;
318    FT_Bool          bitmap_allocated;
319    FT_Byte          bit_depth;
320
321    FT_ULong         ebdt_start;
322    FT_ULong         ebdt_size;
323
324    FT_ULong         strike_index_array;
325    FT_ULong         strike_index_count;
326    FT_Byte*         eblc_base;
327    FT_Byte*         eblc_limit;
328
329  } TT_SBitDecoderRec, *TT_SBitDecoder;
330
331
332  static FT_Error
333  tt_sbit_decoder_init( TT_SBitDecoder       decoder,
334                        TT_Face              face,
335                        FT_ULong             strike_index,
336                        TT_SBit_MetricsRec*  metrics )
337  {
338    FT_Error   error;
339    FT_Stream  stream = face->root.stream;
340    FT_ULong   ebdt_size;
341
342
343    error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size );
344    if ( error )
345      error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
346    if ( error )
347      error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
348    if ( error )
349      goto Exit;
350
351    decoder->face    = face;
352    decoder->stream  = stream;
353    decoder->bitmap  = &face->root.glyph->bitmap;
354    decoder->metrics = metrics;
355
356    decoder->metrics_loaded   = 0;
357    decoder->bitmap_allocated = 0;
358
359    decoder->ebdt_start = FT_STREAM_POS();
360    decoder->ebdt_size  = ebdt_size;
361
362    decoder->eblc_base  = face->sbit_table;
363    decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
364
365    /* now find the strike corresponding to the index */
366    {
367      FT_Byte*  p;
368
369
370      if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
371      {
372        error = FT_THROW( Invalid_File_Format );
373        goto Exit;
374      }
375
376      p = decoder->eblc_base + 8 + 48 * strike_index;
377
378      decoder->strike_index_array = FT_NEXT_ULONG( p );
379      p                          += 4;
380      decoder->strike_index_count = FT_NEXT_ULONG( p );
381      p                          += 34;
382      decoder->bit_depth          = *p;
383
384      if ( decoder->strike_index_array > face->sbit_table_size             ||
385           decoder->strike_index_array + 8 * decoder->strike_index_count >
386             face->sbit_table_size                                         )
387        error = FT_THROW( Invalid_File_Format );
388    }
389
390  Exit:
391    return error;
392  }
393
394
395  static void
396  tt_sbit_decoder_done( TT_SBitDecoder  decoder )
397  {
398    FT_UNUSED( decoder );
399  }
400
401
402  static FT_Error
403  tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder  decoder )
404  {
405    FT_Error    error = FT_Err_Ok;
406    FT_UInt     width, height;
407    FT_Bitmap*  map = decoder->bitmap;
408    FT_Long     size;
409
410
411    if ( !decoder->metrics_loaded )
412    {
413      error = FT_THROW( Invalid_Argument );
414      goto Exit;
415    }
416
417    width  = decoder->metrics->width;
418    height = decoder->metrics->height;
419
420    map->width = (int)width;
421    map->rows  = (int)height;
422
423    switch ( decoder->bit_depth )
424    {
425    case 1:
426      map->pixel_mode = FT_PIXEL_MODE_MONO;
427      map->pitch      = ( map->width + 7 ) >> 3;
428      map->num_grays  = 2;
429      break;
430
431    case 2:
432      map->pixel_mode = FT_PIXEL_MODE_GRAY2;
433      map->pitch      = ( map->width + 3 ) >> 2;
434      map->num_grays  = 4;
435      break;
436
437    case 4:
438      map->pixel_mode = FT_PIXEL_MODE_GRAY4;
439      map->pitch      = ( map->width + 1 ) >> 1;
440      map->num_grays  = 16;
441      break;
442
443    case 8:
444      map->pixel_mode = FT_PIXEL_MODE_GRAY;
445      map->pitch      = map->width;
446      map->num_grays  = 256;
447      break;
448
449    case 32:
450      map->pixel_mode = FT_PIXEL_MODE_BGRA;
451      map->pitch      = map->width * 4;
452      map->num_grays  = 256;
453      break;
454
455    default:
456      error = FT_THROW( Invalid_File_Format );
457      goto Exit;
458    }
459
460    size = map->rows * map->pitch;
461
462    /* check that there is no empty image */
463    if ( size == 0 )
464      goto Exit;     /* exit successfully! */
465
466    error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
467    if ( error )
468      goto Exit;
469
470    decoder->bitmap_allocated = 1;
471
472  Exit:
473    return error;
474  }
475
476
477  static FT_Error
478  tt_sbit_decoder_load_metrics( TT_SBitDecoder  decoder,
479                                FT_Byte*       *pp,
480                                FT_Byte*        limit,
481                                FT_Bool         big )
482  {
483    FT_Byte*         p       = *pp;
484    TT_SBit_Metrics  metrics = decoder->metrics;
485
486
487    if ( p + 5 > limit )
488      goto Fail;
489
490    metrics->height       = p[0];
491    metrics->width        = p[1];
492    metrics->horiBearingX = (FT_Char)p[2];
493    metrics->horiBearingY = (FT_Char)p[3];
494    metrics->horiAdvance  = p[4];
495
496    p += 5;
497    if ( big )
498    {
499      if ( p + 3 > limit )
500        goto Fail;
501
502      metrics->vertBearingX = (FT_Char)p[0];
503      metrics->vertBearingY = (FT_Char)p[1];
504      metrics->vertAdvance  = p[2];
505
506      p += 3;
507    }
508
509    decoder->metrics_loaded = 1;
510    *pp = p;
511    return FT_Err_Ok;
512
513  Fail:
514    FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" ));
515    return FT_THROW( Invalid_Argument );
516  }
517
518
519  /* forward declaration */
520  static FT_Error
521  tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
522                              FT_UInt         glyph_index,
523                              FT_Int          x_pos,
524                              FT_Int          y_pos );
525
526  typedef FT_Error  (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder  decoder,
527                                                FT_Byte*        p,
528                                                FT_Byte*        plimit,
529                                                FT_Int          x_pos,
530                                                FT_Int          y_pos );
531
532
533  static FT_Error
534  tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder  decoder,
535                                     FT_Byte*        p,
536                                     FT_Byte*        limit,
537                                     FT_Int          x_pos,
538                                     FT_Int          y_pos )
539  {
540    FT_Error    error = FT_Err_Ok;
541    FT_Byte*    line;
542    FT_Int      bit_height, bit_width, pitch, width, height, line_bits, h;
543    FT_Bitmap*  bitmap;
544
545
546    /* check that we can write the glyph into the bitmap */
547    bitmap     = decoder->bitmap;
548    bit_width  = bitmap->width;
549    bit_height = bitmap->rows;
550    pitch      = bitmap->pitch;
551    line       = bitmap->buffer;
552
553    width  = decoder->metrics->width;
554    height = decoder->metrics->height;
555
556    line_bits = width * decoder->bit_depth;
557
558    if ( x_pos < 0 || x_pos + width > bit_width   ||
559         y_pos < 0 || y_pos + height > bit_height )
560    {
561      FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:"
562                  " invalid bitmap dimensions\n" ));
563      error = FT_THROW( Invalid_File_Format );
564      goto Exit;
565    }
566
567    if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit )
568    {
569      FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" ));
570      error = FT_THROW( Invalid_File_Format );
571      goto Exit;
572    }
573
574    /* now do the blit */
575    line  += y_pos * pitch + ( x_pos >> 3 );
576    x_pos &= 7;
577
578    if ( x_pos == 0 )  /* the easy one */
579    {
580      for ( h = height; h > 0; h--, line += pitch )
581      {
582        FT_Byte*  pwrite = line;
583        FT_Int    w;
584
585
586        for ( w = line_bits; w >= 8; w -= 8 )
587        {
588          pwrite[0] = (FT_Byte)( pwrite[0] | *p++ );
589          pwrite   += 1;
590        }
591
592        if ( w > 0 )
593          pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) );
594      }
595    }
596    else  /* x_pos > 0 */
597    {
598      for ( h = height; h > 0; h--, line += pitch )
599      {
600        FT_Byte*  pwrite = line;
601        FT_Int    w;
602        FT_UInt   wval = 0;
603
604
605        for ( w = line_bits; w >= 8; w -= 8 )
606        {
607          wval       = (FT_UInt)( wval | *p++ );
608          pwrite[0]  = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
609          pwrite    += 1;
610          wval     <<= 8;
611        }
612
613        if ( w > 0 )
614          wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
615
616        /* all bits read and there are `x_pos + w' bits to be written */
617
618        pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
619
620        if ( x_pos + w > 8 )
621        {
622          pwrite++;
623          wval     <<= 8;
624          pwrite[0]  = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
625        }
626      }
627    }
628
629  Exit:
630    if ( !error )
631      FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" ));
632    return error;
633  }
634
635
636  /*
637   * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
638   * (with pointer `pwrite').  In the example below, the width is 3 pixel,
639   * and `x_pos' is 1 pixel.
640   *
641   *       p                               p+1
642   *     |                               |                               |
643   *     | 7   6   5   4   3   2   1   0 | 7   6   5   4   3   2   1   0 |...
644   *     |                               |                               |
645   *       +-------+   +-------+   +-------+ ...
646   *           .           .           .
647   *           .           .           .
648   *           v           .           .
649   *       +-------+       .           .
650   * |                               | .
651   * | 7   6   5   4   3   2   1   0 | .
652   * |                               | .
653   *   pwrite              .           .
654   *                       .           .
655   *                       v           .
656   *                   +-------+       .
657   *             |                               |
658   *             | 7   6   5   4   3   2   1   0 |
659   *             |                               |
660   *               pwrite+1            .
661   *                                   .
662   *                                   v
663   *                               +-------+
664   *                         |                               |
665   *                         | 7   6   5   4   3   2   1   0 |
666   *                         |                               |
667   *                           pwrite+2
668   *
669   */
670
671  static FT_Error
672  tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder  decoder,
673                                    FT_Byte*        p,
674                                    FT_Byte*        limit,
675                                    FT_Int          x_pos,
676                                    FT_Int          y_pos )
677  {
678    FT_Error    error = FT_Err_Ok;
679    FT_Byte*    line;
680    FT_Int      bit_height, bit_width, pitch, width, height, line_bits, h, nbits;
681    FT_Bitmap*  bitmap;
682    FT_UShort   rval;
683
684
685    /* check that we can write the glyph into the bitmap */
686    bitmap     = decoder->bitmap;
687    bit_width  = bitmap->width;
688    bit_height = bitmap->rows;
689    pitch      = bitmap->pitch;
690    line       = bitmap->buffer;
691
692    width  = decoder->metrics->width;
693    height = decoder->metrics->height;
694
695    line_bits = width * decoder->bit_depth;
696
697    if ( x_pos < 0 || x_pos + width  > bit_width  ||
698         y_pos < 0 || y_pos + height > bit_height )
699    {
700      FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:"
701                  " invalid bitmap dimensions\n" ));
702      error = FT_THROW( Invalid_File_Format );
703      goto Exit;
704    }
705
706    if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit )
707    {
708      FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" ));
709      error = FT_THROW( Invalid_File_Format );
710      goto Exit;
711    }
712
713    /* now do the blit */
714
715    /* adjust `line' to point to the first byte of the bitmap */
716    line  += y_pos * pitch + ( x_pos >> 3 );
717    x_pos &= 7;
718
719    /* the higher byte of `rval' is used as a buffer */
720    rval  = 0;
721    nbits = 0;
722
723    for ( h = height; h > 0; h--, line += pitch )
724    {
725      FT_Byte*  pwrite = line;
726      FT_Int    w      = line_bits;
727
728
729      /* handle initial byte (in target bitmap) specially if necessary */
730      if ( x_pos )
731      {
732        w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos;
733
734        if ( h == height )
735        {
736          rval  = *p++;
737          nbits = x_pos;
738        }
739        else if ( nbits < w )
740        {
741          if ( p < limit )
742            rval |= *p++;
743          nbits += 8 - w;
744        }
745        else
746        {
747          rval  >>= 8;
748          nbits  -= w;
749        }
750
751        *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) &
752                     ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
753        rval     <<= 8;
754
755        w = line_bits - w;
756      }
757
758      /* handle medial bytes */
759      for ( ; w >= 8; w -= 8 )
760      {
761        rval      |= *p++;
762        *pwrite++ |= ( rval >> nbits ) & 0xFF;
763
764        rval <<= 8;
765      }
766
767      /* handle final byte if necessary */
768      if ( w > 0 )
769      {
770        if ( nbits < w )
771        {
772          if ( p < limit )
773            rval |= *p++;
774          *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
775          nbits   += 8 - w;
776
777          rval <<= 8;
778        }
779        else
780        {
781          *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
782          nbits   -= w;
783        }
784      }
785    }
786
787  Exit:
788    if ( !error )
789      FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" ));
790    return error;
791  }
792
793
794  static FT_Error
795  tt_sbit_decoder_load_compound( TT_SBitDecoder  decoder,
796                                 FT_Byte*        p,
797                                 FT_Byte*        limit,
798                                 FT_Int          x_pos,
799                                 FT_Int          y_pos )
800  {
801    FT_Error  error = FT_Err_Ok;
802    FT_UInt   num_components, nn;
803
804    FT_Char  horiBearingX = (FT_Char)decoder->metrics->horiBearingX;
805    FT_Char  horiBearingY = (FT_Char)decoder->metrics->horiBearingY;
806    FT_Byte  horiAdvance  = (FT_Byte)decoder->metrics->horiAdvance;
807    FT_Char  vertBearingX = (FT_Char)decoder->metrics->vertBearingX;
808    FT_Char  vertBearingY = (FT_Char)decoder->metrics->vertBearingY;
809    FT_Byte  vertAdvance  = (FT_Byte)decoder->metrics->vertAdvance;
810
811
812    if ( p + 2 > limit )
813      goto Fail;
814
815    num_components = FT_NEXT_USHORT( p );
816    if ( p + 4 * num_components > limit )
817    {
818      FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" ));
819      goto Fail;
820    }
821
822    FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n",
823                num_components ));
824
825    for ( nn = 0; nn < num_components; nn++ )
826    {
827      FT_UInt  gindex = FT_NEXT_USHORT( p );
828      FT_Byte  dx     = FT_NEXT_BYTE( p );
829      FT_Byte  dy     = FT_NEXT_BYTE( p );
830
831
832      /* NB: a recursive call */
833      error = tt_sbit_decoder_load_image( decoder, gindex,
834                                          x_pos + dx, y_pos + dy );
835      if ( error )
836        break;
837    }
838
839    FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" ));
840
841    decoder->metrics->horiBearingX = horiBearingX;
842    decoder->metrics->horiBearingY = horiBearingY;
843    decoder->metrics->horiAdvance  = horiAdvance;
844    decoder->metrics->vertBearingX = vertBearingX;
845    decoder->metrics->vertBearingY = vertBearingY;
846    decoder->metrics->vertAdvance  = vertAdvance;
847    decoder->metrics->width        = (FT_Byte)decoder->bitmap->width;
848    decoder->metrics->height       = (FT_Byte)decoder->bitmap->rows;
849
850  Exit:
851    return error;
852
853  Fail:
854    error = FT_THROW( Invalid_File_Format );
855    goto Exit;
856  }
857
858
859#ifdef FT_CONFIG_OPTION_USE_PNG
860
861  static FT_Error
862  tt_sbit_decoder_load_png( TT_SBitDecoder  decoder,
863                            FT_Byte*        p,
864                            FT_Byte*        limit,
865                            FT_Int          x_pos,
866                            FT_Int          y_pos )
867  {
868    FT_Error  error = FT_Err_Ok;
869    FT_ULong  png_len;
870
871
872    if ( limit - p < 4 )
873    {
874      FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
875      error = FT_THROW( Invalid_File_Format );
876      goto Exit;
877    }
878
879    png_len = FT_NEXT_ULONG( p );
880    if ( (FT_ULong)( limit - p ) < png_len )
881    {
882      FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
883      error = FT_THROW( Invalid_File_Format );
884      goto Exit;
885    }
886
887    error = Load_SBit_Png( decoder->face->root.glyph,
888                           x_pos,
889                           y_pos,
890                           decoder->bit_depth,
891                           decoder->metrics,
892                           decoder->stream->memory,
893                           p,
894                           png_len,
895                           FALSE );
896
897  Exit:
898    if ( !error )
899      FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" ));
900    return error;
901  }
902
903#endif /* FT_CONFIG_OPTION_USE_PNG */
904
905
906  static FT_Error
907  tt_sbit_decoder_load_bitmap( TT_SBitDecoder  decoder,
908                               FT_UInt         glyph_format,
909                               FT_ULong        glyph_start,
910                               FT_ULong        glyph_size,
911                               FT_Int          x_pos,
912                               FT_Int          y_pos )
913  {
914    FT_Error   error;
915    FT_Stream  stream = decoder->stream;
916    FT_Byte*   p;
917    FT_Byte*   p_limit;
918    FT_Byte*   data;
919
920
921    /* seek into the EBDT table now */
922    if ( glyph_start + glyph_size > decoder->ebdt_size )
923    {
924      error = FT_THROW( Invalid_Argument );
925      goto Exit;
926    }
927
928    if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
929         FT_FRAME_EXTRACT( glyph_size, data )                )
930      goto Exit;
931
932    p       = data;
933    p_limit = p + glyph_size;
934
935    /* read the data, depending on the glyph format */
936    switch ( glyph_format )
937    {
938    case 1:
939    case 2:
940    case 8:
941    case 17:
942      error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
943      break;
944
945    case 6:
946    case 7:
947    case 9:
948    case 18:
949      error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
950      break;
951
952    default:
953      error = FT_Err_Ok;
954    }
955
956    if ( error )
957      goto Fail;
958
959    {
960      TT_SBitDecoder_LoadFunc  loader;
961
962
963      switch ( glyph_format )
964      {
965      case 1:
966      case 6:
967        loader = tt_sbit_decoder_load_byte_aligned;
968        break;
969
970      case 2:
971      case 7:
972        {
973          /* Don't trust `glyph_format'.  For example, Apple's main Korean */
974          /* system font, `AppleMyungJo.ttf' (version 7.0d2e6), uses glyph */
975          /* format 7, but the data is format 6.  We check whether we have */
976          /* an excessive number of bytes in the image: If it is equal to  */
977          /* the value for a byte-aligned glyph, use the other loading     */
978          /* routine.                                                      */
979          /*                                                               */
980          /* Note that for some (width,height) combinations, where the     */
981          /* width is not a multiple of 8, the sizes for bit- and          */
982          /* byte-aligned data are equal, for example (7,7) or (15,6).  We */
983          /* then prefer what `glyph_format' specifies.                    */
984
985          FT_UInt  width  = decoder->metrics->width;
986          FT_UInt  height = decoder->metrics->height;
987
988          FT_UInt  bit_size  = ( width * height + 7 ) >> 3;
989          FT_UInt  byte_size = height * ( ( width + 7 ) >> 3 );
990
991
992          if ( bit_size < byte_size                  &&
993               byte_size == (FT_UInt)( p_limit - p ) )
994            loader = tt_sbit_decoder_load_byte_aligned;
995          else
996            loader = tt_sbit_decoder_load_bit_aligned;
997        }
998        break;
999
1000      case 5:
1001        loader = tt_sbit_decoder_load_bit_aligned;
1002        break;
1003
1004      case 8:
1005        if ( p + 1 > p_limit )
1006          goto Fail;
1007
1008        p += 1;  /* skip padding */
1009        /* fall-through */
1010
1011      case 9:
1012        loader = tt_sbit_decoder_load_compound;
1013        break;
1014
1015      case 17: /* small metrics, PNG image data   */
1016      case 18: /* big metrics, PNG image data     */
1017      case 19: /* metrics in EBLC, PNG image data */
1018#ifdef FT_CONFIG_OPTION_USE_PNG
1019        loader = tt_sbit_decoder_load_png;
1020        break;
1021#else
1022        error = FT_THROW( Unimplemented_Feature );
1023        goto Fail;
1024#endif /* FT_CONFIG_OPTION_USE_PNG */
1025
1026      default:
1027        error = FT_THROW( Invalid_Table );
1028        goto Fail;
1029      }
1030
1031      if ( !decoder->bitmap_allocated )
1032      {
1033        error = tt_sbit_decoder_alloc_bitmap( decoder );
1034        if ( error )
1035          goto Fail;
1036      }
1037
1038      error = loader( decoder, p, p_limit, x_pos, y_pos );
1039    }
1040
1041  Fail:
1042    FT_FRAME_RELEASE( data );
1043
1044  Exit:
1045    return error;
1046  }
1047
1048
1049  static FT_Error
1050  tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
1051                              FT_UInt         glyph_index,
1052                              FT_Int          x_pos,
1053                              FT_Int          y_pos )
1054  {
1055    /*
1056     *  First, we find the correct strike range that applies to this
1057     *  glyph index.
1058     */
1059
1060    FT_Byte*  p          = decoder->eblc_base + decoder->strike_index_array;
1061    FT_Byte*  p_limit    = decoder->eblc_limit;
1062    FT_ULong  num_ranges = decoder->strike_index_count;
1063    FT_UInt   start, end, index_format, image_format;
1064    FT_ULong  image_start = 0, image_end = 0, image_offset;
1065
1066
1067    for ( ; num_ranges > 0; num_ranges-- )
1068    {
1069      start = FT_NEXT_USHORT( p );
1070      end   = FT_NEXT_USHORT( p );
1071
1072      if ( glyph_index >= start && glyph_index <= end )
1073        goto FoundRange;
1074
1075      p += 4;  /* ignore index offset */
1076    }
1077    goto NoBitmap;
1078
1079  FoundRange:
1080    image_offset = FT_NEXT_ULONG( p );
1081
1082    /* overflow check */
1083    p = decoder->eblc_base + decoder->strike_index_array;
1084    if ( image_offset > (FT_ULong)( p_limit - p ) )
1085      goto Failure;
1086
1087    p += image_offset;
1088    if ( p + 8 > p_limit )
1089      goto NoBitmap;
1090
1091    /* now find the glyph's location and extend within the ebdt table */
1092    index_format = FT_NEXT_USHORT( p );
1093    image_format = FT_NEXT_USHORT( p );
1094    image_offset = FT_NEXT_ULONG ( p );
1095
1096    switch ( index_format )
1097    {
1098    case 1: /* 4-byte offsets relative to `image_offset' */
1099      p += 4 * ( glyph_index - start );
1100      if ( p + 8 > p_limit )
1101        goto NoBitmap;
1102
1103      image_start = FT_NEXT_ULONG( p );
1104      image_end   = FT_NEXT_ULONG( p );
1105
1106      if ( image_start == image_end )  /* missing glyph */
1107        goto NoBitmap;
1108      break;
1109
1110    case 2: /* big metrics, constant image size */
1111      {
1112        FT_ULong  image_size;
1113
1114
1115        if ( p + 12 > p_limit )
1116          goto NoBitmap;
1117
1118        image_size = FT_NEXT_ULONG( p );
1119
1120        if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
1121          goto NoBitmap;
1122
1123        image_start = image_size * ( glyph_index - start );
1124        image_end   = image_start + image_size;
1125      }
1126      break;
1127
1128    case 3: /* 2-byte offsets relative to 'image_offset' */
1129      p += 2 * ( glyph_index - start );
1130      if ( p + 4 > p_limit )
1131        goto NoBitmap;
1132
1133      image_start = FT_NEXT_USHORT( p );
1134      image_end   = FT_NEXT_USHORT( p );
1135
1136      if ( image_start == image_end )  /* missing glyph */
1137        goto NoBitmap;
1138      break;
1139
1140    case 4: /* sparse glyph array with (glyph,offset) pairs */
1141      {
1142        FT_ULong  mm, num_glyphs;
1143
1144
1145        if ( p + 4 > p_limit )
1146          goto NoBitmap;
1147
1148        num_glyphs = FT_NEXT_ULONG( p );
1149
1150        /* overflow check for p + ( num_glyphs + 1 ) * 4 */
1151        if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) )
1152          goto NoBitmap;
1153
1154        for ( mm = 0; mm < num_glyphs; mm++ )
1155        {
1156          FT_UInt  gindex = FT_NEXT_USHORT( p );
1157
1158
1159          if ( gindex == glyph_index )
1160          {
1161            image_start = FT_NEXT_USHORT( p );
1162            p          += 2;
1163            image_end   = FT_PEEK_USHORT( p );
1164            break;
1165          }
1166          p += 2;
1167        }
1168
1169        if ( mm >= num_glyphs )
1170          goto NoBitmap;
1171      }
1172      break;
1173
1174    case 5: /* constant metrics with sparse glyph codes */
1175    case 19:
1176      {
1177        FT_ULong  image_size, mm, num_glyphs;
1178
1179
1180        if ( p + 16 > p_limit )
1181          goto NoBitmap;
1182
1183        image_size = FT_NEXT_ULONG( p );
1184
1185        if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
1186          goto NoBitmap;
1187
1188        num_glyphs = FT_NEXT_ULONG( p );
1189
1190        /* overflow check for p + 2 * num_glyphs */
1191        if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) )
1192          goto NoBitmap;
1193
1194        for ( mm = 0; mm < num_glyphs; mm++ )
1195        {
1196          FT_UInt  gindex = FT_NEXT_USHORT( p );
1197
1198
1199          if ( gindex == glyph_index )
1200            break;
1201        }
1202
1203        if ( mm >= num_glyphs )
1204          goto NoBitmap;
1205
1206        image_start = image_size * mm;
1207        image_end   = image_start + image_size;
1208      }
1209      break;
1210
1211    default:
1212      goto NoBitmap;
1213    }
1214
1215    if ( image_start > image_end )
1216      goto NoBitmap;
1217
1218    image_end  -= image_start;
1219    image_start = image_offset + image_start;
1220
1221    FT_TRACE3(( "tt_sbit_decoder_load_image:"
1222                " found sbit (format %d) for glyph index %d\n",
1223                image_format, glyph_index ));
1224
1225    return tt_sbit_decoder_load_bitmap( decoder,
1226                                        image_format,
1227                                        image_start,
1228                                        image_end,
1229                                        x_pos,
1230                                        y_pos );
1231
1232  Failure:
1233    return FT_THROW( Invalid_Table );
1234
1235  NoBitmap:
1236    FT_TRACE4(( "tt_sbit_decoder_load_image:"
1237                " no sbit found for glyph index %d\n", glyph_index ));
1238
1239    return FT_THROW( Invalid_Argument );
1240  }
1241
1242
1243  static FT_Error
1244  tt_face_load_sbix_image( TT_Face              face,
1245                           FT_ULong             strike_index,
1246                           FT_UInt              glyph_index,
1247                           FT_Stream            stream,
1248                           FT_Bitmap           *map,
1249                           TT_SBit_MetricsRec  *metrics )
1250  {
1251    FT_UInt   sbix_pos, strike_offset, glyph_start, glyph_end;
1252    FT_ULong  table_size;
1253    FT_Int    originOffsetX, originOffsetY;
1254    FT_Tag    graphicType;
1255    FT_Int    recurse_depth = 0;
1256
1257    FT_Error  error;
1258    FT_Byte*  p;
1259
1260    FT_UNUSED( map );
1261
1262
1263    metrics->width  = 0;
1264    metrics->height = 0;
1265
1266    p = face->sbit_table + 8 + 4 * strike_index;
1267    strike_offset = FT_NEXT_ULONG( p );
1268
1269    error = face->goto_table( face, TTAG_sbix, stream, &table_size );
1270    if ( error )
1271      return error;
1272    sbix_pos = FT_STREAM_POS();
1273
1274  retry:
1275    if ( glyph_index > (FT_UInt)face->root.num_glyphs )
1276      return FT_THROW( Invalid_Argument );
1277
1278    if ( strike_offset >= table_size                          ||
1279         table_size - strike_offset < 4 + glyph_index * 4 + 8 )
1280      return FT_THROW( Invalid_File_Format );
1281
1282    if ( FT_STREAM_SEEK( sbix_pos + strike_offset + 4 + glyph_index * 4 ) ||
1283         FT_FRAME_ENTER( 8 )                                              )
1284      return error;
1285
1286    glyph_start = FT_GET_ULONG();
1287    glyph_end   = FT_GET_ULONG();
1288
1289    FT_FRAME_EXIT();
1290
1291    if ( glyph_start == glyph_end )
1292      return FT_THROW( Invalid_Argument );
1293    if ( glyph_start > glyph_end                ||
1294         glyph_end - glyph_start < 8            ||
1295         table_size - strike_offset < glyph_end )
1296      return FT_THROW( Invalid_File_Format );
1297
1298    if ( FT_STREAM_SEEK( sbix_pos + strike_offset + glyph_start ) ||
1299         FT_FRAME_ENTER( glyph_end - glyph_start )                )
1300      return error;
1301
1302    originOffsetX = FT_GET_SHORT();
1303    originOffsetY = FT_GET_SHORT();
1304
1305    graphicType = FT_GET_TAG4();
1306
1307    switch ( graphicType )
1308    {
1309    case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ):
1310      if ( recurse_depth < 4 )
1311      {
1312        glyph_index = FT_GET_USHORT();
1313        FT_FRAME_EXIT();
1314        recurse_depth++;
1315        goto retry;
1316      }
1317      error = FT_THROW( Invalid_File_Format );
1318      break;
1319
1320    case FT_MAKE_TAG( 'p', 'n', 'g', ' ' ):
1321#ifdef FT_CONFIG_OPTION_USE_PNG
1322      error = Load_SBit_Png( face->root.glyph,
1323                             0,
1324                             0,
1325                             32,
1326                             metrics,
1327                             stream->memory,
1328                             stream->cursor,
1329                             glyph_end - glyph_start - 8,
1330                             TRUE );
1331#else
1332      error = FT_THROW( Unimplemented_Feature );
1333#endif
1334      break;
1335
1336    case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ):
1337    case FT_MAKE_TAG( 't', 'i', 'f', 'f' ):
1338      error = FT_THROW( Unknown_File_Format );
1339      break;
1340
1341    default:
1342      error = FT_THROW( Unimplemented_Feature );
1343      break;
1344    }
1345
1346    FT_FRAME_EXIT();
1347
1348    if ( !error )
1349    {
1350      FT_Short   abearing;
1351      FT_UShort  aadvance;
1352
1353
1354      tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
1355
1356      metrics->horiBearingX = (FT_Short)originOffsetX;
1357      metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
1358      metrics->horiAdvance  = (FT_Short)( aadvance *
1359                                          face->root.size->metrics.x_ppem /
1360                                          face->header.Units_Per_EM );
1361    }
1362
1363    return error;
1364  }
1365
1366  FT_LOCAL( FT_Error )
1367  tt_face_load_sbit_image( TT_Face              face,
1368                           FT_ULong             strike_index,
1369                           FT_UInt              glyph_index,
1370                           FT_UInt              load_flags,
1371                           FT_Stream            stream,
1372                           FT_Bitmap           *map,
1373                           TT_SBit_MetricsRec  *metrics )
1374  {
1375    FT_Error  error = FT_Err_Ok;
1376
1377
1378    switch ( (FT_UInt)face->sbit_table_type )
1379    {
1380    case TT_SBIT_TABLE_TYPE_EBLC:
1381    case TT_SBIT_TABLE_TYPE_CBLC:
1382      {
1383        TT_SBitDecoderRec  decoder[1];
1384
1385
1386        error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
1387        if ( !error )
1388        {
1389          error = tt_sbit_decoder_load_image( decoder,
1390                                              glyph_index,
1391                                              0,
1392                                              0 );
1393          tt_sbit_decoder_done( decoder );
1394        }
1395      }
1396      break;
1397
1398    case TT_SBIT_TABLE_TYPE_SBIX:
1399      error = tt_face_load_sbix_image( face,
1400                                       strike_index,
1401                                       glyph_index,
1402                                       stream,
1403                                       map,
1404                                       metrics );
1405      break;
1406
1407    default:
1408      error = FT_THROW( Unknown_File_Format );
1409      break;
1410    }
1411
1412    /* Flatten color bitmaps if color was not requested. */
1413    if ( !error                                &&
1414         !( load_flags & FT_LOAD_COLOR )       &&
1415         map->pixel_mode == FT_PIXEL_MODE_BGRA )
1416    {
1417      FT_Bitmap   new_map;
1418      FT_Library  library = face->root.glyph->library;
1419
1420
1421      FT_Bitmap_New( &new_map );
1422
1423      /* Convert to 8bit grayscale. */
1424      error = FT_Bitmap_Convert( library, map, &new_map, 1 );
1425      if ( error )
1426        FT_Bitmap_Done( library, &new_map );
1427      else
1428      {
1429        map->pixel_mode = new_map.pixel_mode;
1430        map->pitch      = new_map.pitch;
1431        map->num_grays  = new_map.num_grays;
1432
1433        ft_glyphslot_set_bitmap( face->root.glyph, new_map.buffer );
1434        face->root.glyph->internal->flags |= FT_GLYPH_OWN_BITMAP;
1435      }
1436    }
1437
1438    return error;
1439  }
1440
1441
1442/* EOF */
1443