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