/*
 *  Copyright 2012 The LibYuv 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 INCLUDE_LIBYUV_MJPEG_DECODER_H_
#define INCLUDE_LIBYUV_MJPEG_DECODER_H_

#include "libyuv/basic_types.h"

#ifdef __cplusplus
// NOTE: For a simplified public API use convert.h MJPGToI420().

struct jpeg_common_struct;
struct jpeg_decompress_struct;
struct jpeg_source_mgr;

namespace libyuv {

#ifdef __cplusplus
extern "C" {
#endif

LIBYUV_BOOL ValidateJpeg(const uint8_t* sample, size_t sample_size);

#ifdef __cplusplus
}  // extern "C"
#endif

static const uint32_t kUnknownDataSize = 0xFFFFFFFF;

enum JpegSubsamplingType {
  kJpegYuv420,
  kJpegYuv422,
  kJpegYuv444,
  kJpegYuv400,
  kJpegUnknown
};

struct Buffer {
  const uint8_t* data;
  int len;
};

struct BufferVector {
  Buffer* buffers;
  int len;
  int pos;
};

struct SetJmpErrorMgr;

// MJPEG ("Motion JPEG") is a pseudo-standard video codec where the frames are
// simply independent JPEG images with a fixed huffman table (which is omitted).
// It is rarely used in video transmission, but is common as a camera capture
// format, especially in Logitech devices. This class implements a decoder for
// MJPEG frames.
//
// See http://tools.ietf.org/html/rfc2435
class LIBYUV_API MJpegDecoder {
 public:
  typedef void (*CallbackFunction)(void* opaque,
                                   const uint8_t* const* data,
                                   const int* strides,
                                   int rows);

  static const int kColorSpaceUnknown;
  static const int kColorSpaceGrayscale;
  static const int kColorSpaceRgb;
  static const int kColorSpaceYCbCr;
  static const int kColorSpaceCMYK;
  static const int kColorSpaceYCCK;

  MJpegDecoder();
  ~MJpegDecoder();

  // Loads a new frame, reads its headers, and determines the uncompressed
  // image format.
  // Returns LIBYUV_TRUE if image looks valid and format is supported.
  // If return value is LIBYUV_TRUE, then the values for all the following
  // getters are populated.
  // src_len is the size of the compressed mjpeg frame in bytes.
  LIBYUV_BOOL LoadFrame(const uint8_t* src, size_t src_len);

  // Returns width of the last loaded frame in pixels.
  int GetWidth();

  // Returns height of the last loaded frame in pixels.
  int GetHeight();

  // Returns format of the last loaded frame. The return value is one of the
  // kColorSpace* constants.
  int GetColorSpace();

  // Number of color components in the color space.
  int GetNumComponents();

  // Sample factors of the n-th component.
  int GetHorizSampFactor(int component);

  int GetVertSampFactor(int component);

  int GetHorizSubSampFactor(int component);

  int GetVertSubSampFactor(int component);

  // Public for testability.
  int GetImageScanlinesPerImcuRow();

  // Public for testability.
  int GetComponentScanlinesPerImcuRow(int component);

  // Width of a component in bytes.
  int GetComponentWidth(int component);

  // Height of a component.
  int GetComponentHeight(int component);

  // Width of a component in bytes with padding for DCTSIZE. Public for testing.
  int GetComponentStride(int component);

  // Size of a component in bytes.
  int GetComponentSize(int component);

  // Call this after LoadFrame() if you decide you don't want to decode it
  // after all.
  LIBYUV_BOOL UnloadFrame();

  // Decodes the entire image into a one-buffer-per-color-component format.
  // dst_width must match exactly. dst_height must be <= to image height; if
  // less, the image is cropped. "planes" must have size equal to at least
  // GetNumComponents() and they must point to non-overlapping buffers of size
  // at least GetComponentSize(i). The pointers in planes are incremented
  // to point to after the end of the written data.
  // TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded.
  LIBYUV_BOOL DecodeToBuffers(uint8_t** planes, int dst_width, int dst_height);

  // Decodes the entire image and passes the data via repeated calls to a
  // callback function. Each call will get the data for a whole number of
  // image scanlines.
  // TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded.
  LIBYUV_BOOL DecodeToCallback(CallbackFunction fn,
                               void* opaque,
                               int dst_width,
                               int dst_height);

  // The helper function which recognizes the jpeg sub-sampling type.
  static JpegSubsamplingType JpegSubsamplingTypeHelper(
      int* subsample_x,
      int* subsample_y,
      int number_of_components);

 private:
  void AllocOutputBuffers(int num_outbufs);
  void DestroyOutputBuffers();

  LIBYUV_BOOL StartDecode();
  LIBYUV_BOOL FinishDecode();

  void SetScanlinePointers(uint8_t** data);
  LIBYUV_BOOL DecodeImcuRow();

  int GetComponentScanlinePadding(int component);

  // A buffer holding the input data for a frame.
  Buffer buf_;
  BufferVector buf_vec_;

  jpeg_decompress_struct* decompress_struct_;
  jpeg_source_mgr* source_mgr_;
  SetJmpErrorMgr* error_mgr_;

  // LIBYUV_TRUE iff at least one component has scanline padding. (i.e.,
  // GetComponentScanlinePadding() != 0.)
  LIBYUV_BOOL has_scanline_padding_;

  // Temporaries used to point to scanline outputs.
  int num_outbufs_;  // Outermost size of all arrays below.
  uint8_t*** scanlines_;
  int* scanlines_sizes_;
  // Temporary buffer used for decoding when we can't decode directly to the
  // output buffers. Large enough for just one iMCU row.
  uint8_t** databuf_;
  int* databuf_strides_;
};

}  // namespace libyuv

#endif  //  __cplusplus
#endif  // INCLUDE_LIBYUV_MJPEG_DECODER_H_
