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