CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/ext/jpge/jpge.h
Views: 1401
// jpge.h - C++ class for JPEG compression.1// Public Domain or Apache 2.0, Richard Geldreich <[email protected]>2// Alex Evans: Added RGBA support, linear memory allocator.3#ifndef JPEG_ENCODER_H4#define JPEG_ENCODER_H56namespace jpge7{8typedef unsigned char uint8;9typedef signed short int16;10typedef signed int int32;11typedef unsigned short uint16;12typedef unsigned int uint32;13typedef unsigned int uint;1415// JPEG chroma subsampling factors. Y_ONLY (grayscale images) and H2V2 (color images) are the most common.16enum subsampling_t { Y_ONLY = 0, H1V1 = 1, H2V1 = 2, H2V2 = 3 };1718// JPEG compression parameters structure.19struct params20{21inline params() : m_quality(85), m_subsampling(H2V2), m_no_chroma_discrim_flag(false), m_two_pass_flag(false), m_use_std_tables(false) { }2223inline bool check() const24{25if ((m_quality < 1) || (m_quality > 100)) return false;26if ((uint)m_subsampling > (uint)H2V2) return false;27return true;28}2930// Quality: 1-100, higher is better. Typical values are around 50-95.31int m_quality;3233// m_subsampling:34// 0 = Y (grayscale) only35// 1 = YCbCr, no subsampling (H1V1, YCbCr 1x1x1, 3 blocks per MCU)36// 2 = YCbCr, H2V1 subsampling (YCbCr 2x1x1, 4 blocks per MCU)37// 3 = YCbCr, H2V2 subsampling (YCbCr 4x1x1, 6 blocks per MCU-- very common)38subsampling_t m_subsampling;3940// Disables CbCr discrimination - only intended for testing.41// If true, the Y quantization table is also used for the CbCr channels.42bool m_no_chroma_discrim_flag;4344bool m_two_pass_flag;4546// By default we use the same quantization tables as mozjpeg's default.47// Set to true to use the traditional tables from JPEG Annex K.48bool m_use_std_tables;49};5051// Writes JPEG image to a file.52// num_channels must be 1 (Y) or 3 (RGB), image pitch must be width*num_channels.53bool compress_image_to_jpeg_file(const char* pFilename, int width, int height, int num_channels, const uint8* pImage_data, const params& comp_params = params());5455// Writes JPEG image to memory buffer.56// On entry, buf_size is the size of the output buffer pointed at by pBuf, which should be at least ~1024 bytes.57// If return value is true, buf_size will be set to the size of the compressed data.58bool compress_image_to_jpeg_file_in_memory(void* pBuf, int& buf_size, int width, int height, int num_channels, const uint8* pImage_data, const params& comp_params = params());5960// Output stream abstract class - used by the jpeg_encoder class to write to the output stream.61// put_buf() is generally called with len==JPGE_OUT_BUF_SIZE bytes, but for headers it'll be called with smaller amounts.62class output_stream63{64public:65virtual ~output_stream() { };66virtual bool put_buf(const void* Pbuf, int len) = 0;67template<class T> inline bool put_obj(const T& obj) { return put_buf(&obj, sizeof(T)); }68};6970// Lower level jpeg_encoder class - useful if more control is needed than the above helper functions.71class jpeg_encoder72{73public:74jpeg_encoder();75~jpeg_encoder();7677// Initializes the compressor.78// pStream: The stream object to use for writing compressed data.79// params - Compression parameters structure, defined above.80// width, height - Image dimensions.81// channels - May be 1, or 3. 1 indicates grayscale, 3 indicates RGB source data.82// Returns false on out of memory or if a stream write fails.83bool init(output_stream* pStream, int width, int height, int src_channels, const params& comp_params = params());8485const params& get_params() const { return m_params; }8687// Deinitializes the compressor, freeing any allocated memory. May be called at any time.88void deinit();8990uint get_total_passes() const { return m_params.m_two_pass_flag ? 2 : 1; }91inline uint get_cur_pass() { return m_pass_num; }9293// Call this method with each source scanline.94// width * src_channels bytes per scanline is expected (RGB or Y format).95// You must call with NULL after all scanlines are processed to finish compression.96// Returns false on out of memory or if a stream write fails.97bool process_scanline(const void* pScanline);9899private:100jpeg_encoder(const jpeg_encoder&);101jpeg_encoder& operator =(const jpeg_encoder&);102103typedef int32 sample_array_t;104105output_stream* m_pStream;106params m_params;107uint8 m_num_components;108uint8 m_comp_h_samp[3], m_comp_v_samp[3];109int m_image_x, m_image_y, m_image_bpp, m_image_bpl;110int m_image_x_mcu, m_image_y_mcu;111int m_image_bpl_xlt, m_image_bpl_mcu;112int m_mcus_per_row;113int m_mcu_x, m_mcu_y;114uint8* m_mcu_lines[16];115uint8 m_mcu_y_ofs;116sample_array_t m_sample_array[64];117int16 m_coefficient_array[64];118int32 m_quantization_tables[2][64];119uint m_huff_codes[4][256];120uint8 m_huff_code_sizes[4][256];121uint8 m_huff_bits[4][17];122uint8 m_huff_val[4][256];123uint32 m_huff_count[4][256];124int m_last_dc_val[3];125enum { JPGE_OUT_BUF_SIZE = 2048 };126uint8 m_out_buf[JPGE_OUT_BUF_SIZE];127uint8* m_pOut_buf;128uint m_out_buf_left;129uint32 m_bit_buffer;130uint m_bits_in;131uint8 m_pass_num;132bool m_all_stream_writes_succeeded;133134void optimize_huffman_table(int table_num, int table_len);135void emit_byte(uint8 i);136void emit_word(uint i);137void emit_marker(int marker);138void emit_jfif_app0();139void emit_dqt();140void emit_sof();141void emit_dht(uint8* bits, uint8* val, int index, bool ac_flag);142void emit_dhts();143void emit_sos();144void emit_markers();145void compute_huffman_table(uint* codes, uint8* code_sizes, uint8* bits, uint8* val);146void compute_quant_table(int32* dst, int16* src);147void adjust_quant_table(int32* dst, int32* src);148void first_pass_init();149bool second_pass_init();150bool jpg_open(int p_x_res, int p_y_res, int src_channels);151void load_block_8_8_grey(int x);152void load_block_8_8(int x, int y, int c);153void load_block_16_8(int x, int c);154void load_block_16_8_8(int x, int c);155void load_quantized_coefficients(int component_num);156void flush_output_buffer();157void put_bits(uint bits, uint len);158void code_coefficients_pass_one(int component_num);159void code_coefficients_pass_two(int component_num);160void code_block(int component_num);161void process_mcu_row();162bool terminate_pass_one();163bool terminate_pass_two();164bool process_end_of_image();165void load_mcu(const void* src);166void clear();167void init();168};169170} // namespace jpge171172#endif // JPEG_ENCODER173174175