• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 struct jpeg_common_struct;
19 struct jpeg_decompress_struct;
20 struct jpeg_source_mgr;
21 
22 namespace libyuv {
23 
24 static const uint32 kUnknownDataSize = 0xFFFFFFFF;
25 
26 enum JpegSubsamplingType {
27   kJpegYuv420,
28   kJpegYuv422,
29   kJpegYuv411,
30   kJpegYuv444,
31   kJpegYuv400,
32   kJpegUnknown
33 };
34 
35 struct 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
44 class 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