blob: 67090cf0b5fe1fbb395f0d5b85bb7d904af86429 [file] [log] [blame]
Hendrik Dahlkamp33cfdeb2013-01-23 18:27:37 -08001/*
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