/****************************************************************************
 *
 * sfwoff2.c
 *
 *   WOFF2 format management (base).
 *
 * Copyright (C) 2019-2022 by
 * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * This file is part of the FreeType project, and may only be used,
 * modified, and distributed under the terms of the FreeType project
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
 * this file you indicate that you have read the license and
 * understand and accept it fully.
 *
 */

#include "sfwoff2.h"
#include "woff2tags.h"
#include <freetype/tttags.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>


#ifdef FT_CONFIG_OPTION_USE_BROTLI

#include <brotli/decode.h>


  /**************************************************************************
   *
   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
   * messages during execution.
   */
#undef  FT_COMPONENT
#define FT_COMPONENT  sfwoff2


#define READ_255USHORT( var )  FT_SET_ERROR( Read255UShort( stream, &var ) )

#define READ_BASE128( var )    FT_SET_ERROR( ReadBase128( stream, &var ) )

  /* `var' should be FT_ULong */
#define ROUND4( var )          ( ( var + 3 ) & ~3UL )

#define WRITE_USHORT( p, v )                \
          do                                \
          {                                 \
            *(p)++ = (FT_Byte)( (v) >> 8 ); \
            *(p)++ = (FT_Byte)( (v) >> 0 ); \
                                            \
          } while ( 0 )

#define WRITE_ULONG( p, v )                  \
          do                                 \
          {                                  \
            *(p)++ = (FT_Byte)( (v) >> 24 ); \
            *(p)++ = (FT_Byte)( (v) >> 16 ); \
            *(p)++ = (FT_Byte)( (v) >>  8 ); \
            *(p)++ = (FT_Byte)( (v) >>  0 ); \
                                             \
          } while ( 0 )

#define WRITE_SHORT( p, v )                 \
          do                                \
          {                                 \
            *(p)++ = (FT_Byte)( (v) >> 8 ); \
            *(p)++ = (FT_Byte)( (v) >> 0 ); \
                                            \
          } while ( 0 )

#define WRITE_SFNT_BUF( buf, s ) \
          write_buf( &sfnt, sfnt_size, &dest_offset, buf, s, memory )

#define WRITE_SFNT_BUF_AT( offset, buf, s ) \
          write_buf( &sfnt, sfnt_size, &offset, buf, s, memory )

#define N_CONTOUR_STREAM    0
#define N_POINTS_STREAM     1
#define FLAG_STREAM         2
#define GLYPH_STREAM        3
#define COMPOSITE_STREAM    4
#define BBOX_STREAM         5
#define INSTRUCTION_STREAM  6

