/*
 *  Copyright (c) 2012 The WebRTC 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.
 */

#ifndef WEBRTC_TOOLS_CONVERTER_CONVERTER_H_
#define WEBRTC_TOOLS_CONVERTER_CONVERTER_H_

#include <string>

#include "libyuv/compare.h"  // NOLINT
#include "libyuv/convert.h"  // NOLINT

namespace webrtc {
namespace test {

// Handles a conversion between a set of RGBA frames to a YUV (I420) video.
class Converter {
 public:
  Converter(int width, int height);

  // Converts RGBA to YUV video. If the delete_frames argument is true, the
  // method will delete the input frames after conversion.
  bool ConvertRGBAToI420Video(std::string frames_dir,
                              std::string output_file_name, bool delete_frames);

 private:
  int width_;  // Width of the video (respectively of the RGBA frames).
  int height_;  // Height of the video (respectively of the RGBA frames).

  // Returns the size of the Y plane in bytes.
  int YPlaneSize() const {
    return width_*height_;
  }

  // Returns the size of the U plane in bytes.
  int UPlaneSize() const {
    return ((width_+1)/2)*((height_)/2);
  }

  // Returns the size of the V plane in bytes.
  int VPlaneSize() const {
    return ((width_+1)/2)*((height_)/2);
  }

  // Returns the number of bytes per row in the RGBA frame.
  int SrcStrideFrame() const {
    return width_*4;
  }

  // Returns the number of bytes in the Y plane.
  int DstStrideY() const {
    return width_;
  }

  // Returns the number of bytes in the U plane.
  int DstStrideU() const {
    return (width_+1)/2;
  }

  // Returns the number of bytes in the V plane.
  int DstStrideV() const {
    return (width_+1)/2;
  }

  // Returns the size in bytes of the input RGBA frames.
  int InputFrameSize() const {
    return width_*height_*4;
  }

  // Writes the Y, U and V (in this order) planes to the file, thus adding a
  // raw YUV frame to the file.
  bool AddYUVToFile(uint8* y_plane, int y_plane_size,
                    uint8* u_plane, int u_plane_size,
                    uint8* v_plane, int v_plane_size,
                    FILE* output_file);

  // Adds the Y, U or V plane to the file.
  bool AddYUVPlaneToFile(uint8* yuv_plane, int yuv_plane_size, FILE* file);

  // Reads a RGBA frame from input_file_name with input_frame_size size in bytes
  // into the buffer.
  bool ReadRGBAFrame(const char* input_file_name, int input_frame_size,
                     unsigned char* buffer);

  // Finds the full path name of the file - concatenates the directory and file
  // names.
  std::string FindFullFileName(std::string dir_name, std::string file_name);

  // Checks if a file exists.
  bool FileExists(std::string file_name_to_check);

  // Returns the name of the file in the form frame_<number>, where <number> is
    // 4 zero padded (i.e. frame_0000, frame_0001, etc.).
  std::string FormFrameName(int width, int number);
};

}  // namespace test
}  // namespace webrtc

#endif  // WEBRTC_TOOLS_CONVERTER_CONVERTER_H_
