f.refine.cc (fotoxx-22.41) | : | f.refine.cc (fotoxx-22.50) | ||
---|---|---|---|---|
skipping to change at line 35 | skipping to change at line 35 | |||
m_edit_dist edit brightness distribution, rebalance bright/dark a reas | m_edit_dist edit brightness distribution, rebalance bright/dark a reas | |||
m_flatten_dist flatten brightness distribution | m_flatten_dist flatten brightness distribution | |||
m_localcon increase local contrast | m_localcon increase local contrast | |||
m_gradients magnify brightness gradients to improve details | m_gradients magnify brightness gradients to improve details | |||
m_gretinex rescale pixel RGB brightness range - entire image | m_gretinex rescale pixel RGB brightness range - entire image | |||
m_lretinex rescale pixel RGB brightness range - within local are as | m_lretinex rescale pixel RGB brightness range - within local are as | |||
m_saturation adjust saturation based on pixel brightness | m_saturation adjust saturation based on pixel brightness | |||
m_soft_focus apply a soft focus effect to an image | m_soft_focus apply a soft focus effect to an image | |||
m_match_colors adjust image colors to match those in a chosen image | m_match_colors adjust image colors to match those in a chosen image | |||
m_brite_ramp adjust brightness gradually across the image | m_brite_ramp adjust brightness gradually across the image | |||
m_vignette highlight selected image region | ||||
******************************************************************************** */ | ******************************************************************************** */ | |||
#define EX extern // enable extern declarations | #define EX extern // enable extern declarations | |||
#include "fotoxx.h" // (variables in fotoxx.h are refs) | #include "fotoxx.h" // (variables in fotoxx.h are refs) | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// automatic image enhancement without user guidance | // automatic image enhancement without user guidance | |||
skipping to change at line 200 | skipping to change at line 201 | |||
float LF, MF, HF; // low, mid, high flatten parms | float LF, MF, HF; // low, mid, high flatten parms | |||
float LS, MS, HS; // low, mid, high stretch parms | float LS, MS, HS; // low, mid, high stretch parms | |||
float BB[1000]; // adjusted B for input B 0-999 | float BB[1000]; // adjusted B for input B 0-999 | |||
int dialog_event(zdialog* zd, cchar *event); | int dialog_event(zdialog* zd, cchar *event); | |||
void compute_BB(); | void compute_BB(); | |||
void * thread(void *); | void * thread(void *); | |||
void * wthread(void *); | void * wthread(void *); | |||
editfunc EFedit_dist; | editfunc EFedit_dist; | |||
char edit_hist[100]; | ||||
} | } | |||
// menu function | // menu function | |||
void m_edit_dist(GtkWidget *, cchar *menu) | void m_edit_dist(GtkWidget *, cchar *menu) | |||
{ | { | |||
using namespace edit_dist_names; | using namespace edit_dist_names; | |||
cchar *title = "Edit Brightness Distribution"; | cchar *title = "Edit Brightness Distribution"; | |||
skipping to change at line 4566 | skipping to change at line 4566 | |||
ey1 = ry; | ey1 = ry; | |||
} | } | |||
else { | else { | |||
ex2 = rx; | ex2 = rx; | |||
ey2 = ry; | ey2 = ry; | |||
} | } | |||
} | } | |||
return; | return; | |||
} | } | |||
/******************************************************************************* | ||||
* | ||||
Vignette function | ||||
1. Change the brightness from center to edge using a curve. | ||||
2. Change the color from center to edge using a color and a curve. | ||||
(the pixel varies between original RGB and selected color) | ||||
3. Mouse click or drag on image sets a new vignette center. | ||||
******************************************************************************** | ||||
*/ | ||||
void vign_mousefunc(); | ||||
editfunc EFvignette; | ||||
uint8 vignette_RGB[3] = { 0, 0, 255 }; | ||||
int vignette_spc; | ||||
float vign_cx, vign_cy; | ||||
float vign_rad; | ||||
void m_vignette(GtkWidget *, cchar *menu) | ||||
{ | ||||
int Vign_dialog_event(zdialog *zd, cchar *event); | ||||
void Vign_curvedit(int); | ||||
void * Vign_thread(void *); | ||||
cchar *title = "Vignette"; | ||||
F1_help_topic = "vignette"; | ||||
Plog(1,"m_vignette \n"); | ||||
EFvignette.menuname = "Vignette"; | ||||
EFvignette.Farea = 2; | ||||
// select area usable | ||||
EFvignette.FprevReq = 1; | ||||
// use preview image | ||||
EFvignette.threadfunc = Vign_thread; | ||||
// thread function | ||||
EFvignette.mousefunc = vign_mousefunc; | ||||
// mouse function | ||||
if (! edit_setup(EFvignette)) return; | ||||
// setup edit | ||||
/*** | ||||
___________________________________ | ||||
| _______________________________ | | ||||
| | | | | ||||
| | | | | ||||
| | curve drawing area | | | ||||
| | | | | ||||
| | | | | ||||
| |_______________________________| | | ||||
| center edge | | ||||
| | | ||||
| (o) Brightness (o) Color [___] | | ||||
| Curve File: [ Open ] [ Save ] | | ||||
| | | ||||
| [ OK ] [Cancel] | | ||||
|___________________________________| | ||||
***/ | ||||
zdialog *zd = zdialog_new(title,Mwin,"OK","Cancel",null); | ||||
EFvignette.zd = zd; | ||||
zdialog_add_widget(zd,"frame","frame","dialog",0,"expand"); | ||||
zdialog_add_widget(zd,"hbox","hb1","dialog",0,"space=3"); | ||||
zdialog_add_widget(zd,"label","labcenter","hb1","Center","space=4"); | ||||
zdialog_add_widget(zd,"label","space","hb1",0,"expand"); | ||||
zdialog_add_widget(zd,"label","labedge","hb1","Edge","space=5"); | ||||
zdialog_add_widget(zd,"hbox","hb2","dialog",0,"space=3"); | ||||
zdialog_add_widget(zd,"radio","RBbrite","hb2","Brightness","space=5"); | ||||
zdialog_add_widget(zd,"radio","RBcolor","hb2","Color","space=5"); | ||||
zdialog_add_widget(zd,"colorbutt","color","hb2","0|0|255"); | ||||
zdialog_add_widget(zd,"hbox","hb3","dialog",0,"space=5"); | ||||
zdialog_add_widget(zd,"label","labcurve","hb3","Curve File","space=5"); | ||||
zdialog_add_widget(zd,"button","load","hb3","Open","space=5"); | ||||
zdialog_add_widget(zd,"button","save","hb3","Save","space=5"); | ||||
vignette_RGB[0] = vignette_RGB[1] = 0; | ||||
// initial color = blue | ||||
vignette_RGB[2] = 255; | ||||
vign_cx = E3pxm->ww / 2; | ||||
// initial vignette center | ||||
vign_cy = E3pxm->hh / 2; | ||||
vign_rad = vign_cx * vign_cx + vign_cy * vign_cy; | ||||
// radius = distance to corners | ||||
vign_rad = sqrtf(vign_rad); | ||||
zdialog_stuff(zd,"RBbrite",1); | ||||
// default curve = brightness | ||||
GtkWidget *frame = zdialog_gtkwidget(zd,"frame"); | ||||
// set up curve edit | ||||
spldat *sd = splcurve_init(frame,Vign_curvedit); | ||||
EFvignette.sd = sd; | ||||
sd->Nspc = 2; | ||||
// 2 curves | ||||
sd->vert[0] = 0; | ||||
// curve 0 = brightness curve | ||||
sd->nap[0] = 2; | ||||
sd->apx[0][0] = 0.01; | ||||
sd->apy[0][0] = 0.5; | ||||
sd->apx[0][1] = 0.99; | ||||
sd->apy[0][1] = 0.5; | ||||
splcurve_generate(sd,0); | ||||
sd->vert[1] = 0; | ||||
// curve 1 = color curve | ||||
sd->nap[1] = 2; | ||||
sd->apx[1][0] = 0.01; | ||||
sd->apy[1][0] = 0.01; | ||||
sd->apx[1][1] = 0.99; | ||||
sd->apy[1][1] = 0.01; | ||||
splcurve_generate(sd,1); | ||||
vignette_spc = 0; | ||||
// initial curve = brightness | ||||
sd->fact[0] = 1; | ||||
sd->fact[1] = 0; | ||||
zdialog_run(zd,Vign_dialog_event,"save"); | ||||
// run dialog - parallel | ||||
takeMouse(vign_mousefunc,dragcursor); | ||||
// connect mouse function | ||||
return; | ||||
} | ||||
// dialog event and completion callback function | ||||
int Vign_dialog_event(zdialog *zd, cchar *event) | ||||
{ | ||||
void Vign_curvedit(int); | ||||
spldat *sd = EFvignette.sd; | ||||
int ii; | ||||
char color[20]; | ||||
char *file, *pp; | ||||
cchar *ppc; | ||||
FILE *fid; | ||||
if (strmatch(event,"escape")) zd->zstat = -2; | ||||
// escape key | ||||
if (strmatch(event,"done")) zd->zstat = 1; | ||||
// from edit_setup() or f_save() | ||||
if (strmatch(event,"cancel")) zd->zstat = 2; | ||||
// from f_open() | ||||
if (strmatch(event,"fullsize")) { | ||||
// from select area | ||||
edit_fullsize(); | ||||
thread_signal(); | ||||
return 1; | ||||
} | ||||
if (zd->zstat) | ||||
{ | ||||
if (zd->zstat == 1) { | ||||
// done | ||||
thread_wait(); | ||||
// insure thread done | ||||
float R = 1.0 * E0pxm->ww / E3pxm->ww; | ||||
vign_cx = R * vign_cx; | ||||
// scale geometries to full size | ||||
vign_cy = R * vign_cy; | ||||
vign_rad = R * vign_rad; | ||||
edit_fullsize(); | ||||
// get full size image | ||||
thread_signal(); | ||||
edit_done(0); | ||||
// commit edit | ||||
} | ||||
else edit_cancel(0); | ||||
// discard edit | ||||
return 1; | ||||
} | ||||
if (strmatch(event,"focus")) | ||||
// toggle mouse capture | ||||
takeMouse(vign_mousefunc,dragcursor); | ||||
// connect mouse function | ||||
if (strmatchN(event,"RB",2)) { | ||||
// new choice of curve | ||||
sd->fact[0] = sd->fact[1] = 0; | ||||
ii = strmatchV(event,"RBbrite","RBcolor",null); | ||||
vignette_spc = ii = ii - 1; | ||||
sd->fact[ii] = 1; | ||||
// active curve | ||||
splcurve_generate(sd,ii); | ||||
// regenerate curve | ||||
gtk_widget_queue_draw(sd->drawarea); | ||||
// draw curve | ||||
thread_signal(); | ||||
} | ||||
if (strmatch(event,"blendwidth")) thread_signal(); | ||||
if (strmatch(event,"color")) { | ||||
// change color | ||||
zdialog_fetch(zd,"color",color,19); | ||||
// get color from color wheel | ||||
ppc = substring(color,"|",1); | ||||
if (ppc) vignette_RGB[0] = atoi(ppc); | ||||
ppc = substring(color,"|",2); | ||||
if (ppc) vignette_RGB[1] = atoi(ppc); | ||||
ppc = substring(color,"|",3); | ||||
if (ppc) vignette_RGB[2] = atoi(ppc); | ||||
thread_signal(); | ||||
// trigger update thread | ||||
} | ||||
if (strmatch(event,"load")) | ||||
// load saved curve | ||||
{ | ||||
file = zgetfile("load curve from a file",MWIN,"file",saved_curves_folder); | ||||
if (! file) return 1; | ||||
fid = fopen(file,"r"); | ||||
zfree(file); | ||||
if (! fid) return 1; | ||||
splcurve_load(sd,fid); | ||||
fclose(fid); | ||||
Vign_curvedit(0); | ||||
thread_signal(); | ||||
return 1; | ||||
} | ||||
if (strmatch(event,"save")) | ||||
// save curve to file | ||||
{ | ||||
file = zgetfile("save curve to a file",MWIN,"save",saved_curves_folder); | ||||
if (! file) return 1; | ||||
pp = zstrdup(file,"vignette",8); | ||||
zfree(file); | ||||
file = pp; | ||||
pp = strrchr(file,'/'); | ||||
// force .curve extension | ||||
if (pp) pp = strrchr(pp,'.'); | ||||
if (pp) strcpy(pp,".curve"); | ||||
else strcat(file,".curve"); | ||||
fid = fopen(file,"w"); | ||||
zfree(file); | ||||
if (! fid) return 1; | ||||
splcurve_save(sd,fid); | ||||
fclose(fid); | ||||
return 1; | ||||
} | ||||
return 1; | ||||
} | ||||
// get mouse position and set new center for vignette | ||||
void vign_mousefunc() | ||||
// mouse function | ||||
{ | ||||
if (! LMclick && ! Mdrag) return; | ||||
LMclick = 0; | ||||
vign_cx = Mxposn; | ||||
// new vignette center = mouse position | ||||
vign_cy = Myposn; | ||||
Mxdrag = Mydrag = 0; | ||||
thread_signal(); | ||||
// trigger image update | ||||
return; | ||||
} | ||||
// this function is called when the curve is edited | ||||
void Vign_curvedit(int) | ||||
{ | ||||
thread_signal(); | ||||
// update image | ||||
return; | ||||
} | ||||
// thread function | ||||
void * Vign_thread(void *) | ||||
{ | ||||
void * Vign_wthread(void *arg); | ||||
do_wthreads(Vign_wthread,NWT); | ||||
// worker threads | ||||
CEF->Fmods++; | ||||
CEF->Fsaved = 0; | ||||
Fpaint2(); | ||||
return 0; | ||||
} | ||||
// working thread | ||||
void * Vign_wthread(void *arg) | ||||
{ | ||||
float *pix1, *pix3; | ||||
int index, ii, kk, px, py, dist = 0; | ||||
float cx, cy, rad, radx, rady, f1, f2, xval, yval; | ||||
float R1, G1, B1, R3, G3, B3; | ||||
float max$; | ||||
spldat *sd = EFvignette.sd; | ||||
cx = vign_cx; | ||||
// vignette center (mouse) | ||||
cy = vign_cy; | ||||
index = *((int *) arg); | ||||
for (py = index; py < E3pxm->hh; py += NWT) | ||||
// loop all image pixels | ||||
for (px = 0; px < E3pxm->ww; px++) | ||||
{ | ||||
ii = py * E3pxm->ww + px; | ||||
if (sa_stat == 3) { | ||||
// select area active | ||||
dist = sa_pixmap[ii]; | ||||
// distance from edge | ||||
if (! dist) continue; | ||||
// pixel is outside area | ||||
} | ||||
pix1 = PXMpix(E1pxm,px,py); | ||||
// input pixel | ||||
pix3 = PXMpix(E3pxm,px,py); | ||||
// output pixel | ||||
R1 = pix1[0]; | ||||
// input RGB | ||||
G1 = pix1[1]; | ||||
B1 = pix1[2]; | ||||
radx = px - cx; | ||||
// distance from vignette center | ||||
rady = py - cy; | ||||
rad = sqrtf(radx*radx + rady*rady); | ||||
// (px,py) distance from center | ||||
xval = rad / vign_rad; | ||||
// scale 0 to 1.0 | ||||
kk = 999.0 * xval; | ||||
// scale 0 to 999 | ||||
if (kk > 999) kk = 999; | ||||
// beyond radius | ||||
yval = sd->yval[0][kk]; | ||||
// brightness curve y-value 0 to 1.0 | ||||
if (yval > 1.0) yval = 1.0; | ||||
yval = 2.0 * yval; | ||||
// 0 to 2.0 | ||||
R3 = yval * R1; | ||||
// adjust brightness | ||||
G3 = yval * G1; | ||||
B3 = yval * B1; | ||||
yval = sd->yval[1][kk]; | ||||
// color curve y-value 0 to 1.0 | ||||
if (yval > 1.0) yval = 1.0; | ||||
f1 = yval; | ||||
// 0 to 1.0 new color | ||||
f2 = 1.0 - f1; | ||||
// 1.0 to 0 old color | ||||
R3 = f1 * vignette_RGB[0] + f2 * R3; | ||||
// mix input and vignette color | ||||
G3 = f1 * vignette_RGB[1] + f2 * G3; | ||||
B3 = f1 * vignette_RGB[2] + f2 * B3; | ||||
if (sa_stat == 3 && dist < sa_blendwidth) { | ||||
// select area is active, | ||||
f1 = sa_blendfunc(dist); | ||||
// blend changes over sa_blendwidth | ||||
f2 = 1.0 - f1; | ||||
R3 = f1 * R3 + f2 * R1; | ||||
G3 = f1 * G3 + f2 * G1; | ||||
B3 = f1 * B3 + f2 * B1; | ||||
} | ||||
RGBFIX(R3,G3,B3) | ||||
pix3[0] = R3; | ||||
pix3[1] = G3; | ||||
pix3[2] = B3; | ||||
} | ||||
return 0; | ||||
} | ||||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added |