doubango/thirdparties/common/include/libyuv/mjpeg_decoder.h
c732d49e
 /*
  *  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_  // NOLINT
 #define INCLUDE_LIBYUV_MJPEG_DECODER_H_
 
 #include "libyuv/basic_types.h"
 
 struct jpeg_common_struct;
 struct jpeg_decompress_struct;
 struct jpeg_source_mgr;
 
 namespace libyuv {
 
 static const uint32 kUnknownDataSize = 0xFFFFFFFF;
 
 enum JpegSubsamplingType {
   kJpegYuv420,
   kJpegYuv422,
   kJpegYuv411,
   kJpegYuv444,
   kJpegYuv400,
   kJpegUnknown
 };
 
 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 MJpegDecoder {
  public:
   typedef void (*CallbackFunction)(void* opaque,
                                    const uint8* 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 true if image looks valid and format is supported.
   // If return value is true, then the values for all the following getters
   // are populated.
   // src_len is the size of the compressed mjpeg frame in bytes.
   bool LoadFrame(const uint8* 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.
   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.
   bool DecodeToBuffers(uint8** 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.
   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:
   struct Buffer {
     const uint8* data;
     int len;
   };
 
   struct BufferVector {
     Buffer* buffers;
     int len;
     int pos;
   };
 
   // Methods that are passed to jpeglib.
   static int fill_input_buffer(jpeg_decompress_struct* cinfo);
   static void init_source(jpeg_decompress_struct* cinfo);
   static void skip_input_data(jpeg_decompress_struct* cinfo,
                               long num_bytes);  // NOLINT
   static void term_source(jpeg_decompress_struct* cinfo);
 
   static void ErrorHandler(jpeg_common_struct* cinfo);
 
   void AllocOutputBuffers(int num_outbufs);
   void DestroyOutputBuffers();
 
   bool StartDecode();
   bool FinishDecode();
 
   void SetScanlinePointers(uint8** data);
   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_;
 
   // true iff at least one component has scanline padding. (i.e.,
   // GetComponentScanlinePadding() != 0.)
   bool has_scanline_padding_;
 
   // Temporaries used to point to scanline outputs.
   int num_outbufs_;  // Outermost size of all arrays below.
   uint8*** 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** databuf_;
   int* databuf_strides_;
 };
 
 }  // namespace libyuv
 
 #endif  // INCLUDE_LIBYUV_MJPEG_DECODER_H_  NOLINT