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