f.warp.cc (fotoxx-22.41) | : | f.warp.cc (fotoxx-22.50) | ||
---|---|---|---|---|
skipping to change at line 50 | skipping to change at line 50 | |||
******************************************************************************** */ | ******************************************************************************** */ | |||
#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) | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// unbend an image | // unbend an image | |||
// straighten curvature added by pano or improve perspective | // straighten curvature added by pano or improve perspective | |||
float unbend_lin_horz, unbend_lin_vert; | namespace unbend_names | |||
// unbend values from dialog | { | |||
float unbend_cur_horz, unbend_cur_vert; | float ub_lin_horz, ub_lin_vert; | |||
float unbend_x1, unbend_x2, unbend_y1, unbend_y2; | // unbend values from dialog | |||
// unbend axes scaled 0 to 1 | float ub_cur_horz, ub_cur_vert; | |||
int unbend_hx1, unbend_hy1, unbend_hx2, unbend_hy2; | float ub_x1, ub_x2, ub_y1, ub_y2; | |||
int unbend_vx1, unbend_vy1, unbend_vx2, unbend_vy2; | // unbend axes scaled 0 to 1 | |||
int ub_hx1, ub_hy1, ub_hx2, ub_hy2; | ||||
int ub_vx1, ub_vy1, ub_vx2, ub_vy2; | ||||
editfunc EFunbend; | editfunc EFunbend; | |||
} | ||||
// menu function | // menu function | |||
void m_unbend(GtkWidget *, cchar *menu) | void m_unbend(GtkWidget *, cchar *menu) | |||
{ | { | |||
using namespace unbend_names; | ||||
int unbend_dialog_event(zdialog* zd, cchar *event); | int unbend_dialog_event(zdialog* zd, cchar *event); | |||
void * unbend_thread(void *); | void * unbend_thread(void *); | |||
void unbend_mousefunc(); | void unbend_mousefunc(); | |||
F1_help_topic = "unbend"; | F1_help_topic = "unbend"; | |||
Plog(1,"m_unbend \n"); | Plog(1,"m_unbend \n"); | |||
EFunbend.menuname = "Unbend"; | EFunbend.menuname = "Unbend"; | |||
EFunbend.FprevReq = 1; // use preview | EFunbend.FprevReq = 1; // use preview | |||
skipping to change at line 119 | skipping to change at line 124 | |||
zdialog_add_widget(zd,"icon","VL","vb1","unbend vert linear.png","size=64"); | zdialog_add_widget(zd,"icon","VL","vb1","unbend vert linear.png","size=64"); | |||
zdialog_add_widget(zd,"icon","VC","vb1","unbend vert curved.png","size=64"); | zdialog_add_widget(zd,"icon","VC","vb1","unbend vert curved.png","size=64"); | |||
zdialog_add_widget(zd,"icon","HL","vb1","unbend horz linear.png","size=64"); | zdialog_add_widget(zd,"icon","HL","vb1","unbend horz linear.png","size=64"); | |||
zdialog_add_widget(zd,"icon","HC","vb1","unbend horz curved.png","size=64"); | zdialog_add_widget(zd,"icon","HC","vb1","unbend horz curved.png","size=64"); | |||
zdialog_add_widget(zd,"zspin","splinvert","vb2","-300|300|1|0"); // finer steps | zdialog_add_widget(zd,"zspin","splinvert","vb2","-300|300|1|0"); // finer steps | |||
zdialog_add_widget(zd,"zspin","spcurvert","vb2","-300|300|1|0"); | zdialog_add_widget(zd,"zspin","spcurvert","vb2","-300|300|1|0"); | |||
zdialog_add_widget(zd,"zspin","splinhorz","vb2","-300|300|1|0"); | zdialog_add_widget(zd,"zspin","splinhorz","vb2","-300|300|1|0"); | |||
zdialog_add_widget(zd,"zspin","spcurhorz","vb2","-300|300|1|0"); | zdialog_add_widget(zd,"zspin","spcurhorz","vb2","-300|300|1|0"); | |||
unbend_x1 = unbend_x2 = unbend_y1 = unbend_y2 = 0.5; | ub_x1 = ub_x2 = ub_y1 = ub_y2 = 0.5; | |||
// initial axes thru image middle | // initial axes thru image middle | |||
unbend_lin_horz = unbend_lin_vert = 0; | ub_lin_horz = ub_lin_vert = 0; | |||
unbend_cur_horz = unbend_cur_vert = 0; | ub_cur_horz = ub_cur_vert = 0; | |||
takeMouse(unbend_mousefunc,dragcursor); // connect mouse function | takeMouse(unbend_mousefunc,dragcursor); // connect mouse function | |||
thread_signal(); | thread_signal(); | |||
zdialog_run(zd,unbend_dialog_event,"save"); // run dialog, parallel | zdialog_run(zd,unbend_dialog_event,"save"); // run dialog, parallel | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int unbend_dialog_event(zdialog *zd, cchar *event) | int unbend_dialog_event(zdialog *zd, cchar *event) | |||
{ | { | |||
using namespace unbend_names; | ||||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | 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,"done")) zd->zstat = 1; // from edit_setup() or f_save() | |||
if (strmatch(event,"cancel")) zd->zstat = 2; // from f_open() | if (strmatch(event,"cancel")) zd->zstat = 2; // from f_open() | |||
if (zd->zstat) // dialog complete | if (zd->zstat) // dialog complete | |||
{ | { | |||
if (zd->zstat == 1) { // done | if (zd->zstat == 1) { // done | |||
CEF->Fmods = 0; | CEF->Fmods = 0; | |||
if (unbend_cur_vert || unbend_cur_horz || | if (ub_cur_vert || ub_cur_horz || | |||
// image3 modified | // image3 modified | |||
unbend_lin_vert || unbend_lin_horz) { | ub_lin_vert || ub_lin_horz) { | |||
CEF->Fmods = 1; | CEF->Fmods = 1; | |||
CEF->Fsaved = 0; // done | CEF->Fsaved = 0; // done | |||
} | } | |||
edit_fullsize(); // get full size image | edit_fullsize(); // get full size image | |||
thread_signal(); | thread_signal(); | |||
edit_addhist("%.0f %.0f %.0f %.0f",unbend_lin_vert,unbend_cur_vert, | edit_addhist("%.0f %.0f %.0f %.0f",ub_lin_vert,ub_cur_vert, | |||
// edit parms > edit hist | // edit parms > edit hist | |||
unbend_lin_horz, unbend_cur_horz); | ub_lin_horz, ub_cur_horz); | |||
draw_toplines(2,0); // erase axes-lines 22.20 | draw_toplines(2,0); // erase axes-lines 22.20 | |||
edit_done(0); // commit edit | edit_done(0); // commit edit | |||
} | } | |||
else edit_cancel(0); // cancel, discard edit | else edit_cancel(0); // cancel, discard edit | |||
draw_toplines(2,0); // erase axes-lines | draw_toplines(2,0); // erase axes-lines | |||
return 1; | return 1; | |||
} | } | |||
if (strmatch(event,"splinvert")) { // get new unbend value | if (strmatch(event,"splinvert")) { // get new unbend value | |||
zdialog_fetch(zd,"splinvert",unbend_lin_vert); | zdialog_fetch(zd,"splinvert",ub_lin_vert); | |||
thread_signal(); // trigger thread | thread_signal(); // trigger thread | |||
} | } | |||
if (strmatch(event,"spcurvert")) { | if (strmatch(event,"spcurvert")) { | |||
zdialog_fetch(zd,"spcurvert",unbend_cur_vert); | zdialog_fetch(zd,"spcurvert",ub_cur_vert); | |||
thread_signal(); | thread_signal(); | |||
} | } | |||
if (strmatch(event,"splinhorz")) { | if (strmatch(event,"splinhorz")) { | |||
zdialog_fetch(zd,"splinhorz",unbend_lin_horz); | zdialog_fetch(zd,"splinhorz",ub_lin_horz); | |||
thread_signal(); | thread_signal(); | |||
} | } | |||
if (strmatch(event,"spcurhorz")) { | if (strmatch(event,"spcurhorz")) { | |||
zdialog_fetch(zd,"spcurhorz",unbend_cur_horz); | zdialog_fetch(zd,"spcurhorz",ub_cur_horz); | |||
thread_signal(); | thread_signal(); | |||
} | } | |||
return 1; | return 1; | |||
} | } | |||
// unbend mouse function // adjustable axes | // unbend mouse function // adjustable axes | |||
void unbend_mousefunc() | void unbend_mousefunc() | |||
{ | { | |||
using namespace unbend_names; | ||||
cchar *close; | cchar *close; | |||
float dist1, dist2; | float dist1, dist2; | |||
float mpx = 0, mpy = 0; | float mpx = 0, mpy = 0; | |||
if (LMclick) { // left mouse click | if (LMclick) { // left mouse click | |||
mpx = Mxclick; | mpx = Mxclick; | |||
mpy = Myclick; | mpy = Myclick; | |||
} | } | |||
if (Mxdrag || Mydrag) { // mouse dragged | if (Mxdrag || Mydrag) { // mouse dragged | |||
skipping to change at line 216 | skipping to change at line 225 | |||
if (mpy < 0.1 || mpy > 0.9) return; | if (mpy < 0.1 || mpy > 0.9) return; | |||
} | } | |||
else if (mpy < 0.2 || mpy > 0.8) { | else if (mpy < 0.2 || mpy > 0.8) { | |||
if (mpx < 0.1 || mpx > 0.9) return; | if (mpx < 0.1 || mpx > 0.9) return; | |||
} | } | |||
else return; | else return; | |||
close = "?"; // find closest axis end-point | close = "?"; // find closest axis end-point | |||
dist1 = 2; | dist1 = 2; | |||
dist2 = mpx * mpx + (mpy-unbend_y1) * (mpy-unbend_y1); | dist2 = mpx * mpx + (mpy-ub_y1) * (mpy-ub_y1); | |||
if (dist2 < dist1) { | if (dist2 < dist1) { | |||
dist1 = dist2; | dist1 = dist2; | |||
close = "left"; | close = "left"; | |||
} | } | |||
dist2 = (1-mpx) * (1-mpx) + (mpy-unbend_y2) * (mpy-unbend_y2); | dist2 = (1-mpx) * (1-mpx) + (mpy-ub_y2) * (mpy-ub_y2); | |||
if (dist2 < dist1) { | if (dist2 < dist1) { | |||
dist1 = dist2; | dist1 = dist2; | |||
close = "right"; | close = "right"; | |||
} | } | |||
dist2 = (mpx-unbend_x1) * (mpx-unbend_x1) + mpy * mpy; | dist2 = (mpx-ub_x1) * (mpx-ub_x1) + mpy * mpy; | |||
if (dist2 < dist1) { | if (dist2 < dist1) { | |||
dist1 = dist2; | dist1 = dist2; | |||
close = "top"; | close = "top"; | |||
} | } | |||
dist2 = (mpx-unbend_x2) * (mpx-unbend_x2) + (1-mpy) * (1-mpy); | dist2 = (mpx-ub_x2) * (mpx-ub_x2) + (1-mpy) * (1-mpy); | |||
if (dist2 < dist1) { | if (dist2 < dist1) { | |||
dist1 = dist2; | dist1 = dist2; | |||
close = "bottom"; | close = "bottom"; | |||
} | } | |||
if (strmatch(close,"left")) unbend_y1 = mpy; | if (strmatch(close,"left")) ub_y1 = mpy; | |||
// set new axis end-point | // set new axis end-point | |||
if (strmatch(close,"right")) unbend_y2 = mpy; | if (strmatch(close,"right")) ub_y2 = mpy; | |||
if (strmatch(close,"top")) unbend_x1 = mpx; | if (strmatch(close,"top")) ub_x1 = mpx; | |||
if (strmatch(close,"bottom")) unbend_x2 = mpx; | if (strmatch(close,"bottom")) ub_x2 = mpx; | |||
thread_signal(); // trigger thread | thread_signal(); // trigger thread | |||
LMclick = Mxdrag = Mydrag = 0; | LMclick = Mxdrag = Mydrag = 0; | |||
return; | return; | |||
} | } | |||
// unbend thread function | // unbend thread function | |||
void * unbend_thread(void *arg) | void * unbend_thread(void *arg) | |||
{ | { | |||
using namespace unbend_names; | ||||
void * unbend_wthread(void *); | void * unbend_wthread(void *); | |||
unbend_hx1 = 0; | ub_hx1 = 0; | |||
// scale axes to E3ww/hh | // scale axes to E3ww/hh | |||
unbend_hy1 = unbend_y1 * E3pxm->hh; | ub_hy1 = ub_y1 * E3pxm->hh; | |||
unbend_hx2 = E3pxm->ww; | ub_hx2 = E3pxm->ww; | |||
unbend_hy2 = unbend_y2 * E3pxm->hh; | ub_hy2 = ub_y2 * E3pxm->hh; | |||
unbend_vx1 = unbend_x1 * E3pxm->ww; | ub_vx1 = ub_x1 * E3pxm->ww; | |||
unbend_vy1 = 0; | ub_vy1 = 0; | |||
unbend_vx2 = unbend_x2 * E3pxm->ww; | ub_vx2 = ub_x2 * E3pxm->ww; | |||
unbend_vy2 = E3pxm->hh; | ub_vy2 = E3pxm->hh; | |||
Ntoplines = 2; | Ntoplines = 2; | |||
toplines[0].x1 = unbend_hx1; | toplines[0].x1 = ub_hx1; | |||
// lines on window | // lines on window | |||
toplines[0].y1 = unbend_hy1; | toplines[0].y1 = ub_hy1; | |||
toplines[0].x2 = unbend_hx2; | toplines[0].x2 = ub_hx2; | |||
toplines[0].y2 = unbend_hy2; | toplines[0].y2 = ub_hy2; | |||
toplines[0].type = 3; // black/white pair | toplines[0].type = 3; // black/white pair | |||
toplines[1].x1 = unbend_vx1; | toplines[1].x1 = ub_vx1; | |||
toplines[1].y1 = unbend_vy1; | toplines[1].y1 = ub_vy1; | |||
toplines[1].x2 = unbend_vx2; | toplines[1].x2 = ub_vx2; | |||
toplines[1].y2 = unbend_vy2; | toplines[1].y2 = ub_vy2; | |||
toplines[1].type = 3; | toplines[1].type = 3; | |||
do_wthreads(unbend_wthread,NWT); // worker threads | do_wthreads(unbend_wthread,NWT); // worker threads | |||
CEF->Fmods++; // image modified | CEF->Fmods++; // image modified | |||
CEF->Fsaved = 0; // not saved | CEF->Fsaved = 0; // not saved | |||
Fpaint2(); // update window | Fpaint2(); // update window | |||
return 0; | return 0; | |||
} | } | |||
void * unbend_wthread(void *arg) // worker thread function | void * unbend_wthread(void *arg) // worker thread function | |||
{ | { | |||
using namespace unbend_names; | ||||
int index = *((int *) arg); | int index = *((int *) arg); | |||
int vstat, px3, py3, cx3, cy3; | int vstat, px3, py3, cx3, cy3; | |||
float dispx, dispy, dispx2, dispy2; | float dispx, dispy, dispx2, dispy2; | |||
float px1, py1, vx1, vx2, hy1, hy2; | float px1, py1, vx1, vx2, hy1, hy2; | |||
float curvert, curhorz, linvert, linhorz; | float curvert, curhorz, linvert, linhorz; | |||
float vpix[4], *pix3; | float vpix[4], *pix3; | |||
int nc = E1pxm->nc, pcc = nc * sizeof(float); | int nc = E1pxm->nc, pcc = nc * sizeof(float); | |||
curvert = int(unbend_cur_vert * 0.0033 * E3pxm->hh); | curvert = int(ub_cur_vert * 0.0033 * E3pxm->hh); | |||
// -0.99 to +0.99 | // -0.99 to +0.99 | |||
curhorz = int(unbend_cur_horz * 0.0033 * E3pxm->ww); | curhorz = int(ub_cur_horz * 0.0033 * E3pxm->ww); | |||
linvert = int(unbend_lin_vert * 0.00043 * E3pxm->hh); | linvert = int(ub_lin_vert * 0.00043 * E3pxm->hh); | |||
// -0.13 to +0.13 | // -0.13 to +0.13 | |||
linhorz = int(unbend_lin_horz * 0.00043 * E3pxm->ww); | linhorz = int(ub_lin_horz * 0.00043 * E3pxm->ww); | |||
vx1 = unbend_vx1; | vx1 = ub_vx1; | |||
vx2 = unbend_vx2; | vx2 = ub_vx2; | |||
hy1 = unbend_hy1; | hy1 = ub_hy1; | |||
hy2 = unbend_hy2; | hy2 = ub_hy2; | |||
for (py3 = index; py3 < E3pxm->hh; py3 += NWT) // step through F3 pixels | for (py3 = index; py3 < E3pxm->hh; py3 += NWT) // step through F3 pixels | |||
for (px3 = 0; px3 < E3pxm->ww; px3++) | for (px3 = 0; px3 < E3pxm->ww; px3++) | |||
{ | { | |||
cx3 = vx1 + (vx2 - vx1) * py3 / E3pxm->hh; // center of unbend | cx3 = vx1 + (vx2 - vx1) * py3 / E3pxm->hh; // center of unbend | |||
cy3 = hy1 + (hy2 - hy1) * px3 / E3pxm->ww; | cy3 = hy1 + (hy2 - hy1) * px3 / E3pxm->ww; | |||
dispx = 2.0 * (px3 - cx3) / E3pxm->ww; // -1.0 .. 0.0 .. +1.0 (roughly) | dispx = 2.0 * (px3 - cx3) / E3pxm->ww; // -1.0 .. 0.0 .. +1.0 (roughly) | |||
dispy = 2.0 * (py3 - cy3) / E3pxm->hh; // -1.0 .. 0.0 .. +1.0 | dispy = 2.0 * (py3 - cy3) / E3pxm->hh; // -1.0 .. 0.0 .. +1.0 | |||
dispx2 = -cosf(0.8 * dispx) + 1; // curved | dispx2 = -cosf(0.8 * dispx) + 1; // curved | |||
dispy2 = -cosf(0.8 * dispy) + 1; | dispy2 = -cosf(0.8 * dispy) + 1; | |||
End of changes. 23 change blocks. | ||||
61 lines changed or deleted | 74 lines changed or added |