#define HAVE_OVERLAP_SIMPLE_BITMAP  0x1


  static void
  stream_close( FT_Stream  stream )
  {
    FT_Memory  memory = stream->memory;


    FT_FREE( stream->base );

    stream->size  = 0;
    stream->close = NULL;
  }


  FT_COMPARE_DEF( int )
  compare_tags( const void*  a,
                const void*  b )
  {
    WOFF2_Table  table1 = *(WOFF2_Table*)a;
    WOFF2_Table  table2 = *(WOFF2_Table*)b;

    FT_Tag  tag1 = table1->Tag;
    FT_Tag  tag2 = table2->Tag;


    if ( tag1 > tag2 )
      return 1;
    else if ( tag1 < tag2 )
      return -1;
    else
      return 0;
  }


  static FT_Error
  Read255UShort( FT_Stream   stream,
                 FT_UShort*  value )
  {
    const FT_Byte    oneMoreByteCode1 = 255;
    const FT_Byte    oneMoreByteCode2 = 254;
    const FT_Byte    wordCode         = 253;
    const FT_UShort  lowestUCode      = 253;

    FT_Error   error        = FT_Err_Ok;
    FT_Byte    code;
    FT_Byte    result_byte  = 0;
    FT_UShort  result_short = 0;


    if ( FT_READ_BYTE( code ) )
      return error;
    if ( code == wordCode )
    {
      /* Read next two bytes and store `FT_UShort' value. */
      if ( FT_READ_USHORT( result_short ) )
        return error;
      *value = result_short;
      return FT_Err_Ok;
    }
    else if ( code == oneMoreByteCode1 )
    {
      if ( FT_READ_BYTE( result_byte ) )
        return error;
      *value = result_byte + lowestUCode;
      return FT_Err_Ok;
    }
    else if ( code == oneMoreByteCode2 )
    {
      if ( FT_READ_BYTE( result_byte ) )
        return error;
      *value = result_byte + lowestUCode * 2;
      return FT_Err_Ok;
    }
    else
    {
      *value = code;
      return FT_Err_Ok;
    }
  }


  static FT_Error
  ReadBase128( FT_Stream  stream,
               FT_ULong*  value )
  {
    FT_ULong  result = 0;
    FT_Int    i;
    FT_Byte   code;
    FT_Error  error  = FT_Err_Ok;


    for ( i = 0; i < 5; ++i )
    {
      code = 0;
      if ( FT_READ_BYTE( code ) )
        return error;

      /* Leading zeros are invalid. */
      if ( i == 0 && code == 0x80 )
        return FT_THROW( Invalid_Table );

      /* If any of top seven bits are set then we're about to overflow. */
      if ( result & 0xfe000000 )
        return FT_THROW( Invalid_Table );

      result = ( result << 7 ) | ( code & 0x7f );

      /* Spin until most significant bit of data byte is false. */
      if ( ( code & 0x80 ) == 0 )
      {
        *value = result;
        return FT_Err_Ok;
      }
    }

    /* Make sure not to exceed the size bound. */
    return FT_THROW( Invalid_Table );
  }


  /* Extend memory of `dst_bytes' buffer and copy data from `src'. */
  static FT_Error
  write_buf( FT_Byte**  dst_bytes,
             FT_ULong*  dst_size,
             FT_ULong*  offset,
             FT_Byte*   src,
             FT_ULong   size,
             FT_Memory  memory )
  {
    FT_Error  error = FT_Err_Ok;
    /* We are reallocating memory for `dst', so its pointer may change. */
    FT_Byte*  dst   = *dst_bytes;


    /* Check whether we are within limits. */
    if ( ( *offset + size ) > WOFF2_DEFAULT_MAX_SIZE  )
      return FT_THROW( Array_Too_Large );

    /* Reallocate `dst'. */
    if ( ( *offset + size ) > *dst_size )
    {
      FT_TRACE6(( "Reallocating %lu to %lu.\n",
                  *dst_size, (*offset + size) ));
      if ( FT_QREALLOC( dst,
                        (FT_ULong)( *dst_size ),
                        (FT_ULong)( *offset + size ) ) )
        goto Exit;

      *dst_size = *offset + size;
    }

    /* Copy data. */
    ft_memcpy( dst + *offset, src, size );

    *offset += size;
    /* Set pointer of `dst' to its correct value. */
    *dst_bytes = dst;

  Exit:
    return error;
  }


  /* Pad buffer to closest multiple of 4. */
  static FT_Error
  pad4( FT_Byte**  sfnt_bytes,
        FT_ULong*  sfnt_size,
        FT_ULong*  out_offset,
        FT_Memory  memory )
  {
    FT_Byte*  sfnt        = *sfnt_bytes;
    FT_ULong  dest_offset = *out_offset;

    FT_Byte   zeroes[] = { 0, 0, 0 };
    FT_ULong  pad_bytes;


    if ( dest_offset + 3 < dest_offset )
      return FT_THROW( Invalid_Table );

    pad_bytes = ROUND4( dest_offset ) - dest_offset;
    if ( pad_bytes > 0 )
    {
      if ( WRITE_SFNT_BUF( &zeroes[0], pad_bytes ) )
        return FT_THROW( Invalid_Table );
    }

    *sfnt_bytes = sfnt;
    *out_offset = dest_offset;
    return FT_Err_Ok;
  }


  /* Calculate table checksum of `buf'. */
  static FT_ULong
  compute_ULong_sum( FT_Byte*  buf,
                     FT_ULong  size )
  {
    FT_ULong  checksum     = 0;
    FT_ULong  aligned_size = size & ~3UL;
    FT_ULong  i;
    FT_ULong  v;


    for ( i = 0; i < aligned_size; i += 4 )
      checksum += ( (FT_ULong)buf[i    ] << 24 ) |
                  ( (FT_ULong)buf[i + 1] << 16 ) |
                  ( (FT_ULong)buf[i + 2] <<  8 ) |
                  ( (FT_ULong)buf[i + 3] <<  0 );

    /* If size is not aligned to 4, treat as if it is padded with 0s. */
    if ( size != aligned_size )
    {
      v = 0;
      for ( i = aligned_size ; i < size; ++i )
        v |= (FT_ULong)buf[i] << ( 24 - 8 * ( i & 3 ) );
      checksum += v;
    }

    return checksum;
  }


  static FT_Error
  woff2_decompress( FT_Byte*        dst,
                    FT_ULong        dst_size,
                    const FT_Byte*  src,
                    FT_ULong        src_size )
  {
    /* this cast is only of importance on 32bit systems; */
    /* we don't validate it                              */
    FT_Offset            uncompressed_size = (FT_Offset)dst_size;
    BrotliDecoderResult  result;


    result = BrotliDecoderDecompress( src_size,
                                      src,
                                      &uncompressed_size,
                                      dst );

    if ( result != BROTLI_DECODER_RESULT_SUCCESS ||
         uncompressed_size != dst_size           )
    {
      FT_ERROR(( "woff2_decompress: Stream length mismatch.\n" ));
      return FT_THROW( Invalid_Table );
    }

    FT_TRACE2(( "woff2_decompress: Brotli stream decompressed.\n" ));
    return FT_Err_Ok;
  }


  static WOFF2_Table
  find_table( WOFF2_Table*  tables,
              FT_UShort     num_tables,
              FT_Tag        tag )
  {
    FT_Int  i;


    for ( i = 0; i < num_tables; i++ )
    {
      if ( tables[i]->Tag == tag )
        return tables[i];
    }
    return NULL;
  }


  /* Read `numberOfHMetrics' field from `hhea' table. */
  static FT_Error
  read_num_hmetrics( FT_Stream   stream,
                     FT_UShort*  num_hmetrics )
  {
    FT_Error   error = FT_Err_Ok;
    FT_UShort  num_metrics;


    if ( FT_STREAM_SKIP( 34 )  )
      return FT_THROW( Invalid_Table );

    if ( FT_READ_USHORT( num_metrics ) )
      return FT_THROW( Invalid_Table );

    *num_hmetrics = num_metrics;

    return error;
  }


  /* An auxiliary function for overflow-safe addition. */
  static FT_Int
  with_sign( FT_Byte  flag,
             FT_Int   base_val )
  {
    /* Precondition: 0 <= base_val < 65536 (to avoid overflow). */
    return ( flag & 1 ) ? base_val : -base_val;
  }


  /* An auxiliary function for overflow-safe addition. */
  static FT_Int
  safe_int_addition( FT_Int   a,
                     FT_Int   b,
                     FT_Int*  result )
  {
    if ( ( ( a > 0 ) && ( b > FT_INT_MAX - a ) ) ||
         ( ( a < 0 ) && ( b < FT_INT_MIN - a ) ) )
      return FT_THROW( Invalid_Table );

    *result = a + b;
    return FT_Err_Ok;
  }


  /*
   * Decode variable-length (flag, xCoordinate, yCoordinate) triplet for a
   * simple glyph.  See
   *
   *   https://www.w3.org/TR/WOFF2/#triplet_decoding
   */
  static FT_Error
  triplet_decode( const FT_Byte*  flags_in,
                  const FT_Byte*  in,
                  FT_ULong        in_size,
                  FT_ULong        n_points,
                  WOFF2_Point     result,
                  FT_ULong*       in_bytes_used )
  {
    FT_Int  x = 0;
    FT_Int  y = 0;
    FT_Int  dx;
    FT_Int  dy;
    FT_Int  b0, b1, b2;

    FT_ULong  triplet_index = 0;
    FT_ULong  data_bytes;

    FT_UInt  i;


    if ( n_points > in_size )
      return FT_THROW( Invalid_Table );

    for ( i = 0; i < n_points; ++i )
    {
      FT_Byte  flag     = flags_in[i];
      FT_Bool  on_curve = !( flag >> 7 );


      flag &= 0x7f;
      if ( flag < 84 )
        data_bytes = 1;
      else if ( flag < 120 )
        data_bytes = 2;
      else if ( flag < 124 )
        data_bytes = 3;
      else
        data_bytes = 4;

      /* Overflow checks */
      if ( triplet_index + data_bytes > in_size       ||
           triplet_index + data_bytes < triplet_index )
        return FT_THROW( Invalid_Table );

      if ( flag < 10 )
      {
        dx = 0;
        dy = with_sign( flag,
                        ( ( flag & 14 ) << 7 ) + in[triplet_index] );
      }
      else if ( flag < 20 )
      {
        dx = with_sign( flag,
                        ( ( ( flag - 10 ) & 14 ) << 7 ) +
                          in[triplet_index] );
        dy = 0;
      }
      else if ( flag < 84 )
      {
        b0 = flag - 20;
        b1 = in[triplet_index];
        dx = with_sign( flag,
                        1 + ( b0 & 0x30 ) + ( b1 >> 4 ) );
        dy = with_sign( flag >> 1,
                        1 + ( ( b0 & 0x0c ) << 2 ) + ( b1 & 0x0f ) );
      }
      else if ( flag < 120 )
      {
        b0 = flag - 84;
        dx = with_sign( flag,
                        1 + ( ( b0 / 12 ) << 8 ) + in[triplet_index] );
        dy = with_sign( flag >> 1,
                        1 + ( ( ( b0 % 12 ) >> 2 ) << 8 ) +
                          in[triplet_index + 1] );
      }
      else if ( flag < 124 )
      {
        b2 = in[triplet_index + 1];
        dx = with_sign( flag,
                        ( in[triplet_index] << 4 ) + ( b2 >> 4 ) );
        dy = with_sign( flag >> 1,
                        ( ( b2 & 0x0f ) << 8 ) + in[triplet_index + 2] );
      }
      else
      {
        dx = with_sign( flag,
                        ( in[triplet_index] << 8 ) +
                          in[triplet_index + 1] );
        dy = with_sign( flag >> 1,
                        ( in[triplet_index + 2] << 8 ) +
                          in[triplet_index + 3] );
      }

      triplet_index += data_bytes;

      if ( safe_int_addition( x, dx, &x ) )
        return FT_THROW( Invalid_Table );

      if ( safe_int_addition( y, dy, &y ) )
        return FT_THROW( Invalid_Table );

      result[i].x        = x;
      result[i].y        = y;
      result[i].on_curve = on_curve;
    }

    *in_bytes_used = triplet_index;
    return FT_Err_Ok;
  }


  /* Store decoded points in glyph buffer. */
  static FT_Error
  store_points( FT_ULong           n_points,
                const WOFF2_Point  points,
                FT_UShort          n_contours,
                FT_UShort          instruction_len,
                FT_Bool            have_overlap,
                FT_Byte*           dst,
                FT_ULong           dst_size,
                FT_ULong*          glyph_size )
  {
    FT_UInt   flag_offset  = 10 + ( 2 * n_contours ) + 2 + instruction_len;
    FT_Byte   last_flag    = 0xFFU;
    FT_Byte   repeat_count = 0;
    FT_Int    last_x       = 0;
    FT_Int    last_y       = 0;
    FT_UInt   x_bytes      = 0;
    FT_UInt   y_bytes      = 0;
    FT_UInt   xy_bytes;
    FT_UInt   i;
    FT_UInt   x_offset;
    FT_UInt   y_offset;
    FT_Byte*  pointer;


    for ( i = 0; i < n_points; ++i )
    {
      const WOFF2_PointRec  point = points[i];

      FT_Byte  flag = point.on_curve ? GLYF_ON_CURVE : 0;
      FT_Int   dx   = point.x - last_x;
      FT_Int   dy   = point.y - last_y;


      if ( i == 0 && have_overlap )
        flag |= GLYF_OVERLAP_SIMPLE;

      if ( dx == 0 )
        flag |= GLYF_THIS_X_IS_SAME;
      else if ( dx > -256 && dx < 256 )
      {
        flag |= GLYF_X_SHORT | ( dx > 0 ? GLYF_THIS_X_IS_SAME : 0 );
        x_bytes += 1;
      }
      else
        x_bytes += 2;

      if ( dy == 0 )
        flag |= GLYF_THIS_Y_IS_SAME;
      else if ( dy > -256 && dy < 256 )
      {
        flag |= GLYF_Y_SHORT | ( dy > 0 ? GLYF_THIS_Y_IS_SAME : 0 );
        y_bytes += 1;
      }
      else
        y_bytes += 2;

      if ( flag == last_flag && repeat_count != 255 )
      {
        dst[flag_offset - 1] |= GLYF_REPEAT;
        repeat_count++;
      }
      else
      {
        if ( repeat_count != 0 )
        {
          if ( flag_offset >= dst_size )
            return FT_THROW( Invalid_Table );

          dst[flag_offset++] = repeat_count;
        }
        if ( flag_offset >= dst_size )
          return FT_THROW( Invalid_Table );

        dst[flag_offset++] = flag;
        repeat_count       = 0;
      }

      last_x    = point.x;
      last_y    = point.y;
      last_flag = flag;
    }

    if ( repeat_count != 0 )
    {
      if ( flag_offset >= dst_size )
        return FT_THROW( Invalid_Table );

      dst[flag_offset++] = repeat_count;
    }

    xy_bytes = x_bytes + y_bytes;
    if ( xy_bytes < x_bytes                   ||
         flag_offset + xy_bytes < flag_offset ||
         flag_offset + xy_bytes > dst_size    )
      return FT_THROW( Invalid_Table );

    x_offset = flag_offset;
    y_offset = flag_offset + x_bytes;
    last_x = 0;
    last_y = 0;

    for ( i = 0; i < n_points; ++i )
    {
      FT_Int  dx = points[i].x - last_x;
      FT_Int  dy = points[i].y - last_y;


      if ( dx == 0 )
        ;
      else if ( dx > -256 && dx < 256 )
        dst[x_offset++] = (FT_Byte)FT_ABS( dx );
      else
      {
        pointer = dst + x_offset;
        WRITE_SHORT( pointer, dx );
        x_offset += 2;
      }

      last_x += dx;

      if ( dy == 0 )
        ;
      else if ( dy > -256 && dy < 256 )
        dst[y_offset++] = (FT_Byte)FT_ABS( dy );
      else
      {
        pointer = dst + y_offset;
        WRITE_SHORT( pointer, dy );
        y_offset += 2;
      }

      last_y += dy;
    }

    *glyph_size = y_offset;
    return FT_Err_Ok;
  }


  static void
  compute_bbox( FT_ULong           n_points,
                const WOFF2_Point  points,
                FT_Byte*           dst,
                FT_UShort*         src_x_min )
  {
    FT_Int  x_min = 0;
    FT_Int  y_min = 0;
    FT_Int  x_max = 0;
    FT_Int  y_max = 0;

    FT_UInt  i;

    FT_ULong  offset;
    FT_Byte*  pointer;


    if ( n_points > 0 )
    {
      x_min = points[0].x;
      y_min = points[0].y;
      x_max = points[0].x;
      y_max = points[0].y;
    }

    for ( i = 1; i < n_points; ++i )
    {
      FT_Int  x = points[i].x;
      FT_Int  y = points[i].y;


      x_min = FT_MIN( x, x_min );
      y_min = FT_MIN( y, y_min );
      x_max = FT_MAX( x, x_max );
      y_max = FT_MAX( y, y_max );
    }

    /* Write values to `glyf' record. */
    offset  = 2;
    pointer = dst + offset;

    WRITE_SHORT( pointer, x_min );
    WRITE_SHORT( pointer, y_min );
    WRITE_SHORT( pointer, x_max );
    WRITE_SHORT( pointer, y_max );

    *src_x_min = (FT_UShort)x_min;
  }


  static FT_Error
  compositeGlyph_size( FT_Stream  stream,
                       FT_ULong   offset,
                       FT_ULong*  size,
                       FT_Bool*   have_instructions )
  {
    FT_Error   error        = FT_Err_Ok;
    FT_ULong   start_offset = offset;
    FT_Bool    we_have_inst = FALSE;
    FT_UShort  flags        = FLAG_MORE_COMPONENTS;


    if ( FT_STREAM_SEEK( start_offset ) )
      goto Exit;
    while ( flags & FLAG_MORE_COMPONENTS )
    {
      FT_ULong  arg_size;


      if ( FT_READ_USHORT( flags ) )
        goto Exit;
      we_have_inst |= ( flags & FLAG_WE_HAVE_INSTRUCTIONS ) != 0;
      /* glyph index */
      arg_size = 2;
      if ( flags & FLAG_ARG_1_AND_2_ARE_WORDS )
        arg_size += 4;
      else
        arg_size += 2;

      if ( flags & FLAG_WE_HAVE_A_SCALE )
        arg_size += 2;
      else if ( flags & FLAG_WE_HAVE_AN_X_AND_Y_SCALE )
        arg_size += 4;
      else if ( flags & FLAG_WE_HAVE_A_TWO_BY_TWO )
        arg_size += 8;

      if ( FT_STREAM_SKIP( arg_size ) )
        goto Exit;
    }

    *size              = FT_STREAM_POS() - start_offset;
    *have_instructions = we_have_inst;

  Exit:
    return error;
  }


  /* Store loca values (provided by `reconstruct_glyf') to output stream. */
  static FT_Error
  store_loca( FT_ULong*  loca_values,
              FT_ULong   loca_values_size,
              FT_UShort  index_format,
              FT_ULong*  checksum,
              FT_Byte**  sfnt_bytes,
              FT_ULong*  sfnt_size,
              FT_ULong*  out_offset,
              FT_Memory  memory )
  {
    FT_Error  error       = FT_Err_Ok;
    FT_Byte*  sfnt        = *sfnt_bytes;
    FT_ULong  dest_offset = *out_offset;

    FT_Byte*  loca_buf = NULL;
    FT_Byte*  dst      = NULL;

    FT_UInt   i = 0;
    FT_ULong  loca_buf_size;

    const FT_ULong  offset_size = index_format ? 4 : 2;


    if ( ( loca_values_size << 2 ) >> 2 != loca_values_size )
      goto Fail;

    loca_buf_size = loca_values_size * offset_size;
    if ( FT_QALLOC( loca_buf, loca_buf_size ) )
      goto Fail;

    dst = loca_buf;
    for ( i = 0; i < loca_values_size; i++ )
    {
      FT_ULong  value = loca_values[i];


      if ( index_format )
        WRITE_ULONG( dst, value );
      else
        WRITE_USHORT( dst, ( value >> 1 ) );
    }

    *checksum = compute_ULong_sum( loca_buf, loca_buf_size );
    /* Write `loca' table to sfnt buffer. */
    if ( WRITE_SFNT_BUF( loca_buf, loca_buf_size ) )
      goto Fail;

    /* Set pointer `sfnt_bytes' to its correct value. */
    *sfnt_bytes = sfnt;
    *out_offset = dest_offset;

    FT_FREE( loca_buf );
    return error;

  Fail:
    if ( !error )
      error = FT_THROW( Invalid_Table );

    FT_FREE( loca_buf );

    return error;
  }


  static FT_Error
  reconstruct_glyf( FT_Stream    stream,
                    FT_ULong*    glyf_checksum,
                    FT_ULong*    loca_checksum,
                    FT_Byte**    sfnt_bytes,
                    FT_ULong*    sfnt_size,
                    FT_ULong*    out_offset,
                    WOFF2_Info   info,
                    FT_Memory    memory )
  {
    FT_Error  error = FT_Err_Ok;
    FT_Byte*  sfnt  = *sfnt_bytes;

    /* current position in stream */
    const FT_ULong  pos = FT_STREAM_POS();

    FT_UInt  num_substreams = 7;

    FT_UShort  option_flags;
    FT_UShort  num_glyphs;
    FT_UShort  index_format;
    FT_ULong   expected_loca_length;
    FT_UInt    offset;
    FT_UInt    i;
    FT_ULong   points_size;
    FT_ULong   glyph_buf_size;
    FT_ULong   bbox_bitmap_offset;
    FT_ULong   bbox_bitmap_length;
    FT_ULong   overlap_bitmap_offset = 0;
    FT_ULong   overlap_bitmap_length = 0;

    const FT_ULong  glyf_start  = *out_offset;
    FT_ULong        dest_offset = *out_offset;

    WOFF2_Substream  substreams = NULL;

    FT_ULong*    loca_values  = NULL;
    FT_UShort*   n_points_arr = NULL;
    FT_Byte*     glyph_buf    = NULL;
    WOFF2_Point  points       = NULL;


    if ( FT_QNEW_ARRAY( substreams, num_substreams ) )
      goto Fail;

    if ( FT_STREAM_SKIP( 2 ) )
      goto Fail;
    if ( FT_READ_USHORT( option_flags ) )
      goto Fail;
    if ( FT_READ_USHORT( num_glyphs ) )
      goto Fail;
    if ( FT_READ_USHORT( index_format ) )
      goto Fail;

    FT_TRACE4(( "option_flags = %u; num_glyphs = %u; index_format = %u\n",
                option_flags, num_glyphs, index_format ));

    info->num_glyphs = num_glyphs;

    /* Calculate expected length of loca and compare.          */
    /* See https://www.w3.org/TR/WOFF2/#conform-mustRejectLoca */
    /* index_format = 0 => Short version `loca'.               */
    /* index_format = 1 => Long version `loca'.                */
    expected_loca_length = ( index_format ? 4 : 2 ) *
                             ( (FT_ULong)num_glyphs + 1 );
    if ( info->loca_table->dst_length != expected_loca_length )
      goto Fail;

    offset = 2 + 2 + 2 + 2 + ( num_substreams * 4 );
    if ( offset > info->glyf_table->TransformLength )
      goto Fail;

    for ( i = 0; i < num_substreams; ++i )
    {
      FT_ULong  substream_size;


      if ( FT_READ_ULONG( substream_size ) )
        goto Fail;
      if ( substream_size > info->glyf_table->TransformLength - offset )
        goto Fail;

      substreams[i].start  = pos + offset;
      substreams[i].offset = pos + offset;
      substreams[i].size   = substream_size;

      FT_TRACE5(( "  Substream %d: offset = %lu; size = %lu;\n",
                  i, substreams[i].offset, substreams[i].size ));
      offset += substream_size;
    }

    if ( option_flags & HAVE_OVERLAP_SIMPLE_BITMAP )
    {
      /* Size of overlapBitmap = floor((numGlyphs + 7) / 8) */
      overlap_bitmap_length = ( num_glyphs + 7U ) >> 3;
      if ( overlap_bitmap_length > info->glyf_table->TransformLength - offset )
        goto Fail;

      overlap_bitmap_offset = pos + offset;

      FT_TRACE5(( "  Overlap bitmap: offset = %lu; size = %lu;\n",
                  overlap_bitmap_offset, overlap_bitmap_length ));
      offset += overlap_bitmap_length;
    }

    if ( FT_QNEW_ARRAY( loca_values, num_glyphs + 1 ) )
      goto Fail;

    points_size        = 0;
    bbox_bitmap_offset = substreams[BBOX_STREAM].offset;

    /* Size of bboxBitmap = 4 * floor((numGlyphs + 31) / 32) */
    bbox_bitmap_length              = ( ( num_glyphs + 31U ) >> 5 ) << 2;
    /* bboxStreamSize is the combined size of bboxBitmap and bboxStream. */
    substreams[BBOX_STREAM].offset += bbox_bitmap_length;

    glyph_buf_size = WOFF2_DEFAULT_GLYPH_BUF;
    if ( FT_QALLOC( glyph_buf, glyph_buf_size ) )
      goto Fail;

    if ( FT_QNEW_ARRAY( info->x_mins, num_glyphs ) )
      goto Fail;

    for ( i = 0; i < num_glyphs; ++i )
    {
      FT_ULong   glyph_size = 0;
      FT_UShort  n_contours = 0;
      FT_Bool    have_bbox  = FALSE;
      FT_Byte    bbox_bitmap;
      FT_ULong   bbox_offset;
      FT_UShort  x_min      = 0;


      /* Set `have_bbox'. */
      bbox_offset = bbox_bitmap_offset + ( i >> 3 );
      if ( FT_STREAM_SEEK( bbox_offset ) ||
           FT_READ_BYTE( bbox_bitmap )   )
        goto Fail;
      if ( bbox_bitmap & ( 0x80 >> ( i & 7 ) ) )
        have_bbox = TRUE;

      /* Read value from `nContourStream'. */
      if ( FT_STREAM_SEEK( substreams[N_CONTOUR_STREAM].offset ) ||
           FT_READ_USHORT( n_contours )                          )
        goto Fail;
      substreams[N_CONTOUR_STREAM].offset += 2;

      if ( n_contours == 0xffff )
      {
        /* composite glyph */
        FT_Bool    have_instructions = FALSE;
        FT_UShort  instruction_size  = 0;
        FT_ULong   composite_size    = 0;
        FT_ULong   size_needed;
        FT_Byte*   pointer           = NULL;


        /* Composite glyphs must have explicit bbox. */
        if ( !have_bbox )
          goto Fail;

        if ( compositeGlyph_size( stream,
                                  substreams[COMPOSITE_STREAM].offset,
                                  &composite_size,
                                  &have_instructions) )
          goto Fail;

        if ( have_instructions )
        {
          if ( FT_STREAM_SEEK( substreams[GLYPH_STREAM].offset ) ||
               READ_255USHORT( instruction_size )                )
            goto Fail;
          substreams[GLYPH_STREAM].offset = FT_STREAM_POS();
        }

        size_needed = 12 + composite_size + instruction_size;
        if ( glyph_buf_size < size_needed )
        {
          if ( FT_QREALLOC( glyph_buf, glyph_buf_size, size_needed ) )
            goto Fail;
          glyph_buf_size = size_needed;
        }

        pointer = glyph_buf + glyph_size;
        WRITE_USHORT( pointer, n_contours );
        glyph_size += 2;

        /* Read x_min for current glyph. */
        if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
             FT_READ_USHORT( x_min )                          )
          goto Fail;
        /* No increment here because we read again. */

        if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
             FT_STREAM_READ( glyph_buf + glyph_size, 8 )      )
          goto Fail;

        substreams[BBOX_STREAM].offset += 8;
        glyph_size                     += 8;

        if ( FT_STREAM_SEEK( substreams[COMPOSITE_STREAM].offset )    ||
             FT_STREAM_READ( glyph_buf + glyph_size, composite_size ) )
          goto Fail;

        substreams[COMPOSITE_STREAM].offset += composite_size;
        glyph_size                          += composite_size;

        if ( have_instructions )
        {
          pointer = glyph_buf + glyph_size;
          WRITE_USHORT( pointer, instruction_size );
          glyph_size += 2;

          if ( FT_STREAM_SEEK( substreams[INSTRUCTION_STREAM].offset )    ||
               FT_STREAM_READ( glyph_buf + glyph_size, instruction_size ) )
            goto Fail;

          substreams[INSTRUCTION_STREAM].offset += instruction_size;
          glyph_size                            += instruction_size;
        }
      }
      else if ( n_contours > 0 )
      {
        /* simple glyph */
        FT_ULong   total_n_points = 0;
        FT_UShort  n_points_contour;
        FT_UInt    j;
        FT_ULong   flag_size;
        FT_ULong   triplet_size;
        FT_ULong   triplet_bytes_used;
        FT_Bool    have_overlap  = FALSE;
        FT_Byte    overlap_bitmap;
        FT_ULong   overlap_offset;
        FT_Byte*   flags_buf     = NULL;
        FT_Byte*   triplet_buf   = NULL;
        FT_UShort  instruction_size;
        FT_ULong   size_needed;
        FT_Int     end_point;
        FT_UInt    contour_ix;

        FT_Byte*   pointer = NULL;


        /* Set `have_overlap`. */
        if ( overlap_bitmap_offset )
        {
          overlap_offset = overlap_bitmap_offset + ( i >> 3 );
          if ( FT_STREAM_SEEK( overlap_offset ) ||
               FT_READ_BYTE( overlap_bitmap )   )
            goto Fail;
          if ( overlap_bitmap & ( 0x80 >> ( i & 7 ) ) )
            have_overlap = TRUE;
        }

        if ( FT_QNEW_ARRAY( n_points_arr, n_contours ) )
          goto Fail;

        if ( FT_STREAM_SEEK( substreams[N_POINTS_STREAM].offset ) )
          goto Fail;

        for ( j = 0; j < n_contours; ++j )
        {
          if ( READ_255USHORT( n_points_contour ) )
            goto Fail;
          n_points_arr[j] = n_points_contour;
          /* Prevent negative/overflow. */
          if ( total_n_points + n_points_contour < total_n_points )
            goto Fail;
          total_n_points += n_points_contour;
        }
        substreams[N_POINTS_STREAM].offset = FT_STREAM_POS();

        flag_size = total_n_points;
        if ( flag_size > substreams[FLAG_STREAM].size )
          goto Fail;

        flags_buf   = stream->base + substreams[FLAG_STREAM].offset;
        triplet_buf = stream->base + substreams[GLYPH_STREAM].offset;

        if ( substreams[GLYPH_STREAM].size <
               ( substreams[GLYPH_STREAM].offset -
                 substreams[GLYPH_STREAM].start ) )
          goto Fail;

        triplet_size       = substreams[GLYPH_STREAM].size -
                               ( substreams[GLYPH_STREAM].offset -
                                 substreams[GLYPH_STREAM].start );
        triplet_bytes_used = 0;

        /* Create array to store point information. */
        points_size = total_n_points;
        if ( FT_QNEW_ARRAY( points, points_size ) )
          goto Fail;

        if ( triplet_decode( flags_buf,
                             triplet_buf,
                             triplet_size,
                             total_n_points,
                             points,
                             &triplet_bytes_used ) )
          goto Fail;

        substreams[FLAG_STREAM].offset  += flag_size;
        substreams[GLYPH_STREAM].offset += triplet_bytes_used;

        if ( FT_STREAM_SEEK( substreams[GLYPH_STREAM].offset ) ||
             READ_255USHORT( instruction_size )                )
          goto Fail;

        substreams[GLYPH_STREAM].offset = FT_STREAM_POS();

        if ( total_n_points >= ( 1 << 27 ) )
          goto Fail;

        size_needed = 12 +
                      ( 2 * n_contours ) +
                      ( 5 * total_n_points ) +
                      instruction_size;
        if ( glyph_buf_size < size_needed )
        {
          if ( FT_QREALLOC( glyph_buf, glyph_buf_size, size_needed ) )
            goto Fail;
          glyph_buf_size = size_needed;
        }

        pointer = glyph_buf + glyph_size;
        WRITE_USHORT( pointer, n_contours );
        glyph_size += 2;

        if ( have_bbox )
        {
          /* Read x_min for current glyph. */
          if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
               FT_READ_USHORT( x_min )                          )
            goto Fail;
          /* No increment here because we read again. */

          if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
               FT_STREAM_READ( glyph_buf + glyph_size, 8 )      )
            goto Fail;
          substreams[BBOX_STREAM].offset += 8;
        }
        else
          compute_bbox( total_n_points, points, glyph_buf, &x_min );

        glyph_size = CONTOUR_OFFSET_END_POINT;

        pointer   = glyph_buf + glyph_size;
        end_point = -1;

        for ( contour_ix = 0; contour_ix < n_contours; ++contour_ix )
        {
          end_point += n_points_arr[contour_ix];
          if ( end_point >= 65536 )
            goto Fail;

          WRITE_SHORT( pointer, end_point );
          glyph_size += 2;
        }

        WRITE_USHORT( pointer, instruction_size );
        glyph_size += 2;

        if ( FT_STREAM_SEEK( substreams[INSTRUCTION_STREAM].offset )    ||
             FT_STREAM_READ( glyph_buf + glyph_size, instruction_size ) )
          goto Fail;

        substreams[INSTRUCTION_STREAM].offset += instruction_size;
        glyph_size                            += instruction_size;

        if ( store_points( total_n_points,
                           points,
                           n_contours,
                           instruction_size,
                           have_overlap,
                           glyph_buf,
                           glyph_buf_size,
                           &glyph_size ) )
          goto Fail;

        FT_FREE( points );
        FT_FREE( n_points_arr );
      }
      else
      {
        /* Empty glyph.          */
        /* Must not have a bbox. */
        if ( have_bbox )
        {
          FT_ERROR(( "Empty glyph has a bbox.\n" ));
          goto Fail;
        }
      }

      loca_values[i] = dest_offset - glyf_start;

      if ( WRITE_SFNT_BUF( glyph_buf, glyph_size ) )
        goto Fail;

      if ( pad4( &sfnt, sfnt_size, &dest_offset, memory ) )
        goto Fail;

      *glyf_checksum += compute_ULong_sum( glyph_buf, glyph_size );

      /* Store x_mins, may be required to reconstruct `hmtx'. */
      info->x_mins[i] = (FT_Short)x_min;
    }

    info->glyf_table->dst_length = dest_offset - info->glyf_table->dst_offset;
    info->loca_table->dst_offset = dest_offset;

    /* `loca[n]' will be equal to the length of the `glyf' table. */
    loca_values[num_glyphs] = info->glyf_table->dst_length;

    if ( store_loca( loca_values,
                     num_glyphs + 1,
                     index_format,
                     loca_checksum,
                     &sfnt,
                     sfnt_size,
                     &dest_offset,
                     memory ) )
      goto Fail;

    info->loca_table->dst_length = dest_offset - info->loca_table->dst_offset;

    FT_TRACE4(( "  loca table info:\n" ));
    FT_TRACE4(( "    dst_offset = %lu\n", info->loca_table->dst_offset ));
    FT_TRACE4(( "    dst_length = %lu\n", info->loca_table->dst_length ));
    FT_TRACE4(( "    checksum = %09lx\n", *loca_checksum ));

    /* Set pointer `sfnt_bytes' to its correct value. */
    *sfnt_bytes = sfnt;
    *out_offset = dest_offset;

    FT_FREE( substreams );
    FT_FREE( loca_values );
    FT_FREE( n_points_arr );
    FT_FREE( glyph_buf );
    FT_FREE( points );

    return error;

  Fail:
    if ( !error )
      error = FT_THROW( Invalid_Table );

    /* Set pointer `sfnt_bytes' to its correct value. */
    *sfnt_bytes = sfnt;

    FT_FREE( substreams );
    FT_FREE( loca_values );
    FT_FREE( n_points_arr );
    FT_FREE( glyph_buf );
    FT_FREE( points );

    return error;
  }


  /* Get `x_mins' for untransformed `glyf' table. */
  static FT_Error
  get_x_mins( FT_Stream     stream,
              WOFF2_Table*  tables,
              FT_UShort     num_tables,
              WOFF2_Info    info,
              FT_Memory     memory )
  {
    FT_UShort  num_glyphs;
    FT_UShort  index_format;
    FT_ULong   glyf_offset;
    FT_UShort  glyf_offset_short;
    FT_ULong   loca_offset;
    FT_Int     i;
    FT_Error   error = FT_Err_Ok;
    FT_ULong   offset_size;

    /* At this point of time those tables might not have been read yet. */
    const WOFF2_Table  maxp_table = find_table( tables, num_tables,
                                                TTAG_maxp );
    const WOFF2_Table  head_table = find_table( tables, num_tables,
                                                TTAG_head );


    if ( !maxp_table )
    {
      FT_ERROR(( "`maxp' table is missing.\n" ));
      return FT_THROW( Invalid_Table );
    }

    if ( !head_table )
    {
      FT_ERROR(( "`head' table is missing.\n" ));
      return FT_THROW( Invalid_Table );
    }

    if ( !info->loca_table )
    {
      FT_ERROR(( "`loca' table is missing.\n" ));
      return FT_THROW( Invalid_Table );
    }

    /* Read `numGlyphs' field from `maxp' table. */
    if ( FT_STREAM_SEEK( maxp_table->src_offset ) || FT_STREAM_SKIP( 8 ) )
      return error;

    if ( FT_READ_USHORT( num_glyphs ) )
      return error;

    info->num_glyphs = num_glyphs;

    /* Read `indexToLocFormat' field from `head' table. */
    if ( FT_STREAM_SEEK( head_table->src_offset ) ||
         FT_STREAM_SKIP( 50 )                     )
      return error;

    if ( FT_READ_USHORT( index_format ) )
      return error;

    offset_size = index_format ? 4 : 2;

    /* Create `x_mins' array. */
    if ( FT_QNEW_ARRAY( info->x_mins, num_glyphs ) )
      return error;

    loca_offset = info->loca_table->src_offset;

    for ( i = 0; i < num_glyphs; ++i )
    {
      if ( FT_STREAM_SEEK( loca_offset ) )
        return error;

      loca_offset += offset_size;

      if ( index_format )
      {
        if ( FT_READ_ULONG( glyf_offset ) )
          return error;
      }
      else
      {
        if ( FT_READ_USHORT( glyf_offset_short ) )
          return error;

        glyf_offset = (FT_ULong)( glyf_offset_short );
        glyf_offset = glyf_offset << 1;
      }

      glyf_offset += info->glyf_table->src_offset;

      if ( FT_STREAM_SEEK( glyf_offset ) || FT_STREAM_SKIP( 2 ) )
        return error;

      if ( FT_READ_SHORT( info->x_mins[i] ) )
        return error;
    }

    return error;
  }


  static FT_Error
  reconstruct_hmtx( FT_Stream  stream,
                    FT_UShort  num_glyphs,
                    FT_UShort  num_hmetrics,
                    FT_Short*  x_mins,
                    FT_ULong*  checksum,
                    FT_Byte**  sfnt_bytes,
                    FT_ULong*  sfnt_size,
                    FT_ULong*  out_offset,
                    FT_Memory  memory )
  {
    FT_Error  error       = FT_Err_Ok;
    FT_Byte*  sfnt        = *sfnt_bytes;
    FT_ULong  dest_offset = *out_offset;

    FT_Byte   hmtx_flags;
    FT_Bool   has_proportional_lsbs, has_monospace_lsbs;
    FT_ULong  hmtx_table_size;
    FT_Int    i;

    FT_UShort*  advance_widths = NULL;
    FT_Short*   lsbs           = NULL;
    FT_Byte*    hmtx_table     = NULL;
    FT_Byte*    dst            = NULL;


    if ( FT_READ_BYTE( hmtx_flags ) )
      goto Fail;

    has_proportional_lsbs = ( hmtx_flags & 1 ) == 0;
    has_monospace_lsbs    = ( hmtx_flags & 2 ) == 0;

    /* Bits 2-7 are reserved and MUST be zero. */
    if ( ( hmtx_flags & 0xFC ) != 0 )
      goto Fail;

    /* Are you REALLY transformed? */
    if ( has_proportional_lsbs && has_monospace_lsbs )
      goto Fail;

    /* Cannot have a transformed `hmtx' without `glyf'. */
    if ( ( num_hmetrics > num_glyphs ) ||
         ( num_hmetrics < 1 )          )
      goto Fail;

    /* Must have at least one entry. */
    if ( num_hmetrics < 1 )
      goto Fail;

    if ( FT_QNEW_ARRAY( advance_widths, num_hmetrics ) ||
         FT_QNEW_ARRAY( lsbs, num_glyphs )             )
      goto Fail;

    /* Read `advanceWidth' stream.  Always present. */
    for ( i = 0; i < num_hmetrics; i++ )
    {
      FT_UShort  advance_width;


      if ( FT_READ_USHORT( advance_width ) )
        goto Fail;

      advance_widths[i] = advance_width;
    }

    /* lsb values for proportional glyphs. */
    for ( i = 0; i < num_hmetrics; i++ )
    {
      FT_Short  lsb;


      if ( has_proportional_lsbs )
      {
        if ( FT_READ_SHORT( lsb ) )
          goto Fail;
      }
      else
        lsb = x_mins[i];

      lsbs[i] = lsb;
    }

    /* lsb values for monospaced glyphs. */
    for ( i = num_hmetrics; i < num_glyphs; i++ )
    {
      FT_Short  lsb;


      if ( has_monospace_lsbs )
      {
        if ( FT_READ_SHORT( lsb ) )
          goto Fail;
      }
      else
        lsb = x_mins[i];

      lsbs[i] = lsb;
    }

    /* Build the hmtx table. */
    hmtx_table_size = 2 * num_hmetrics + 2 * num_glyphs;
    if ( FT_QALLOC( hmtx_table, hmtx_table_size ) )
      goto Fail;

    dst = hmtx_table;
    FT_TRACE6(( "hmtx values: \n" ));
    for ( i = 0; i < num_glyphs; i++ )
    {
      if ( i < num_hmetrics )
      {
        WRITE_SHORT( dst, advance_widths[i] );
        FT_TRACE6(( "%d ", advance_widths[i] ));
      }

      WRITE_SHORT( dst, lsbs[i] );
      FT_TRACE6(( "%d ", lsbs[i] ));
    }
    FT_TRACE6(( "\n" ));

    *checksum = compute_ULong_sum( hmtx_table, hmtx_table_size );
    /* Write `hmtx' table to sfnt buffer. */
    if ( WRITE_SFNT_BUF( hmtx_table, hmtx_table_size ) )
      goto Fail;

    /* Set pointer `sfnt_bytes' to its correct value. */
    *sfnt_bytes = sfnt;
    *out_offset = dest_offset;

    FT_FREE( advance_widths );
    FT_FREE( lsbs );
    FT_FREE( hmtx_table );

    return error;

  Fail:
    FT_FREE( advance_widths );
    FT_FREE( lsbs );
    FT_FREE( hmtx_table );

    if ( !error )
      error = FT_THROW( Invalid_Table );

    return error;
  }


  static FT_Error
  reconstruct_font( FT_Byte*      transformed_buf,
                    FT_ULong      transformed_buf_size,
                    WOFF2_Table*  indices,
                    WOFF2_Header  woff2,
                    WOFF2_Info    info,
                    FT_Byte**     sfnt_bytes,
                    FT_ULong*     sfnt_size,
                    FT_Memory     memory )
  {
    /* Memory management of `transformed_buf' is handled by the caller. */

    FT_Error   error      = FT_Err_Ok;
    FT_Stream  stream     = NULL;
    FT_Byte*   buf_cursor = NULL;
    FT_Byte    table_entry[16];

    /* We are reallocating memory for `sfnt', so its pointer may change. */
    FT_Byte*   sfnt = *sfnt_bytes;

    FT_UShort  num_tables  = woff2->num_tables;
    FT_ULong   dest_offset = 12 + num_tables * 16UL;

    FT_ULong   checksum      = 0;
    FT_ULong   loca_checksum = 0;
    FT_Int     nn            = 0;
    FT_UShort  num_hmetrics  = 0;
    FT_ULong   font_checksum = info->header_checksum;
    FT_Bool    is_glyf_xform = FALSE;

    FT_ULong  table_entry_offset = 12;


    /* A few table checks before reconstruction. */
    /* `glyf' must be present with `loca'.       */
    info->glyf_table = find_table( indices, num_tables, TTAG_glyf );
    info->loca_table = find_table( indices, num_tables, TTAG_loca );

    if ( ( info->glyf_table == NULL ) ^ ( info->loca_table == NULL ) )
    {
      FT_ERROR(( "One of `glyf'/`loca' tables missing.\n" ));
      return FT_THROW( Invalid_Table );
    }

    /* Both `glyf' and `loca' must have same transformation. */
    if ( info->glyf_table != NULL )
    {
      if ( ( info->glyf_table->flags & WOFF2_FLAGS_TRANSFORM ) !=
           ( info->loca_table->flags & WOFF2_FLAGS_TRANSFORM ) )
      {
        FT_ERROR(( "Transformation mismatch"
                   " between `glyf' and `loca' table." ));
        return FT_THROW( Invalid_Table );
      }
    }

    /* Create a stream for the uncompressed buffer. */
    if ( FT_NEW( stream ) )
      goto Fail;
    FT_Stream_OpenMemory( stream, transformed_buf, transformed_buf_size );

    FT_ASSERT( FT_STREAM_POS() == 0 );

    /* Reconstruct/copy tables to output stream. */
    for ( nn = 0; nn < num_tables; nn++ )
    {
      WOFF2_TableRec  table = *( indices[nn] );


      FT_TRACE3(( "Seeking to %ld with table size %ld.\n",
                  table.src_offset, table.src_length ));
      FT_TRACE3(( "Table tag: %c%c%c%c.\n",
                  (FT_Char)( table.Tag >> 24 ),
                  (FT_Char)( table.Tag >> 16 ),
                  (FT_Char)( table.Tag >> 8  ),
                  (FT_Char)( table.Tag       ) ));

      if ( FT_STREAM_SEEK( table.src_offset ) )
        goto Fail;

      if ( table.src_offset + table.src_length > transformed_buf_size )
        goto Fail;

      /* Get stream size for fields of `hmtx' table. */
      if ( table.Tag == TTAG_hhea )
      {
        if ( read_num_hmetrics( stream, &num_hmetrics ) )
          goto Fail;
      }

      info->num_hmetrics = num_hmetrics;

      checksum = 0;
      if ( ( table.flags & WOFF2_FLAGS_TRANSFORM ) != WOFF2_FLAGS_TRANSFORM )
      {
        /* Check whether `head' is at least 12 bytes. */
        if ( table.Tag == TTAG_head )
        {
          if ( table.src_length < 12 )
            goto Fail;

          buf_cursor = transformed_buf + table.src_offset + 8;
          /* Set checkSumAdjustment = 0 */
          WRITE_ULONG( buf_cursor, 0 );
        }

        table.dst_offset = dest_offset;

        checksum = compute_ULong_sum( transformed_buf + table.src_offset,
                                      table.src_length );
        FT_TRACE4(( "Checksum = %09lx.\n", checksum ));

        if ( WRITE_SFNT_BUF( transformed_buf + table.src_offset,
                             table.src_length ) )
          goto Fail;
      }
      else
      {
        FT_TRACE3(( "This table is transformed.\n" ));

        if ( table.Tag == TTAG_glyf )
        {
          is_glyf_xform    = TRUE;
          table.dst_offset = dest_offset;

          if ( reconstruct_glyf( stream,
                                 &checksum,
                                 &loca_checksum,
                                 &sfnt,
                                 sfnt_size,
                                 &dest_offset,
                                 info,
                                 memory ) )
            goto Fail;

          FT_TRACE4(( "Checksum = %09lx.\n", checksum ));
        }

        else if ( table.Tag == TTAG_loca )
          checksum = loca_checksum;

        else if ( table.Tag == TTAG_hmtx )
        {
          /* If glyf is not transformed and hmtx is, handle separately. */
          if ( !is_glyf_xform )
          {
            if ( get_x_mins( stream, indices, num_tables, info, memory ) )
              goto Fail;
          }

          table.dst_offset = dest_offset;

          if ( reconstruct_hmtx( stream,
                                 info->num_glyphs,
                                 info->num_hmetrics,
                                 info->x_mins,
                                 &checksum,
                                 &sfnt,
                                 sfnt_size,
                                 &dest_offset,
                                 memory ) )
            goto Fail;
        }
        else
        {
          /* Unknown transform. */
          FT_ERROR(( "Unknown table transform.\n" ));
          goto Fail;
        }
      }

      font_checksum += checksum;

      buf_cursor = &table_entry[0];
      WRITE_ULONG( buf_cursor, table.Tag );
      WRITE_ULONG( buf_cursor, checksum );
      WRITE_ULONG( buf_cursor, table.dst_offset );
      WRITE_ULONG( buf_cursor, table.dst_length );

      WRITE_SFNT_BUF_AT( table_entry_offset, table_entry, 16 );

      /* Update checksum. */
      font_checksum += compute_ULong_sum( table_entry, 16 );

      if ( pad4( &sfnt, sfnt_size, &dest_offset, memory ) )
        goto Fail;

      /* Sanity check. */
      if ( (FT_ULong)( table.dst_offset + table.dst_length ) > dest_offset )
      {
        FT_ERROR(( "Table was partially written.\n" ));
        goto Fail;
      }
    }

    /* Update `head' checkSumAdjustment. */
    info->head_table = find_table( indices, num_tables, TTAG_head );
    if ( !info->head_table )
    {
      FT_ERROR(( "`head' table is missing.\n" ));
      goto Fail;
    }

    if ( info->head_table->dst_length < 12 )
      goto Fail;

    buf_cursor    = sfnt + info->head_table->dst_offset + 8;
    font_checksum = 0xB1B0AFBA - font_checksum;

    WRITE_ULONG( buf_cursor, font_checksum );

    FT_TRACE2(( "Final checksum = %09lx.\n", font_checksum ));

    woff2->actual_sfnt_size = dest_offset;

    /* Set pointer of sfnt stream to its correct value. */
    *sfnt_bytes = sfnt;

    FT_Stream_Close( stream );
    FT_FREE( stream );

    return error;

  Fail:
    if ( !error )
      error = FT_THROW( Invalid_Table );

    /* Set pointer of sfnt stream to its correct value. */
    *sfnt_bytes = sfnt;

    FT_Stream_Close( stream );
    FT_FREE( stream );

    return error;
  }


  /* Replace `face->root.stream' with a stream containing the extracted */
  /* SFNT of a WOFF2 font.                                              */

  FT_LOCAL_DEF( FT_Error )
  woff2_open_font( FT_Stream  stream,
                   TT_Face    face,
                   FT_Int*    face_instance_index,
                   FT_Long*   num_faces )
  {
    FT_Memory  memory = stream->memory;
    FT_Error   error  = FT_Err_Ok;
    FT_Int     face_index;

    WOFF2_HeaderRec  woff2;
    WOFF2_InfoRec    info         = { 0, 0, 0, NULL, NULL, NULL, NULL };
    WOFF2_Table      tables       = NULL;
    WOFF2_Table*     indices      = NULL;
    WOFF2_Table*     temp_indices = NULL;
    WOFF2_Table      last_table;

    FT_Int     nn;
    FT_ULong   j;
    FT_ULong   flags;
    FT_UShort  xform_version;
    FT_ULong   src_offset = 0;

    FT_UInt    glyf_index;
    FT_UInt    loca_index;
    FT_UInt32  file_offset;

    FT_Byte*   sfnt        = NULL;
    FT_Stream  sfnt_stream = NULL;
    FT_Byte*   sfnt_header;
    FT_ULong   sfnt_size;

    FT_Byte*  uncompressed_buf = NULL;

    static const FT_Frame_Field  woff2_header_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  WOFF2_HeaderRec

      FT_FRAME_START( 48 ),
        FT_FRAME_ULONG     ( signature ),
        FT_FRAME_ULONG     ( flavor ),
        FT_FRAME_ULONG     ( length ),
        FT_FRAME_USHORT    ( num_tables ),
        FT_FRAME_SKIP_BYTES( 2 ),
        FT_FRAME_ULONG     ( totalSfntSize ),
        FT_FRAME_ULONG     ( totalCompressedSize ),
        FT_FRAME_SKIP_BYTES( 2 * 2 ),
        FT_FRAME_ULONG     ( metaOffset ),
        FT_FRAME_ULONG     ( metaLength ),
        FT_FRAME_ULONG     ( metaOrigLength ),
        FT_FRAME_ULONG     ( privOffset ),
        FT_FRAME_ULONG     ( privLength ),
      FT_FRAME_END
    };


    FT_ASSERT( stream == face->root.stream );
    FT_ASSERT( FT_STREAM_POS() == 0 );

    face_index = FT_ABS( *face_instance_index ) & 0xFFFF;

    /* Read WOFF2 Header. */
    if ( FT_STREAM_READ_FIELDS( woff2_header_fields, &woff2 ) )
      return error;

    FT_TRACE4(( "signature     -> 0x%lX\n", woff2.signature ));
    FT_TRACE2(( "flavor        -> 0x%08lx\n", woff2.flavor ));
    FT_TRACE4(( "length        -> %lu\n", woff2.length ));
    FT_TRACE2(( "num_tables    -> %hu\n", woff2.num_tables ));
    FT_TRACE4(( "totalSfntSize -> %lu\n", woff2.totalSfntSize ));
    FT_TRACE4(( "metaOffset    -> %lu\n", woff2.metaOffset ));
    FT_TRACE4(( "metaLength    -> %lu\n", woff2.metaLength ));
    FT_TRACE4(( "privOffset    -> %lu\n", woff2.privOffset ));
    FT_TRACE4(( "privLength    -> %lu\n", woff2.privLength ));

    /* Make sure we don't recurse back here. */
    if ( woff2.flavor == TTAG_wOF2 )
      return FT_THROW( Invalid_Table );

    /* Miscellaneous checks. */
    if ( woff2.length != stream->size                               ||
         woff2.num_tables == 0                                      ||
         48 + woff2.num_tables * 20UL >= woff2.length               ||
         ( woff2.metaOffset == 0 && ( woff2.metaLength != 0     ||
                                      woff2.metaOrigLength != 0 ) ) ||
         ( woff2.metaLength != 0 && woff2.metaOrigLength == 0 )     ||
         ( woff2.metaOffset >= woff2.length )                       ||
         ( woff2.length - woff2.metaOffset < woff2.metaLength )     ||
         ( woff2.privOffset == 0 && woff2.privLength != 0 )         ||
         ( woff2.privOffset >= woff2.length )                       ||
         ( woff2.length - woff2.privOffset < woff2.privLength )     )
    {
      FT_ERROR(( "woff2_open_font: invalid WOFF2 header\n" ));
      return FT_THROW( Invalid_Table );
    }

    FT_TRACE2(( "woff2_open_font: WOFF2 Header is valid.\n" ));

    woff2.ttc_fonts = NULL;

    /* Read table directory. */
    if ( FT_QNEW_ARRAY( tables, woff2.num_tables )  ||
         FT_QNEW_ARRAY( indices, woff2.num_tables ) )
      goto Exit;

    FT_TRACE2(( "\n" ));
    FT_TRACE2(( "  tag    flags    transform  origLen   transformLen   offset\n" ));
    FT_TRACE2(( "  -----------------------------------------------------------\n" ));
             /* "  XXXX  XXXXXXXX  XXXXXXXX   XXXXXXXX    XXXXXXXX    XXXXXXXX" */

    for ( nn = 0; nn < woff2.num_tables; nn++ )
    {
      WOFF2_Table  table = tables + nn;


      if ( FT_READ_BYTE( table->FlagByte ) )
        goto Exit;

      if ( ( table->FlagByte & 0x3f ) == 0x3f )
      {
        if ( FT_READ_ULONG( table->Tag ) )
          goto Exit;
      }
      else
      {
        table->Tag = woff2_known_tags( table->FlagByte & 0x3f );
        if ( !table->Tag )
        {
          FT_ERROR(( "woff2_open_font: Unknown table tag." ));
          error = FT_THROW( Invalid_Table );
          goto Exit;
        }
      }

      flags = 0;
      xform_version = ( table->FlagByte >> 6 ) & 0x03;

      /* 0 means xform for glyph/loca, non-0 for others. */
      if ( table->Tag == TTAG_glyf || table->Tag == TTAG_loca )
      {
        if ( xform_version == 0 )
          flags |= WOFF2_FLAGS_TRANSFORM;
      }
      else if ( xform_version != 0 )
        flags |= WOFF2_FLAGS_TRANSFORM;

      flags |= xform_version;

      if ( READ_BASE128( table->dst_length ) )
        goto Exit;

      table->TransformLength = table->dst_length;

      if ( ( flags & WOFF2_FLAGS_TRANSFORM ) != 0 )
      {
        if ( READ_BASE128( table->TransformLength ) )
          goto Exit;

        if ( table->Tag == TTAG_loca && table->TransformLength )
        {
          FT_ERROR(( "woff2_open_font: Invalid loca `transformLength'.\n" ));
          error = FT_THROW( Invalid_Table );
          goto Exit;
        }
      }

      if ( src_offset + table->TransformLength < src_offset )
      {
        FT_ERROR(( "woff2_open_font: invalid WOFF2 table directory.\n" ));
        error = FT_THROW( Invalid_Table );
        goto Exit;
      }

      table->flags      = flags;
      table->src_offset = src_offset;
      table->src_length = table->TransformLength;
      src_offset       += table->TransformLength;
      table->dst_offset = 0;

      FT_TRACE2(( "  %c%c%c%c  %08d  %08d   %08ld    %08ld    %08ld\n",
                  (FT_Char)( table->Tag >> 24 ),
                  (FT_Char)( table->Tag >> 16 ),
                  (FT_Char)( table->Tag >> 8  ),
                  (FT_Char)( table->Tag       ),
                  table->FlagByte & 0x3f,
                  ( table->FlagByte >> 6 ) & 0x03,
                  table->dst_length,
                  table->TransformLength,
                  table->src_offset ));

      indices[nn] = table;
    }

    /* End of last table is uncompressed size. */
    last_table = indices[woff2.num_tables - 1];

    woff2.uncompressed_size = last_table->src_offset +
                              last_table->src_length;
    if ( woff2.uncompressed_size < last_table->src_offset )
    {
      error = FT_THROW( Invalid_Table );
      goto Exit;
    }

    FT_TRACE2(( "Table directory parsed.\n" ));

    /* Check for and read collection directory. */
    woff2.num_fonts      = 1;
    woff2.header_version = 0;

    if ( woff2.flavor == TTAG_ttcf )
    {
      FT_TRACE2(( "Font is a TTC, reading collection directory.\n" ));

      if ( FT_READ_ULONG( woff2.header_version ) )
        goto Exit;

      if ( woff2.header_version != 0x00010000 &&
           woff2.header_version != 0x00020000 )
      {
        error = FT_THROW( Invalid_Table );
        goto Exit;
      }

      if ( READ_255USHORT( woff2.num_fonts ) )
        goto Exit;

      if ( !woff2.num_fonts )
      {
        error = FT_THROW( Invalid_Table );
        goto Exit;
      }

      FT_TRACE4(( "Number of fonts in TTC: %d\n", woff2.num_fonts ));

      /* pre-zero pointers within in case of failure */
      if ( FT_NEW_ARRAY( woff2.ttc_fonts, woff2.num_fonts ) )
        goto Exit;

      for ( nn = 0; nn < woff2.num_fonts; nn++ )
      {
        WOFF2_TtcFont  ttc_font = woff2.ttc_fonts + nn;


        if ( READ_255USHORT( ttc_font->num_tables ) )
          goto Exit;
        if ( FT_READ_ULONG( ttc_font->flavor ) )
          goto Exit;

        if ( FT_QNEW_ARRAY( ttc_font->table_indices, ttc_font->num_tables ) )
          goto Exit;

        FT_TRACE5(( "Number of tables in font %d: %d\n",
                    nn, ttc_font->num_tables ));

#ifdef FT_DEBUG_LEVEL_TRACE
        if ( ttc_font->num_tables )
          FT_TRACE6(( "  Indices: " ));
#endif

        glyf_index = 0;
        loca_index = 0;

        for ( j = 0; j < ttc_font->num_tables; j++ )
        {
          FT_UShort    table_index;
          WOFF2_Table  table;


          if ( READ_255USHORT( table_index ) )
            goto Exit;

          FT_TRACE6(( "%hu ", table_index ));
          if ( table_index >= woff2.num_tables )
          {
            FT_ERROR(( "woff2_open_font: invalid table index\n" ));
            error = FT_THROW( Invalid_Table );
            goto Exit;
          }

          ttc_font->table_indices[j] = table_index;

          table = indices[table_index];
          if ( table->Tag == TTAG_loca )
            loca_index = table_index;
          if ( table->Tag == TTAG_glyf )
            glyf_index = table_index;
        }

#ifdef FT_DEBUG_LEVEL_TRACE
        if ( ttc_font->num_tables )
          FT_TRACE6(( "\n" ));
#endif

        /* glyf and loca must be consecutive */
        if ( glyf_index > 0 || loca_index > 0 )
        {
          if ( glyf_index > loca_index      ||
               loca_index - glyf_index != 1 )
          {
            error = FT_THROW( Invalid_Table );
            goto Exit;
          }
        }
      }

      /* Collection directory reading complete. */
      FT_TRACE2(( "WOFF2 collection directory is valid.\n" ));
    }
    else
      woff2.ttc_fonts = NULL;

    woff2.compressed_offset = FT_STREAM_POS();
    file_offset             = ROUND4( woff2.compressed_offset +
                                      woff2.totalCompressedSize );

    /* Some more checks before we start reading the tables. */
    if ( file_offset > woff2.length )
    {
      error = FT_THROW( Invalid_Table );
      goto Exit;
    }

    if ( woff2.metaOffset )
    {
      if ( file_offset != woff2.metaOffset )
      {
        error = FT_THROW( Invalid_Table );
        goto Exit;
      }
      file_offset = ROUND4( woff2.metaOffset + woff2.metaLength );
    }

    if ( woff2.privOffset )
    {
      if ( file_offset != woff2.privOffset )
      {
        error = FT_THROW( Invalid_Table );
        goto Exit;
      }
      file_offset = ROUND4( woff2.privOffset + woff2.privLength );
    }

    if ( file_offset != ( ROUND4( woff2.length ) ) )
    {
      error = FT_THROW( Invalid_Table );
      goto Exit;
    }

    /* Validate requested face index. */
    *num_faces = woff2.num_fonts;
    /* value -(N+1) requests information on index N */
    if ( *face_instance_index < 0 && face_index > 0 )
      face_index--;

    if ( face_index >= woff2.num_fonts )
    {
      if ( *face_instance_index >= 0 )
      {
        error = FT_THROW( Invalid_Argument );
        goto Exit;
      }
      else
        face_index = 0;
    }

    /* Only retain tables of the requested face in a TTC. */
    if ( woff2.header_version )
    {
      WOFF2_TtcFont  ttc_font = woff2.ttc_fonts + face_index;


      /* Create a temporary array. */
      if ( FT_QNEW_ARRAY( temp_indices,
                          ttc_font->num_tables ) )
        goto Exit;

      FT_TRACE4(( "Storing tables for TTC face index %d.\n", face_index ));
      for ( nn = 0; nn < ttc_font->num_tables; nn++ )
        temp_indices[nn] = indices[ttc_font->table_indices[nn]];

      /* Resize array to required size. */
      if ( FT_QRENEW_ARRAY( indices,
                            woff2.num_tables,
                            ttc_font->num_tables ) )
        goto Exit;

      for ( nn = 0; nn < ttc_font->num_tables; nn++ )
        indices[nn] = temp_indices[nn];

      FT_FREE( temp_indices );

      /* Change header values. */
      woff2.flavor     = ttc_font->flavor;
      woff2.num_tables = ttc_font->num_tables;
    }

    /* We need to allocate this much at the minimum. */
    sfnt_size = 12 + woff2.num_tables * 16UL;
    /* This is what we normally expect.                              */
    /* Initially trust `totalSfntSize' and change later as required. */
    if ( woff2.totalSfntSize > sfnt_size )
    {
      /* However, adjust the value to something reasonable. */

      /* Factor 64 is heuristic. */
      if ( ( woff2.totalSfntSize >> 6 ) > woff2.length )
        sfnt_size = woff2.length << 6;
      else
        sfnt_size = woff2.totalSfntSize;

      /* Value 1<<26 = 67108864 is heuristic. */
      if (sfnt_size >= (1 << 26))
        sfnt_size = 1 << 26;

#ifdef FT_DEBUG_LEVEL_TRACE
      if ( sfnt_size != woff2.totalSfntSize )
        FT_TRACE4(( "adjusting estimate of uncompressed font size"
                    " to %lu bytes\n",
                    sfnt_size ));
#endif
    }

    /* Write sfnt header. */
    if ( FT_QALLOC( sfnt, sfnt_size ) ||
         FT_NEW( sfnt_stream )        )
      goto Exit;

    sfnt_header = sfnt;

    WRITE_ULONG( sfnt_header, woff2.flavor );

    if ( woff2.num_tables )
    {
      FT_UInt  searchRange, entrySelector, rangeShift, x;


      x             = woff2.num_tables;
      entrySelector = 0;
      while ( x )
      {
        x            >>= 1;
        entrySelector += 1;
      }
      entrySelector--;

      searchRange = ( 1 << entrySelector ) * 16;
      rangeShift  = ( woff2.num_tables * 16 ) - searchRange;

      WRITE_USHORT( sfnt_header, woff2.num_tables );
      WRITE_USHORT( sfnt_header, searchRange );
      WRITE_USHORT( sfnt_header, entrySelector );
      WRITE_USHORT( sfnt_header, rangeShift );
    }

    info.header_checksum = compute_ULong_sum( sfnt, 12 );

    /* Sort tables by tag. */
    ft_qsort( indices,
              woff2.num_tables,
              sizeof ( WOFF2_Table ),
              compare_tags );

    /* reject fonts that have multiple tables with the same tag */
    for ( nn = 1; nn < woff2.num_tables; nn++ )
    {
      FT_Tag  tag = indices[nn]->Tag;


      if ( tag == indices[nn - 1]->Tag )
      {
        FT_ERROR(( "woff2_open_font:"
                   " multiple tables with tag `%c%c%c%c'.\n",
                   (FT_Char)( tag >> 24 ),
                   (FT_Char)( tag >> 16 ),
                   (FT_Char)( tag >> 8  ),
                   (FT_Char)( tag       ) ));
        error = FT_THROW( Invalid_Table );
        goto Exit;
      }
    }

    if ( woff2.uncompressed_size < 1 )
    {
      error = FT_THROW( Invalid_Table );
      goto Exit;
    }

    if ( woff2.uncompressed_size > sfnt_size )
    {
      FT_ERROR(( "woff2_open_font: SFNT table lengths are too large.\n" ));
      error = FT_THROW( Invalid_Table );
      goto Exit;
    }

    /* Allocate memory for uncompressed table data. */
    if ( FT_QALLOC( uncompressed_buf, woff2.uncompressed_size ) ||
         FT_FRAME_ENTER( woff2.totalCompressedSize )            )
      goto Exit;

    /* Uncompress the stream. */
    error = woff2_decompress( uncompressed_buf,
                              woff2.uncompressed_size,
                              stream->cursor,
                              woff2.totalCompressedSize );

    FT_FRAME_EXIT();

    if ( error )
      goto Exit;

    error = reconstruct_font( uncompressed_buf,
                              woff2.uncompressed_size,
                              indices,
                              &woff2,
                              &info,
                              &sfnt,
                              &sfnt_size,
                              memory );

    if ( error )
      goto Exit;

    /* Resize `sfnt' to actual size of sfnt stream. */
    if ( woff2.actual_sfnt_size < sfnt_size )
    {
      FT_TRACE5(( "Trimming sfnt stream from %lu to %lu.\n",
                  sfnt_size, woff2.actual_sfnt_size ));
      if ( FT_QREALLOC( sfnt,
                        (FT_ULong)( sfnt_size ),
                        (FT_ULong)( woff2.actual_sfnt_size ) ) )
        goto Exit;
    }

    /* `reconstruct_font' has done all the work. */
    /* Swap out stream and return.               */
    FT_Stream_OpenMemory( sfnt_stream, sfnt, woff2.actual_sfnt_size );
    sfnt_stream->memory = stream->memory;
    sfnt_stream->close  = stream_close;

    FT_Stream_Free(
      face->root.stream,
      ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );

    face->root.stream      = sfnt_stream;
    face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;

    /* Set face_index to 0 or -1. */
    if ( *face_instance_index >= 0 )
      *face_instance_index = 0;
    else
      *face_instance_index = -1;

    FT_TRACE2(( "woff2_open_font: SFNT synthesized.\n" ));

  Exit:
    FT_FREE( tables );
    FT_FREE( indices );
    FT_FREE( uncompressed_buf );
    FT_FREE( info.x_mins );

    if ( woff2.ttc_fonts )
    {
      WOFF2_TtcFont  ttc_font = woff2.ttc_fonts;


      for ( nn = 0; nn < woff2.num_fonts; nn++ )
      {
        FT_FREE( ttc_font->table_indices );
        ttc_font++;
      }

      FT_FREE( woff2.ttc_fonts );
    }

    if ( error )
    {
      FT_FREE( sfnt );
      if ( sfnt_stream )
      {
        FT_Stream_Close( sfnt_stream );
        FT_FREE( sfnt_stream );
      }
    }

    return error;
  }


#undef READ_255USHORT
#undef READ_BASE128
#undef ROUND4
#undef WRITE_USHORT
#undef WRITE_ULONG
#undef WRITE_SHORT
#undef WRITE_SFNT_BUF
#undef WRITE_SFNT_BUF_AT

#undef N_CONTOUR_STREAM
#undef N_POINTS_STREAM
#undef FLAG_STREAM
#undef GLYPH_STREAM
#undef COMPOSITE_STREAM
#undef BBOX_STREAM
#undef INSTRUCTION_STREAM

#else /* !FT_CONFIG_OPTION_USE_BROTLI */

  /* ANSI C doesn't like empty source files */
  typedef int  _sfwoff2_dummy;

#endif /* !FT_CONFIG_OPTION_USE_BROTLI */


/* END */
