summaryrefslogtreecommitdiff
path: root/media/libyuv/include/libyuv/mjpeg_decoder.h
blob: 8423121d11ec7b51e19a45da905b743660d0803a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*
 *  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"

#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* sample, size_t sample_size);

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

static const uint32 kUnknownDataSize = 0xFFFFFFFF;

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

struct Buffer {
  const uint8* 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* 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* 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** 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** 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*** 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  //  __cplusplus
#endif  // INCLUDE_LIBYUV_MJPEG_DECODER_H_  NOLINT