1/*
2 *  Copyright 2012 The LibYuv Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef INCLUDE_LIBYUV_MJPEG_DECODER_H_  // NOLINT
12#define INCLUDE_LIBYUV_MJPEG_DECODER_H_
13
14#include "libyuv/basic_types.h"
15
16// NOTE: For a simplified public API use convert.h MJPGToI420().
17
18struct jpeg_common_struct;
19struct jpeg_decompress_struct;
20struct jpeg_source_mgr;
21
22namespace libyuv {
23
24static const uint32 kUnknownDataSize = 0xFFFFFFFF;
25
26enum JpegSubsamplingType {
27  kJpegYuv420,
28  kJpegYuv422,
29  kJpegYuv411,
30  kJpegYuv444,
31  kJpegYuv400,
32  kJpegUnknown
33};
34
35struct SetJmpErrorMgr;
36
37// MJPEG ("Motion JPEG") is a pseudo-standard video codec where the frames are
38// simply independent JPEG images with a fixed huffman table (which is omitted).
39// It is rarely used in video transmission, but is common as a camera capture
40// format, especially in Logitech devices. This class implements a decoder for
41// MJPEG frames.
42//
43// See http://tools.ietf.org/html/rfc2435
44class MJpegDecoder {
45 public:
46  typedef void (*CallbackFunction)(void* opaque,
47                                   const uint8* const* data,
48                                   const int* strides,
49                                   int rows);
50
51  static const int kColorSpaceUnknown;
52  static const int kColorSpaceGrayscale;
53  static const int kColorSpaceRgb;
54  static const int kColorSpaceYCbCr;
55  static const int kColorSpaceCMYK;
56  static const int kColorSpaceYCCK;
57
58  MJpegDecoder();
59  ~MJpegDecoder();
60
61  // Loads a new frame, reads its headers, and determines the uncompressed
62  // image format. Returns true if image looks valid and format is supported.
63  // If return value is true, then the values for all the following getters
64  // are populated.
65  // src_len is the size of the compressed mjpeg frame in bytes.
66  bool LoadFrame(const uint8* src, size_t src_len);
67
68  // Returns width of the last loaded frame in pixels.
69  int GetWidth();
70
71  // Returns height of the last loaded frame in pixels.
72  int GetHeight();
73
74  // Returns format of the last loaded frame. The return value is one of the
75  // kColorSpace* constants.
76  int GetColorSpace();
77
78  // Number of color components in the color space.
79  int GetNumComponents();
80
81  // Sample factors of the n-th component.
82  int GetHorizSampFactor(int component);
83
84  int GetVertSampFactor(int component);
85
86  int GetHorizSubSampFactor(int component);
87
88  int GetVertSubSampFactor(int component);
89
90  // Public for testability.
91  int GetImageScanlinesPerImcuRow();
92
93  // Public for testability.
94  int GetComponentScanlinesPerImcuRow(int component);
95
96  // Width of a component in bytes.
97  int GetComponentWidth(int component);
98
99  // Height of a component.
100  int GetComponentHeight(int component);
101
102  // Width of a component in bytes with padding for DCTSIZE. Public for testing.
103  int GetComponentStride(int component);
104
105  // Size of a component in bytes.
106  int GetComponentSize(int component);
107
108  // Call this after LoadFrame() if you decide you don't want to decode it
109  // after all.
110  bool UnloadFrame();
111
112  // Decodes the entire image into a one-buffer-per-color-component format.
113  // dst_width must match exactly. dst_height must be <= to image height; if
114  // less, the image is cropped. "planes" must have size equal to at least
115  // GetNumComponents() and they must point to non-overlapping buffers of size
116  // at least GetComponentSize(i). The pointers in planes are incremented
117  // to point to after the end of the written data.
118  // TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded.
119  bool DecodeToBuffers(uint8** planes, int dst_width, int dst_height);
120
121  // Decodes the entire image and passes the data via repeated calls to a
122  // callback function. Each call will get the data for a whole number of
123  // image scanlines.
124  // TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded.
125  bool DecodeToCallback(CallbackFunction fn, void* opaque,
126                        int dst_width, int dst_height);
127
128  // The helper function which recognizes the jpeg sub-sampling type.
129  static JpegSubsamplingType JpegSubsamplingTypeHelper(
130     int* subsample_x, int* subsample_y, int number_of_components);
131
132 private:
133  struct Buffer {
134    const uint8* data;
135    int len;
136  };
137
138  struct BufferVector {
139    Buffer* buffers;
140    int len;
141    int pos;
142  };
143
144  // Methods that are passed to jpeglib.
145  static int fill_input_buffer(jpeg_decompress_struct* cinfo);
146  static void init_source(jpeg_decompress_struct* cinfo);
147  static void skip_input_data(jpeg_decompress_struct* cinfo,
148                              long num_bytes);  // NOLINT
149  static void term_source(jpeg_decompress_struct* cinfo);
150
151  static void ErrorHandler(jpeg_common_struct* cinfo);
152
153  void AllocOutputBuffers(int num_outbufs);
154  void DestroyOutputBuffers();
155
156  bool StartDecode();
157  bool FinishDecode();
158
159  void SetScanlinePointers(uint8** data);
160  bool DecodeImcuRow();
161
162  int GetComponentScanlinePadding(int component);
163
164  // A buffer holding the input data for a frame.
165  Buffer buf_;
166  BufferVector buf_vec_;
167
168  jpeg_decompress_struct* decompress_struct_;
169  jpeg_source_mgr* source_mgr_;
170  SetJmpErrorMgr* error_mgr_;
171
172  // true iff at least one component has scanline padding. (i.e.,
173  // GetComponentScanlinePadding() != 0.)
174  bool has_scanline_padding_;
175
176  // Temporaries used to point to scanline outputs.
177  int num_outbufs_;  // Outermost size of all arrays below.
178  uint8*** scanlines_;
179  int* scanlines_sizes_;
180  // Temporary buffer used for decoding when we can't decode directly to the
181  // output buffers. Large enough for just one iMCU row.
182  uint8** databuf_;
183  int* databuf_strides_;
184};
185
186}  // namespace libyuv
187
188#endif  // INCLUDE_LIBYUV_MJPEG_DECODER_H_  NOLINT
189