-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmozjpeg.c
148 lines (124 loc) · 3.51 KB
/
mozjpeg.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "custom_libc.h"
#include "stdlib.h"
#include "stddef.h"
#include "cdjpeg.h"
#include "jpeglib.h"
#include <stdbool.h>
#include <inttypes.h>
#include <emscripten.h>
void fail(char *msg)
{
fprintf(stderr, "fail: %s", msg);
exit(1);
}
FILE *const stdout = (FILE *)1;
FILE *const stderr = (FILE *)2;
FILE *const outImgFile = (FILE *)10042;
struct jpeg_error_mgr jerr;
struct jpeg_compress_struct cinfo;
uint8_t *in_row_buffer;
EMSCRIPTEN_KEEPALIVE
void *init_compress(int width, int height, int in_color_space, int channels)
{
free_everything();
memset(&jerr, 0, sizeof(jerr));
memset(&cinfo, 0, sizeof(cinfo));
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
// jpeg_mem_dest(&cinfo, &result, &length);
jpeg_stdio_dest(&cinfo, outImgFile);
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = channels;
cinfo.in_color_space = in_color_space;
jpeg_set_defaults(&cinfo);
return in_row_buffer = malloc(width * channels);
}
EMSCRIPTEN_KEEPALIVE
void cinfo_set_out_color_space(int value)
{
jpeg_set_colorspace(&cinfo, value);
}
EMSCRIPTEN_KEEPALIVE
void cinfo_set_quant_table(int value)
{
jpeg_c_set_int_param(&cinfo, JINT_BASE_QUANT_TBL_IDX, value);
}
EMSCRIPTEN_KEEPALIVE
void cinfo_set_optimize_coding(bool value)
{
cinfo.optimize_coding = value;
}
// EMSCRIPTEN_KEEPALIVE
// void cinfo_set_arithmetic(bool value) {
// cinfo.arith_code = value;
// }
EMSCRIPTEN_KEEPALIVE
void cinfo_set_smoothing_factor(int value)
{
cinfo.smoothing_factor = value;
}
EMSCRIPTEN_KEEPALIVE
void cinfo_set_trellis(int num_loops, bool use_multipass, bool optimize_zero_blocks, bool optimize_table)
{
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_USE_SCANS_IN_TRELLIS, use_multipass);
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_EOB_OPT, optimize_zero_blocks);
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_Q_OPT, optimize_table);
jpeg_c_set_int_param(&cinfo, JINT_TRELLIS_NUM_LOOPS, num_loops);
}
EMSCRIPTEN_KEEPALIVE
void cinfo_set_channel_samp_factor(int component, int h_samp_factor, int v_samp_factor)
{
cinfo.comp_info[component].h_samp_factor = h_samp_factor;
cinfo.comp_info[component].v_samp_factor = v_samp_factor;
}
EMSCRIPTEN_KEEPALIVE
void cinfo_set_chroma_subsample(int h_samp_factor, int v_samp_factor)
{
cinfo_set_channel_samp_factor(0, h_samp_factor, v_samp_factor);
}
EMSCRIPTEN_KEEPALIVE
void cinfo_set_quality(int luma_quality, int chroma_quality)
{
if (luma_quality < 0 || luma_quality > 100)
fail("wrong quality value");
if (chroma_quality > 100)
fail("wrong quality value");
if (chroma_quality < 0)
chroma_quality = luma_quality;
set_quality_ratings_simple(&cinfo, luma_quality, chroma_quality, /* baseline */ TRUE);
// Disabling subsampling when high-quality color is desired.
// See set_quality_ratings in rdswitch.c
if (chroma_quality >= 90) {
cinfo_set_chroma_subsample(1, 1);
} else if (chroma_quality >= 80) {
cinfo_set_chroma_subsample(2, 1);
}
}
EMSCRIPTEN_KEEPALIVE
void cinfo_disable_progression()
{
// enabled by default (cinfo->master->compress_profile == JCP_MAX_COMPRESSION)
// jpeg_simple_progression(&cinfo);
cinfo.num_scans = 0;
cinfo.scan_info = NULL;
}
EMSCRIPTEN_KEEPALIVE
void start_compress()
{
jpeg_start_compress(&cinfo, TRUE);
}
EMSCRIPTEN_KEEPALIVE
bool write_scanlines()
{
JSAMPROW row_pointer[1] = {in_row_buffer};
jpeg_write_scanlines(&cinfo, row_pointer, 1);
return cinfo.next_scanline >= cinfo.image_height;
}
EMSCRIPTEN_KEEPALIVE
void finish_compress()
{
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
free_everything();
}