/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "vp9/common/seg_common.h"

static const int segfeaturedata_signed[SEG_LVL_MAX] = { 1, 1, 0, 0, 0, 0 };
static const int seg_feature_data_bits[SEG_LVL_MAX] = { QINDEX_BITS, 6, 4, 4, 6, 2 };

// These functions provide access to new segment level features.
// Eventually these function may be "optimized out" but for the moment,
// the coding mechanism is still subject to change so these provide a
// convenient single point of change.

int vp9_segfeature_active(const MACROBLOCKD *xd,
                          int segment_id,
                          SEG_LVL_FEATURES feature_id) {
  // Return true if mask bit set and segmentation enabled.
  return (xd->segmentation_enabled &&
          (xd->segment_feature_mask[segment_id] &
           (0x01 << feature_id)));
}

void vp9_clearall_segfeatures(MACROBLOCKD *xd) {
  vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data));
  vpx_memset(xd->segment_feature_mask, 0, sizeof(xd->segment_feature_mask));
}

void vp9_enable_segfeature(MACROBLOCKD *xd,
                           int segment_id,
                           SEG_LVL_FEATURES feature_id) {
  xd->segment_feature_mask[segment_id] |= (0x01 << feature_id);
}

void vp9_disable_segfeature(MACROBLOCKD *xd,
                            int segment_id,
                            SEG_LVL_FEATURES feature_id) {
  xd->segment_feature_mask[segment_id] &= ~(1 << feature_id);
}

int vp9_seg_feature_data_bits(SEG_LVL_FEATURES feature_id) {
  return seg_feature_data_bits[feature_id];
}

int vp9_is_segfeature_signed(SEG_LVL_FEATURES feature_id) {
  return (segfeaturedata_signed[feature_id]);
}

void vp9_clear_segdata(MACROBLOCKD *xd,
                       int segment_id,
                       SEG_LVL_FEATURES feature_id) {
  xd->segment_feature_data[segment_id][feature_id] = 0;
}

void vp9_set_segdata(MACROBLOCKD *xd,
                     int segment_id,
                     SEG_LVL_FEATURES feature_id,
                     int seg_data) {
  xd->segment_feature_data[segment_id][feature_id] = seg_data;
}

int vp9_get_segdata(const MACROBLOCKD *xd,
                    int segment_id,
                    SEG_LVL_FEATURES feature_id) {
  return xd->segment_feature_data[segment_id][feature_id];
}

void vp9_clear_segref(MACROBLOCKD *xd, int segment_id) {
  xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] = 0;
}

void vp9_set_segref(MACROBLOCKD *xd,
                    int segment_id,
                    MV_REFERENCE_FRAME ref_frame) {
  xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] |=
    (1 << ref_frame);
}

int vp9_check_segref(const MACROBLOCKD *xd,
                     int segment_id,
                     MV_REFERENCE_FRAME ref_frame) {
  return (xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] &
          (1 << ref_frame)) ? 1 : 0;
}

int vp9_check_segref_inter(MACROBLOCKD *xd, int segment_id) {
  return (xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] &
          ~(1 << INTRA_FRAME)) ? 1 : 0;
}

int vp9_get_seg_tx_type(MACROBLOCKD *xd, int segment_id) {
  if (vp9_segfeature_active(xd, segment_id, SEG_LVL_TRANSFORM))
    return vp9_get_segdata(xd, segment_id, SEG_LVL_TRANSFORM);
  else
    return TX_4X4;
}
// TBD? Functions to read and write segment data with range / validity checking
