CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/ext/jpge/jpge.h
Views: 1401
1
// jpge.h - C++ class for JPEG compression.
2
// Public Domain or Apache 2.0, Richard Geldreich <[email protected]>
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
{
22
inline params() : m_quality(85), m_subsampling(H2V2), m_no_chroma_discrim_flag(false), m_two_pass_flag(false), m_use_std_tables(false) { }
23
24
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
// By default we use the same quantization tables as mozjpeg's default.
48
// Set to true to use the traditional tables from JPEG Annex K.
49
bool m_use_std_tables;
50
};
51
52
// Writes JPEG image to a file.
53
// num_channels must be 1 (Y) or 3 (RGB), image pitch must be width*num_channels.
54
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());
55
56
// Writes JPEG image to memory buffer.
57
// On entry, buf_size is the size of the output buffer pointed at by pBuf, which should be at least ~1024 bytes.
58
// If return value is true, buf_size will be set to the size of the compressed data.
59
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());
60
61
// Output stream abstract class - used by the jpeg_encoder class to write to the output stream.
62
// put_buf() is generally called with len==JPGE_OUT_BUF_SIZE bytes, but for headers it'll be called with smaller amounts.
63
class output_stream
64
{
65
public:
66
virtual ~output_stream() { };
67
virtual bool put_buf(const void* Pbuf, int len) = 0;
68
template<class T> inline bool put_obj(const T& obj) { return put_buf(&obj, sizeof(T)); }
69
};
70
71
// Lower level jpeg_encoder class - useful if more control is needed than the above helper functions.
72
class jpeg_encoder
73
{
74
public:
75
jpeg_encoder();
76
~jpeg_encoder();
77
78
// Initializes the compressor.
79
// pStream: The stream object to use for writing compressed data.
80
// params - Compression parameters structure, defined above.
81
// width, height - Image dimensions.
82
// channels - May be 1, or 3. 1 indicates grayscale, 3 indicates RGB source data.
83
// Returns false on out of memory or if a stream write fails.
84
bool init(output_stream* pStream, int width, int height, int src_channels, const params& comp_params = params());
85
86
const params& get_params() const { return m_params; }
87
88
// Deinitializes the compressor, freeing any allocated memory. May be called at any time.
89
void deinit();
90
91
uint get_total_passes() const { return m_params.m_two_pass_flag ? 2 : 1; }
92
inline uint get_cur_pass() { return m_pass_num; }
93
94
// Call this method with each source scanline.
95
// width * src_channels bytes per scanline is expected (RGB or Y format).
96
// You must call with NULL after all scanlines are processed to finish compression.
97
// Returns false on out of memory or if a stream write fails.
98
bool process_scanline(const void* pScanline);
99
100
private:
101
jpeg_encoder(const jpeg_encoder&);
102
jpeg_encoder& operator =(const jpeg_encoder&);
103
104
typedef int32 sample_array_t;
105
106
output_stream* m_pStream;
107
params m_params;
108
uint8 m_num_components;
109
uint8 m_comp_h_samp[3], m_comp_v_samp[3];
110
int m_image_x, m_image_y, m_image_bpp, m_image_bpl;
111
int m_image_x_mcu, m_image_y_mcu;
112
int m_image_bpl_xlt, m_image_bpl_mcu;
113
int m_mcus_per_row;
114
int m_mcu_x, m_mcu_y;
115
uint8* m_mcu_lines[16];
116
uint8 m_mcu_y_ofs;
117
sample_array_t m_sample_array[64];
118
int16 m_coefficient_array[64];
119
int32 m_quantization_tables[2][64];
120
uint m_huff_codes[4][256];
121
uint8 m_huff_code_sizes[4][256];
122
uint8 m_huff_bits[4][17];
123
uint8 m_huff_val[4][256];
124
uint32 m_huff_count[4][256];
125
int m_last_dc_val[3];
126
enum { JPGE_OUT_BUF_SIZE = 2048 };
127
uint8 m_out_buf[JPGE_OUT_BUF_SIZE];
128
uint8* m_pOut_buf;
129
uint m_out_buf_left;
130
uint32 m_bit_buffer;
131
uint m_bits_in;
132
uint8 m_pass_num;
133
bool m_all_stream_writes_succeeded;
134
135
void optimize_huffman_table(int table_num, int table_len);
136
void emit_byte(uint8 i);
137
void emit_word(uint i);
138
void emit_marker(int marker);
139
void emit_jfif_app0();
140
void emit_dqt();
141
void emit_sof();
142
void emit_dht(uint8* bits, uint8* val, int index, bool ac_flag);
143
void emit_dhts();
144
void emit_sos();
145
void emit_markers();
146
void compute_huffman_table(uint* codes, uint8* code_sizes, uint8* bits, uint8* val);
147
void compute_quant_table(int32* dst, int16* src);
148
void adjust_quant_table(int32* dst, int32* src);
149
void first_pass_init();
150
bool second_pass_init();
151
bool jpg_open(int p_x_res, int p_y_res, int src_channels);
152
void load_block_8_8_grey(int x);
153
void load_block_8_8(int x, int y, int c);
154
void load_block_16_8(int x, int c);
155
void load_block_16_8_8(int x, int c);
156
void load_quantized_coefficients(int component_num);
157
void flush_output_buffer();
158
void put_bits(uint bits, uint len);
159
void code_coefficients_pass_one(int component_num);
160
void code_coefficients_pass_two(int component_num);
161
void code_block(int component_num);
162
void process_mcu_row();
163
bool terminate_pass_one();
164
bool terminate_pass_two();
165
bool process_end_of_image();
166
void load_mcu(const void* src);
167
void clear();
168
void init();
169
};
170
171
} // namespace jpge
172
173
#endif // JPEG_ENCODER
174
175