forked from xiaozhi/xiaozhi-esp32
120 lines
4.4 KiB
C++
120 lines
4.4 KiB
C++
// jpeg_encoder.h - 使用类成员变量的简单版本
|
||
// 这个版本直接在类中声明数组,要求必须在堆上创建实例
|
||
|
||
#ifndef JPEG_ENCODER_H
|
||
#define JPEG_ENCODER_H
|
||
|
||
namespace jpge2_simple
|
||
{
|
||
typedef unsigned char uint8;
|
||
typedef signed short int16;
|
||
typedef signed int int32;
|
||
typedef unsigned short uint16;
|
||
typedef unsigned int uint32;
|
||
typedef unsigned int uint;
|
||
|
||
enum subsampling_t { Y_ONLY = 0, H1V1 = 1, H2V1 = 2, H2V2 = 3 };
|
||
|
||
struct params {
|
||
inline params() : m_quality(85), m_subsampling(H2V2) { }
|
||
inline bool check() const {
|
||
if ((m_quality < 1) || (m_quality > 100)) return false;
|
||
if ((uint)m_subsampling > (uint)H2V2) return false;
|
||
return true;
|
||
}
|
||
int m_quality;
|
||
subsampling_t m_subsampling;
|
||
};
|
||
|
||
class output_stream {
|
||
public:
|
||
virtual ~output_stream() { };
|
||
virtual bool put_buf(const void* Pbuf, int len) = 0;
|
||
virtual uint get_size() const = 0;
|
||
};
|
||
|
||
// 简单版本:直接在类中声明数组
|
||
// 警告:必须在堆上创建实例!(使用 new)
|
||
class jpeg_encoder {
|
||
public:
|
||
jpeg_encoder();
|
||
~jpeg_encoder();
|
||
|
||
bool init(output_stream *pStream, int width, int height, int src_channels, const params &comp_params = params());
|
||
bool process_scanline(const void* pScanline);
|
||
void deinit();
|
||
|
||
private:
|
||
jpeg_encoder(const jpeg_encoder &);
|
||
jpeg_encoder &operator =(const jpeg_encoder &);
|
||
|
||
typedef int32 sample_array_t;
|
||
enum { JPGE_OUT_BUF_SIZE = 512 };
|
||
|
||
output_stream *m_pStream;
|
||
params m_params;
|
||
uint8 m_num_components;
|
||
uint8 m_comp_h_samp[3], m_comp_v_samp[3];
|
||
int m_image_x, m_image_y, m_image_bpp, m_image_bpl;
|
||
int m_image_x_mcu, m_image_y_mcu;
|
||
int m_image_bpl_xlt, m_image_bpl_mcu;
|
||
int m_mcus_per_row;
|
||
int m_mcu_x, m_mcu_y;
|
||
uint8 *m_mcu_lines[16];
|
||
uint8 m_mcu_y_ofs;
|
||
sample_array_t m_sample_array[64];
|
||
int16 m_coefficient_array[64];
|
||
|
||
int m_last_dc_val[3];
|
||
uint8 m_out_buf[JPGE_OUT_BUF_SIZE];
|
||
uint8 *m_pOut_buf;
|
||
uint m_out_buf_left;
|
||
uint32 m_bit_buffer;
|
||
uint m_bits_in;
|
||
uint8 m_pass_num;
|
||
bool m_all_stream_writes_succeeded;
|
||
|
||
// 直接声明为类成员变量(约8KB)
|
||
int32 m_last_quality;
|
||
int32 m_quantization_tables[2][64]; // 512 bytes
|
||
bool m_huff_initialized;
|
||
uint m_huff_codes[4][256]; // 4096 bytes
|
||
uint8 m_huff_code_sizes[4][256]; // 1024 bytes
|
||
uint8 m_huff_bits[4][17]; // 68 bytes
|
||
uint8 m_huff_val[4][256]; // 1024 bytes
|
||
|
||
// compute_huffman_table的临时缓冲区也作为成员变量
|
||
uint8 m_huff_size_temp[257]; // 257 bytes
|
||
uint m_huff_code_temp[257]; // 1028 bytes
|
||
|
||
bool jpg_open(int p_x_res, int p_y_res, int src_channels);
|
||
void flush_output_buffer();
|
||
void put_bits(uint bits, uint len);
|
||
void emit_byte(uint8 i);
|
||
void emit_word(uint i);
|
||
void emit_marker(int marker);
|
||
void emit_jfif_app0();
|
||
void emit_dqt();
|
||
void emit_sof();
|
||
void emit_dht(uint8 *bits, uint8 *val, int index, bool ac_flag);
|
||
void emit_dhts();
|
||
void emit_sos();
|
||
void compute_quant_table(int32 *dst, const int16 *src);
|
||
void load_quantized_coefficients(int component_num);
|
||
void load_block_8_8_grey(int x);
|
||
void load_block_8_8(int x, int y, int c);
|
||
void load_block_16_8(int x, int c);
|
||
void load_block_16_8_8(int x, int c);
|
||
void code_coefficients_pass_two(int component_num);
|
||
void code_block(int component_num);
|
||
void process_mcu_row();
|
||
bool process_end_of_image();
|
||
void load_mcu(const void* src);
|
||
void clear();
|
||
void compute_huffman_table(uint *codes, uint8 *code_sizes, uint8 *bits, uint8 *val);
|
||
};
|
||
|
||
} // namespace jpge2_simple
|
||
|
||
#endif // JPEG_ENCODER_H
|