Here's the HSL one with gamma correction (you can adjust the gamma curve for the image, and for the S/M/H separately):
Code:
// Shadow/midtone/highlight hue/saturation/luminance adjust
//@param 1:fade 'fade' 1
//@param 2:gamma 'gamma correct' 1 .1 4 1 .01
//@param 3:h.shadow 'shadow hue' 0 -360 360 0 1
//@param 4:s.shadow 'shadow saturation' 1 0 8 1 .01
//@param 5:y.shadow 'shadow luminance' 0 -256 256 0 1
//@param 6:h.midtone 'midtone hue' 0 -360 360 0 1
//@param 7:s.midtone 'midtone saturation' 1 0 8 1 .01
//@param 8:y.midtone 'midtone luminance' 0 -256 256 0 1
//@param 9:h.highlight 'highlight hue' 0 -360 360 0 1
//@param 10:s.highlight 'highlight saturation'1 0 8 1 .01
//@param 11:y.highlight 'highlight luminance' 0 -256 256 0 1
//@param 12:showc 'show curves' 0 0 1 0.5 1
//@param 13:cgamma 'curve gamma' 1 .1 4 1 .01
//@param 14:shadow_curve 'shadow steepness' 1 0 8 1 .01
//@param 15:midtone_curve 'midtone steepness' 1 .125 8 1 .01
//@param 16:highlight_curve 'highlight steepness' 1 0 8 1 .01
function scurve(i) local(t) (
i^=cgamma;
t = (cos(i*$pi)*.5+.5)^shadow_curve;
shadow_curve < 1 ? shadow_curve*t + (1-i)*(1-shadow_curve): t;
);
function hcurve(i) (
i^=cgamma;
t = (cos((1-i)*$pi)*.5+.5)^highlight_curve;
highlight_curve < 1 ? highlight_curve*t + i*(1-highlight_curve): t;
);
function mcurve(i) ( sin((i^cgamma)*$pi)^midtone_curve );
fade > 0 || showc ? (
input_info(0,project_w,project_h);
gfx_blit(0);
fade > 0 ? (
i = vv = 0;
colorspace='YV12';
loop(256,
v = min(max((vv-16)/224,0),1);
i[0] = fade * (scurve(v)*y.shadow + mcurve(v)*y.midtone + hcurve(v)*y.highlight);
i[1] = sat = 1 + fade*(
(1 + scurve(v) * (s.shadow - 1)) *
(1 + mcurve(v) * (s.midtone - 1)) *
(1 + hcurve(v) * (s.highlight - 1)) - 1);
ang = (scurve(v)*h.shadow + mcurve(v)*h.midtone + hcurve(v)*h.highlight) * $pi/180 * fade;
i[2] = cos(ang)*sat;
i[3] = sin(ang)*sat;
i+=4;
vv[1024] = 256 * (vv/256)^gamma;
vv+=1;
);
#code = "";
h.shadow || h.midtone || h.highlight ? (
#code += "
_1=((y1+y2+y3+y4)&-4);
u=min(max((_4=(u-128))*(_2=_1[2])+(v-128)*(_3=_1[3])+128,0),255);
v=min(max((v-128)*_2-_4*_3+128,0),255);
";
) : s.shadow!=1 || s.midtone!=1 || s.highlight!=1 ? (
#code += "
_3=((y1+y2+y3+y4)&-4)[1];
u=min(max((u-128)*_3+128,0),255);
v=min(max((v-128)*_3+128,0),255);
";
);
gstr = gamma != 1.0 ? "[1024]" : "";
y.shadow || y.midtone || y.highlight ? #code += sprintf(#,
"y1 = min(max(y1%s+(y1*4)[],0),255);
y2 = min(max(y2%s+(y2*4)[],0),255);
y3 = min(max(y3%s+(y3*4)[],0),255);
y4 = min(max(y4%s+(y4*4)[],0),255);",gstr,gstr,gstr,gstr) :
gamma!=1.0 ? #code += "y1 = y1[1024]; y2=y2[1024]; y3=y3[1024]; y4=y4[1024];";
gfx_evalrect(0,0,project_w,project_h,#code);
);
showc ? (
x = 32; y = 32;
ysz = 200;
gfx_set(0,0,0,0.85);
gfx_fillrect(x,y,512,ysz);
gfx_set(.75);
gfx_a=0.4;
i=0; loop(256, v=ysz*scurve(i/256); gfx_fillrect(x+i*2,y+ysz-v,2,v); i+=1; );
i=0; loop(256, v=ysz*mcurve(i/256); gfx_fillrect(x+i*2,y+ysz-v,2,v); i+=1; );
i=0; loop(256, v=ysz*hcurve(i/256); gfx_fillrect(x+i*2,y+ysz-v,2,v); i+=1; );
);
);