// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Routines for encoding and decoding a small number of bits into an image
// in a way that is decodable even after scaling/encoding/cropping.
//
// The encoding is very simple:
//
//   ####    ####    ########    ####        ####    ####
//   ####    ####    ########    ####        ####    ####
//   ####    ####    ########    ####        ####    ####
//   ####    ####    ########    ####        ####    ####
//   1   2   3   4   5   6   7   8   9   10  11  12  13  14
//   <-----start----><--one-bit-><-zero bit-><----stop---->
//
// We use a basic unit, depicted here as four characters wide.
// We start with 1u black 1u white 1u black 1u white. (1-4 above)
// From there on, a "one" bit is encoded as 2u black and 1u white,
// and a zero bit is encoded as 1u black and 2u white. After
// all the bits we end the pattern with the same pattern as the
// start of the pattern.

#include <algorithm>
#include <vector>

#include "base/check_op.h"
#include "base/containers/circular_deque.h"
#include "media/base/video_frame.h"
#include "media/cast/test/utility/barcode.h"

namespace media {
namespace cast {
namespace test {

const int kBlackThreshold = 256 * 2 / 3;
const int kWhiteThreshold = 256 / 3;

bool EncodeBarcode(const std::vector<bool>& bits,
                   scoped_refptr<VideoFrame> output_frame) {
  DCHECK(output_frame->format() == PIXEL_FORMAT_YV12 ||
         output_frame->format() == PIXEL_FORMAT_I422 ||
         output_frame->format() == PIXEL_FORMAT_I420);
  int row_bytes = output_frame->row_bytes(VideoFrame::kYPlane);
  std::vector<unsigned char> bytes(row_bytes);
  for (int i = 0; i < row_bytes; i++) {
    bytes[i] = 255;
  }
  size_t units = bits.size() * 3 + 7;  // White or black bar where size matters.
  // We only use 60% of the image to make sure it works even if
  // the image gets cropped.
  size_t unit_size = row_bytes * 6 / 10 / units;
  if (unit_size < 1) return false;
  size_t bytes_required = unit_size * units;
  size_t padding = (row_bytes - bytes_required) / 2;
  unsigned char *pos = &bytes[padding];
  // Two leading black bars.
  memset(pos, 0, unit_size);
  pos += unit_size * 2;
  memset(pos, 0, unit_size);
  pos += unit_size * 2;
  for (size_t bit = 0; bit < bits.size(); bit++) {
    memset(pos, 0, bits[bit] ? unit_size * 2: unit_size);
    pos += unit_size * 3;
  }
  memset(pos, 0, unit_size);
  pos += unit_size * 2;
  memset(pos, 0, unit_size);
  pos += unit_size;
  DCHECK_LE(pos - &bytes.front(), row_bytes);

  // Now replicate this one row into all rows in kYPlane.
  for (int row = 0; row < output_frame->rows(VideoFrame::kYPlane); row++) {
    memcpy(output_frame->data(VideoFrame::kYPlane) +
           output_frame->stride(VideoFrame::kYPlane) * row,
           &bytes.front(),
           row_bytes);
  }
  return true;
}

namespace {
bool DecodeBarCodeRows(const VideoFrame& frame,
                       std::vector<bool>* output,
                       int min_row,
                       int max_row) {
  // Do a basic run-length encoding
  base::circular_deque<int> runs;
  bool is_black = true;
  int length = 0;
  for (int pos = 0; pos < frame.row_bytes(VideoFrame::kYPlane); pos++) {
    float value = 0.0;
    for (int row = min_row; row < max_row; row++) {
      value += frame.data(
          VideoFrame::kYPlane)[frame.stride(VideoFrame::kYPlane) * row + pos];
    }
    value /= max_row - min_row;
    if (is_black ? value > kBlackThreshold : value < kWhiteThreshold) {
      is_black = !is_black;
      runs.push_back(length);
      length = 1;
    } else {
      length++;
    }
  }
  runs.push_back(length);

  // Try decoding starting at each white-black transition.
  while (runs.size() >=  output->size() * 2 + 7) {
    base::circular_deque<int>::const_iterator i = runs.begin();
    double unit_size = (i[1] + i[2] + i[3] + i[4]) / 4;
    bool valid = true;
    if (i[0] > unit_size * 2 || i[0] < unit_size / 2) valid = false;
    if (i[1] > unit_size * 2 || i[1] < unit_size / 2) valid = false;
    if (i[2] > unit_size * 2 || i[2] < unit_size / 2) valid = false;
    if (i[3] > unit_size * 2 || i[3] < unit_size / 2) valid = false;
    i += 4;
    for (size_t bit = 0; valid && bit < output->size(); bit++) {
      if (i[0] > unit_size / 2 && i[0] <= unit_size * 1.5 &&
          i[1] > unit_size * 1.5 && i[1] <= unit_size * 3) {
        (*output)[bit] = false;
      } else if (i[1] > unit_size / 2 && i[1] <= unit_size * 1.5 &&
                 i[0] > unit_size * 1.5 && i[0] <= unit_size * 3) {
        (*output)[bit] = true;
      } else {
        // Not a valid code
        valid = false;
      }
      i += 2;
    }
    if (i[0] > unit_size * 2 || i[0] < unit_size / 2) valid = false;
    if (i[1] > unit_size * 2 || i[1] < unit_size / 2) valid = false;
    if (i[2] > unit_size * 2 || i[2] < unit_size / 2) valid = false;
    i += 3;
    DCHECK(i <= runs.end());
    if (valid) {
      // Decoding successful, return true
     return true;
    }
    runs.pop_front();
    runs.pop_front();
  }
  return false;
}

}  // namespace

// Note that "output" is assumed to be the right size already. This
// could be inferred from the data, but the decoding is more robust
// if we can assume that we know how many bits we want.
bool DecodeBarcode(const VideoFrame& frame, std::vector<bool>* output) {
  DCHECK(frame.format() == PIXEL_FORMAT_YV12 ||
         frame.format() == PIXEL_FORMAT_I422 ||
         frame.format() == PIXEL_FORMAT_I420);
  int rows = frame.rows(VideoFrame::kYPlane);
  // Middle 10 lines
  if (DecodeBarCodeRows(frame, output, std::max(0, rows / 2 - 5),
                        std::min(rows, rows / 2 + 5))) {
    return true;
  }

  // Top 5 lines
  if (DecodeBarCodeRows(frame, output, 0, std::min(5, rows))) {
    return true;
  }

  return false;
}

}  // namespace test
}  // namespace cast
}  // namespace media
