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