/****************************************************************************
 *
 * ttcpal.c
 *
 *   TrueType and OpenType color palette support (body).
 *
 * Copyright (C) 2018-2020 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * Originally written by Shao Yu Zhang <shaozhang@fb.com>.
 *
 * 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.
 *
 */


  /**************************************************************************
   *
   * `CPAL' table specification:
   *
   *   https://www.microsoft.com/typography/otspec/cpal.htm
   *
   */


#include <ft2build.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
#include <freetype/tttags.h>
#include <freetype/ftcolor.h>


#ifdef TT_CONFIG_OPTION_COLOR_LAYERS

#include "ttcpal.h"


  /* NOTE: These are the table sizes calculated through the specs. */
#define CPAL_V0_HEADER_BASE_SIZE  12
#define COLOR_SIZE                 4


  /* all data from `CPAL' not covered in FT_Palette_Data */
  typedef struct Cpal_
  {
    FT_UShort  version;        /* Table version number (0 or 1 supported). */
    FT_UShort  num_colors;               /* Total number of color records, */
                                         /* combined for all palettes.     */
    FT_Byte*  colors;                              /* RGBA array of colors */
    FT_Byte*  color_indices; /* Index of each palette's first color record */
                             /* in the combined color record array.        */

    /* The memory which backs up the `CPAL' table. */
    void*     table;
    FT_ULong  table_size;

  } Cpal;


  /**************************************************************************
   *
   * 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  ttcpal


  FT_LOCAL_DEF( FT_Error )
  tt_face_load_cpal( TT_Face    face,
                     FT_Stream  stream )
  {
    FT_Error   error;
    FT_Memory  memory = face->root.memory;

    FT_Byte*  table = NULL;
    FT_Byte*  p     = NULL;

    Cpal*  cpal = NULL;

    FT_ULong  colors_offset;
    FT_ULong  table_size;


    error = face->goto_table( face, TTAG_CPAL, stream, &table_size );
    if ( error )
      goto NoCpal;

    if ( table_size < CPAL_V0_HEADER_BASE_SIZE )
      goto InvalidTable;

    if ( FT_FRAME_EXTRACT( table_size, table ) )
      goto NoCpal;

    p = table;

    if ( FT_NEW( cpal ) )
      goto NoCpal;

    cpal->version = FT_NEXT_USHORT( p );
    if ( cpal->version > 1 )
      goto InvalidTable;

    face->palette_data.num_palette_entries = FT_NEXT_USHORT( p );
    face->palette_data.num_palettes        = FT_NEXT_USHORT( p );

    cpal->num_colors = FT_NEXT_USHORT( p );
    colors_offset    = FT_NEXT_ULONG( p );

    if ( CPAL_V0_HEADER_BASE_SIZE             +
         face->palette_data.num_palettes * 2U > table_size )
      goto InvalidTable;

    if ( colors_offset >= table_size )
      goto InvalidTable;
    if ( cpal->num_colors * COLOR_SIZE > table_size - colors_offset )
      goto InvalidTable;

    if ( face->palette_data.num_palette_entries > cpal->num_colors )
      goto InvalidTable;

    cpal->color_indices = p;
    cpal->colors        = (FT_Byte*)( table + colors_offset );

    if ( cpal->version == 1 )
    {
      FT_ULong    type_offset, label_offset, entry_label_offset;
      FT_UShort*  array = NULL;
      FT_UShort*  limit;
      FT_UShort*  q;


      if ( CPAL_V0_HEADER_BASE_SIZE             +
           face->palette_data.num_palettes * 2U +
           3U * 4                               > table_size )
        goto InvalidTable;

      p += face->palette_data.num_palettes * 2;

      type_offset        = FT_NEXT_ULONG( p );
      label_offset       = FT_NEXT_ULONG( p );
      entry_label_offset = FT_NEXT_ULONG( p );

      if ( type_offset )
      {
        if ( type_offset >= table_size )
          goto InvalidTable;
        if ( face->palette_data.num_palettes * 2 >
               table_size - type_offset )
          goto InvalidTable;

        if ( FT_QNEW_ARRAY( array, face->palette_data.num_palettes ) )
          goto NoCpal;

        p     = table + type_offset;
        q     = array;
        limit = q + face->palette_data.num_palettes;

        while ( q < limit )
          *q++ = FT_NEXT_USHORT( p );

        face->palette_data.palette_flags = array;
      }

      if ( label_offset )
      {
        if ( label_offset >= table_size )
          goto InvalidTable;
        if ( face->palette_data.num_palettes * 2 >
               table_size - label_offset )
          goto InvalidTable;

        if ( FT_QNEW_ARRAY( array, face->palette_data.num_palettes ) )
          goto NoCpal;

        p     = table + label_offset;
        q     = array;
        limit = q + face->palette_data.num_palettes;

        while ( q < limit )
          *q++ = FT_NEXT_USHORT( p );

        face->palette_data.palette_name_ids = array;
      }

      if ( entry_label_offset )
      {
        if ( entry_label_offset >= table_size )
          goto InvalidTable;
        if ( face->palette_data.num_palette_entries * 2 >
               table_size - entry_label_offset )
          goto InvalidTable;

        if ( FT_QNEW_ARRAY( array, face->palette_data.num_palette_entries ) )
          goto NoCpal;

        p     = table + entry_label_offset;
        q     = array;
        limit = q + face->palette_data.num_palette_entries;

        while ( q < limit )
          *q++ = FT_NEXT_USHORT( p );

        face->palette_data.palette_entry_name_ids = array;
      }
    }

    cpal->table      = table;
    cpal->table_size = table_size;

    face->cpal = cpal;

    /* set up default palette */
    if ( FT_NEW_ARRAY( face->palette,
                       face->palette_data.num_palette_entries ) )
      goto NoCpal;

    if ( tt_face_palette_set( face, 0 ) )
      goto InvalidTable;

    return FT_Err_Ok;

  InvalidTable:
    error = FT_THROW( Invalid_Table );

  NoCpal:
    FT_FRAME_RELEASE( table );
    FT_FREE( cpal );

    face->cpal = NULL;

    /* arrays in `face->palette_data' and `face->palette' */
    /* are freed in `sfnt_done_face'                      */

    return error;
  }


  FT_LOCAL_DEF( void )
  tt_face_free_cpal( TT_Face  face )
  {
    FT_Stream  stream = face->root.stream;
    FT_Memory  memory = face->root.memory;

    Cpal*  cpal = (Cpal*)face->cpal;


    if ( cpal )
    {
      FT_FRAME_RELEASE( cpal->table );
      FT_FREE( cpal );
    }
  }


  FT_LOCAL_DEF( FT_Error )
  tt_face_palette_set( TT_Face  face,
                       FT_UInt  palette_index )
  {
    Cpal*  cpal = (Cpal*)face->cpal;

    FT_Byte*   offset;
    FT_Byte*   p;

    FT_Color*  q;
    FT_Color*  limit;

    FT_UShort  color_index;


    if ( !cpal || palette_index >= face->palette_data.num_palettes )
      return FT_THROW( Invalid_Argument );

    offset      = cpal->color_indices + 2 * palette_index;
    color_index = FT_PEEK_USHORT( offset );

    if ( color_index + face->palette_data.num_palette_entries >
           cpal->num_colors )
      return FT_THROW( Invalid_Table );

    p     = cpal->colors + COLOR_SIZE * color_index;
    q     = face->palette;
    limit = q + face->palette_data.num_palette_entries;

    while ( q < limit )
    {
      q->blue  = FT_NEXT_BYTE( p );
      q->green = FT_NEXT_BYTE( p );
      q->red   = FT_NEXT_BYTE( p );
      q->alpha = FT_NEXT_BYTE( p );

      q++;
    }

    return FT_Err_Ok;
  }


#else /* !TT_CONFIG_OPTION_COLOR_LAYERS */

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

#endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */

/* EOF */
