const JPEG_COMPRESS: &str = r#"
vec3 fx_ycc(vec3 c) {
return vec3(dot(c, vec3(0.299, 0.587, 0.114)),
dot(c, vec3(-0.168736, -0.331264, 0.5)) + 0.5,
dot(c, vec3(0.5, -0.418688, -0.081312)) + 0.5);
}
vec3 fx_rgb(vec3 y) {
float cb = y.y - 0.5;
float cr = y.z - 0.5;
return vec3(y.x + 1.402 * cr, y.x - 0.344136 * cb - 0.714136 * cr, y.x + 1.772 * cb);
}
void main() {
vec2 uv = gl_FragCoord.xy / u_res;
vec4 src = texture(tex, uv);
float sc = max(u_scale, 0.05);
float b = max(p1, 2.0) * sc;
vec2 org = floor(gl_FragCoord.xy / b) * b;
vec3 dc = texture(tex, (org + b * vec2(0.25, 0.25)) / u_res).rgb
+ texture(tex, (org + b * vec2(0.75, 0.25)) / u_res).rgb
+ texture(tex, (org + b * vec2(0.25, 0.75)) / u_res).rgb
+ texture(tex, (org + b * vec2(0.75, 0.75)) / u_res).rgb;
dc *= 0.25;
float q = clamp(p0, 1.0, 100.0);
float qs = q < 50.0 ? 50.0 / q : 2.0 - q / 50.0;
float step_ = clamp(qs * 0.05, 0.004, 0.6);
vec3 ydc = fx_ycc(dc);
vec3 ypx = fx_ycc(src.rgb);
float dcs = step_ * 0.5;
float luma = floor(ydc.x / dcs + 0.5) * dcs + floor((ypx.x - ydc.x) / step_ + 0.5) * step_;
vec2 ch = ypx.yz;
if (p2 >= 0.5) {
vec2 sub = (floor(gl_FragCoord.xy / (2.0 * sc)) + 0.5) * (2.0 * sc);
ch = fx_ycc(texture(tex, sub / u_res).rgb).yz;
}
float cstep = step_ * 2.0;
ch = floor((ch - 0.5) / cstep + 0.5) * cstep + 0.5;
vec4 res = vec4(clamp(fx_rgb(vec3(luma, ch)), 0.0, 1.0), src.a);
float m = u_has_mask > 0.5 ? texture(u_mask, uv).r : 1.0;
out_color = mix(src, res, m);
}
"#;Expand description
JPEG-ish: the block DC (4 taps) is quantised coarsely, the AC residual more coarsely still, and the
chroma optionally read from a 2x2 grid (4:2:0). This is an approximation - there is no DCT here,
but the visible artefacts (blocking, colour smear, banding) track Quality the same way.