text: /*****************************************************************************
   * wma.c
   *****************************************************************************
   * Copyright (C) 2014-2015 L-SMASH project
   *
   * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
   *
   * Permission to use, copy, modify, and/or distribute this software for any
   * purpose with or without fee is hereby granted, provided that the above
   * copyright notice and this permission notice appear in all copies.
   *
   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   *****************************************************************************/
  
  /* This file is available under an ISC license. */
  
  #include "common/internal.h" /* must be placed first */
  
  #include <inttypes.h>
  
  #include "core/box.h"
  
  #define WFEX_BOX_MIN_LENGTH 26
  
  #define WAVE_FORMAT_TAG_ID_WMA_V2 0x0161
  #define WAVE_FORMAT_TAG_ID_WMA_V3 0x0162
  
  int wma_print_codec_specific( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
  {
      assert( fp && file && box && (box->manager & LSMASH_BINARY_CODED_BOX) );
      int indent = level;
      lsmash_ifprintf( fp, indent++, "[%s: General Extended Waveform Format Box]\n", isom_4cc2str( box->type.fourcc ) );
      lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
      lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
      if( box->size < WFEX_BOX_MIN_LENGTH )
          return LSMASH_ERR_INVALID_DATA;
      uint8_t *data = box->binary;
      isom_skip_box_common( &data );
      uint16_t wFormatTag = LSMASH_GET_LE16( &data[0] );
      static const char *codec_name[] =
      {
          "Windows Media Audio V2",
          "Windows Media Audio V3"
      };
      if( wFormatTag == WAVE_FORMAT_TAG_ID_WMA_V2
       || wFormatTag == WAVE_FORMAT_TAG_ID_WMA_V3 )
          lsmash_ifprintf( fp, indent, "wFormatTag = 0x%04"PRIx16" (%s)\n", wFormatTag, codec_name[wFormatTag - WAVE_FORMAT_TAG_ID_WMA_V2] );
      else
          lsmash_ifprintf( fp, indent, "wFormatTag = 0x%04"PRIx16"\n", wFormatTag );
      lsmash_ifprintf( fp, indent, "nChannels = %"PRIu16"\n",       LSMASH_GET_LE16( &data[ 2] ) );
      lsmash_ifprintf( fp, indent, "nSamplesPerSec = %"PRIu32"\n",  LSMASH_GET_LE32( &data[ 4] ) );
      lsmash_ifprintf( fp, indent, "nAvgBytesPerSec = %"PRIu32"\n", LSMASH_GET_LE32( &data[ 8] ) );
      lsmash_ifprintf( fp, indent, "nBlockAlign = %"PRIu16"\n",     LSMASH_GET_LE16( &data[12] ) );
      lsmash_ifprintf( fp, indent, "wBitsPerSample = %"PRIu16"\n",  LSMASH_GET_LE16( &data[14] ) );
      uint16_t cbSize = LSMASH_GET_BYTE( &data[16] );
      lsmash_ifprintf( fp, indent, "cbSize = %"PRIu16"\n",           cbSize );
      switch( wFormatTag )
      {
          case WAVE_FORMAT_TAG_ID_WMA_V2 :
              if( cbSize < 10 )
                  return LSMASH_ERR_INVALID_DATA;
              lsmash_ifprintf( fp, indent, "dwSamplesPerBlock = %"PRIu32"\n",  LSMASH_GET_LE32( &data[18] ) );
              lsmash_ifprintf( fp, indent, "wEncodeOptions = 0x%04"PRIu16"\n", LSMASH_GET_LE16( &data[22] ) );
              lsmash_ifprintf( fp, indent, "dwSuperBlockAlign = %"PRIu32"\n",  LSMASH_GET_LE32( &data[24] ) );
              break;
          case WAVE_FORMAT_TAG_ID_WMA_V3 :
              if( cbSize < 18 )
                  return LSMASH_ERR_INVALID_DATA;
              lsmash_ifprintf( fp, indent, "wValidBitsPerSample = %"PRIu16"\n", LSMASH_GET_LE16( &data[18] ) );
              lsmash_ifprintf( fp, indent, "dwChannelMask = 0x%08"PRIu32"\n",   LSMASH_GET_LE32( &data[20] ) );
              lsmash_ifprintf( fp, indent, "dwReserved1 = 0x%08"PRIu32"\n",     LSMASH_GET_LE32( &data[24] ) );
              lsmash_ifprintf( fp, indent, "dwReserved2 = 0x%08"PRIu32"\n",     LSMASH_GET_LE32( &data[28] ) );
              lsmash_ifprintf( fp, indent, "wEncodeOptions = 0x%04"PRIu16"\n",  LSMASH_GET_LE16( &data[32] ) );
              lsmash_ifprintf( fp, indent, "wReserved3 = 0x%04"PRIu16"\n",      LSMASH_GET_LE16( &data[34] ) );
              break;
          default :
              break;
      }
      return 0;
  }
  