1 // jpge.h - C++ class for JPEG compression. 2 // Public domain, Rich Geldreich <richgel99@gmail.com> 3 // Alex Evans: Added RGBA support, linear memory allocator. 4 #ifndef JPEG_ENCODER_H 5 #define JPEG_ENCODER_H 6 7 namespace jpge 8 { 9 typedef unsigned char uint8; 10 typedef signed short int16; 11 typedef signed int int32; 12 typedef unsigned short uint16; 13 typedef unsigned int uint32; 14 typedef unsigned int uint; 15 16 // JPEG chroma subsampling factors. Y_ONLY (grayscale images) and H2V2 (color images) are the most common. 17 enum subsampling_t { Y_ONLY = 0, H1V1 = 1, H2V1 = 2, H2V2 = 3 }; 18 19 // JPEG compression parameters structure. 20 struct params 21 { paramsparams22 inline params() : m_quality(85), m_subsampling(H2V2), m_no_chroma_discrim_flag(false), m_two_pass_flag(false) { } 23 checkparams24 inline bool check() const 25 { 26 if ((m_quality < 1) || (m_quality > 100)) return false; 27 if ((uint)m_subsampling > (uint)H2V2) return false; 28 return true; 29 } 30 31 // Quality: 1-100, higher is better. Typical values are around 50-95. 32 int m_quality; 33 34 // m_subsampling: 35 // 0 = Y (grayscale) only 36 // 1 = YCbCr, no subsampling (H1V1, YCbCr 1x1x1, 3 blocks per MCU) 37 // 2 = YCbCr, H2V1 subsampling (YCbCr 2x1x1, 4 blocks per MCU) 38 // 3 = YCbCr, H2V2 subsampling (YCbCr 4x1x1, 6 blocks per MCU-- very common) 39 subsampling_t m_subsampling; 40 41 // Disables CbCr discrimination - only intended for testing. 42 // If true, the Y quantization table is also used for the CbCr channels. 43 bool m_no_chroma_discrim_flag; 44 45 bool m_two_pass_flag; 46 }; 47 48 // Writes JPEG image to a file. 49 // num_channels must be 1 (Y) or 3 (RGB), image pitch must be width*num_channels. 50 bool compress_image_to_jpeg_file(const char *pFilename, int width, int height, int num_channels, const uint8 *pImage_data, const params &comp_params = params()); 51 52 // Writes JPEG image to memory buffer. 53 // On entry, buf_size is the size of the output buffer pointed at by pBuf, which should be at least ~1024 bytes. 54 // If return value is true, buf_size will be set to the size of the compressed data. 55 bool 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()); 56 57 // Output stream abstract class - used by the jpeg_encoder class to write to the output stream. 58 // put_buf() is generally called with len==JPGE_OUT_BUF_SIZE bytes, but for headers it'll be called with smaller amounts. 59 class output_stream 60 { 61 public: ~output_stream()62 virtual ~output_stream() { }; 63 virtual bool put_buf(const void* Pbuf, int len) = 0; put_obj(const T & obj)64 template<class T> inline bool put_obj(const T& obj) { return put_buf(&obj, sizeof(T)); } 65 }; 66 67 // Lower level jpeg_encoder class - useful if more control is needed than the above helper functions. 68 class jpeg_encoder 69 { 70 public: 71 jpeg_encoder(); 72 ~jpeg_encoder(); 73 74 // Initializes the compressor. 75 // pStream: The stream object to use for writing compressed data. 76 // params - Compression parameters structure, defined above. 77 // width, height - Image dimensions. 78 // channels - May be 1, or 3. 1 indicates grayscale, 3 indicates RGB source data. 79 // Returns false on out of memory or if a stream write fails. 80 bool init(output_stream *pStream, int width, int height, int src_channels, const params &comp_params = params()); 81 get_params()82 const params &get_params() const { return m_params; } 83 84 // Deinitializes the compressor, freeing any allocated memory. May be called at any time. 85 void deinit(); 86 get_total_passes()87 uint get_total_passes() const { return m_params.m_two_pass_flag ? 2 : 1; } get_cur_pass()88 inline uint get_cur_pass() { return m_pass_num; } 89 90 // Call this method with each source scanline. 91 // width * src_channels bytes per scanline is expected (RGB or Y format). 92 // You must call with NULL after all scanlines are processed to finish compression. 93 // Returns false on out of memory or if a stream write fails. 94 bool process_scanline(const void* pScanline); 95 96 private: 97 jpeg_encoder(const jpeg_encoder &); 98 jpeg_encoder &operator =(const jpeg_encoder &); 99 100 typedef int32 sample_array_t; 101 102 output_stream *m_pStream; 103 params m_params; 104 uint8 m_num_components; 105 uint8 m_comp_h_samp[3], m_comp_v_samp[3]; 106 int m_image_x, m_image_y, m_image_bpp, m_image_bpl; 107 int m_image_x_mcu, m_image_y_mcu; 108 int m_image_bpl_xlt, m_image_bpl_mcu; 109 int m_mcus_per_row; 110 int m_mcu_x, m_mcu_y; 111 uint8 *m_mcu_lines[16]; 112 uint8 m_mcu_y_ofs; 113 sample_array_t m_sample_array[64]; 114 int16 m_coefficient_array[64]; 115 int32 m_quantization_tables[2][64]; 116 uint m_huff_codes[4][256]; 117 uint8 m_huff_code_sizes[4][256]; 118 uint8 m_huff_bits[4][17]; 119 uint8 m_huff_val[4][256]; 120 uint32 m_huff_count[4][256]; 121 int m_last_dc_val[3]; 122 enum { JPGE_OUT_BUF_SIZE = 2048 }; 123 uint8 m_out_buf[JPGE_OUT_BUF_SIZE]; 124 uint8 *m_pOut_buf; 125 uint m_out_buf_left; 126 uint32 m_bit_buffer; 127 uint m_bits_in; 128 uint8 m_pass_num; 129 bool m_all_stream_writes_succeeded; 130 131 void optimize_huffman_table(int table_num, int table_len); 132 void emit_byte(uint8 i); 133 void emit_word(uint i); 134 void emit_marker(int marker); 135 void emit_jfif_app0(); 136 void emit_dqt(); 137 void emit_sof(); 138 void emit_dht(uint8 *bits, uint8 *val, int index, bool ac_flag); 139 void emit_dhts(); 140 void emit_sos(); 141 void emit_markers(); 142 void compute_huffman_table(uint *codes, uint8 *code_sizes, uint8 *bits, uint8 *val); 143 void compute_quant_table(int32 *dst, int16 *src); 144 void adjust_quant_table(int32 *dst, int32 *src); 145 void first_pass_init(); 146 bool second_pass_init(); 147 bool jpg_open(int p_x_res, int p_y_res, int src_channels); 148 void load_block_8_8_grey(int x); 149 void load_block_8_8(int x, int y, int c); 150 void load_block_16_8(int x, int c); 151 void load_block_16_8_8(int x, int c); 152 void load_quantized_coefficients(int component_num); 153 void flush_output_buffer(); 154 void put_bits(uint bits, uint len); 155 void code_coefficients_pass_one(int component_num); 156 void code_coefficients_pass_two(int component_num); 157 void code_block(int component_num); 158 void process_mcu_row(); 159 bool terminate_pass_one(); 160 bool terminate_pass_two(); 161 bool process_end_of_image(); 162 void load_mcu(const void* src); 163 void clear(); 164 void init(); 165 }; 166 167 } // namespace jpge 168 169 #endif // JPEG_ENCODER 170