f.effects.cc (fotoxx-22.41) | : | f.effects.cc (fotoxx-22.50) | ||
---|---|---|---|---|
skipping to change at line 542 | skipping to change at line 542 | |||
editfunc EFcartoon; | editfunc EFcartoon; | |||
int line_threshold = 100; | int line_threshold = 100; | |||
int line_width = 3; | int line_width = 3; | |||
int blur_radius = 4; | int blur_radius = 4; | |||
int kuwahara_depth = 2; | int kuwahara_depth = 2; | |||
int priorKD, priorBR; | int priorKD, priorBR; | |||
int Eww, Ehh; | int Eww, Ehh; | |||
float *pixcon; | float *pixcon; | |||
float Fthreshold; | float Fthreshold; | |||
float Wrad[41][41]; // radius <= 20 | float Wrad[41][41]; // radius <= 20 | |||
int dialog_event(zdialog* zd, cchar *event); | ||||
void * thread(void *); | ||||
void blur(); | ||||
void * blur_wthread(void *); | ||||
void kuwahara(); | ||||
void * kuwahara_wthread(void *); | ||||
void contrast_map(); | ||||
void drawlines(); | ||||
void * drawlines_wthread(void *); | ||||
} | } | |||
// menu function | // menu function | |||
void m_cartoon(GtkWidget *, cchar *menu) | void m_cartoon(GtkWidget *, cchar *menu) | |||
{ | { | |||
using namespace cartoon; | using namespace cartoon; | |||
int cartoon_dialog_event(zdialog *zd, cchar *event); | ||||
void * cartoon_thread(void *); | ||||
F1_help_topic = "cartoon"; | F1_help_topic = "cartoon"; | |||
Plog(1,"m_cartoon \n"); | Plog(1,"m_cartoon \n"); | |||
EFcartoon.menuname = "Cartoon"; | EFcartoon.menuname = "Cartoon"; | |||
EFcartoon.menufunc = m_cartoon; | EFcartoon.menufunc = m_cartoon; | |||
EFcartoon.Farea = 2; // select area usable | EFcartoon.Farea = 2; // select area usable | |||
EFcartoon.Fscript = 1; // scripting supported | EFcartoon.Fscript = 1; // scripting supported | |||
EFcartoon.threadfunc = thread; // thread function | EFcartoon.threadfunc = cartoon_thread; // thread function | |||
if (! edit_setup(EFcartoon)) return; // setup edit | if (! edit_setup(EFcartoon)) return; // setup edit | |||
Eww = E1pxm->ww; | Eww = E1pxm->ww; | |||
Ehh = E1pxm->hh; | Ehh = E1pxm->hh; | |||
pixcon = (float *) zmalloc(Eww * Ehh * sizeof(float),"cartoon"); | pixcon = (float *) zmalloc(Eww * Ehh * sizeof(float),"cartoon"); | |||
E8pxm = PXM_copy(E1pxm); // blurred image | E8pxm = PXM_copy(E1pxm); // blurred image | |||
E9pxm = PXM_copy(E1pxm); // kuwahara image | E9pxm = PXM_copy(E1pxm); // kuwahara image | |||
skipping to change at line 611 | skipping to change at line 604 | |||
zdialog_add_widget(zd,"label","lab1","vb1","Line Threshold"); | zdialog_add_widget(zd,"label","lab1","vb1","Line Threshold"); | |||
zdialog_add_widget(zd,"label","lab1","vb1","Line Width"); | zdialog_add_widget(zd,"label","lab1","vb1","Line Width"); | |||
zdialog_add_widget(zd,"label","lab1","vb1","Kuwahara Depth"); | zdialog_add_widget(zd,"label","lab1","vb1","Kuwahara Depth"); | |||
zdialog_add_widget(zd,"zspin","line_threshold","vb2","0|1000|1|1000"); | zdialog_add_widget(zd,"zspin","line_threshold","vb2","0|1000|1|1000"); | |||
zdialog_add_widget(zd,"zspin","line_width","vb2","0|10|1|1"); | zdialog_add_widget(zd,"zspin","line_width","vb2","0|10|1|1"); | |||
zdialog_add_widget(zd,"zspin","kuwahara_depth","vb2","0|10|1|1"); | zdialog_add_widget(zd,"zspin","kuwahara_depth","vb2","0|10|1|1"); | |||
zdialog_resize(zd,200,0); | zdialog_resize(zd,200,0); | |||
zdialog_restore_inputs(zd); | zdialog_restore_inputs(zd); | |||
zdialog_run(zd,dialog_event,"save"); // run dialog, parallel | zdialog_run(zd,cartoon_dialog_event,"save"); // run dialog, parallel | |||
zdialog_fetch(zd,"line_threshold",line_threshold); | zdialog_fetch(zd,"line_threshold",line_threshold); | |||
zdialog_fetch(zd,"line_width",line_width); | zdialog_fetch(zd,"line_width",line_width); | |||
zdialog_fetch(zd,"kuwahara_depth",kuwahara_depth); | zdialog_fetch(zd,"kuwahara_depth",kuwahara_depth); | |||
blur_radius = 2 * kuwahara_depth; // 22.30 | blur_radius = 2 * kuwahara_depth; // 22.30 | |||
priorKD = priorBR = -1; // initial edit | priorKD = priorBR = -1; // initial edit | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int cartoon::dialog_event(zdialog *zd, cchar *event) // dialog event function | int cartoon_dialog_event(zdialog *zd, cchar *event) // dialog event function | |||
{ | { | |||
using namespace cartoon; | using namespace cartoon; | |||
if (strmatch(event,"escape")) zd->zstat = -2; // escape key | if (strmatch(event,"escape")) zd->zstat = -2; // escape key | |||
if (strmatch(event,"focus")) return 1; | if (strmatch(event,"focus")) return 1; | |||
if (strmatch(event,"done")) zd->zstat = 2; // from edit_setup() or f_save() | if (strmatch(event,"done")) zd->zstat = 2; // from edit_setup() or f_save() | |||
if (strmatch(event,"cancel")) zd->zstat = 3; // from f_open() | if (strmatch(event,"cancel")) zd->zstat = 3; // from f_open() | |||
if (strmatch(event,"apply")) zd->zstat = 1; // from script | if (strmatch(event,"apply")) zd->zstat = 1; // from script | |||
zdialog_fetch(zd,"line_threshold",line_threshold); // get outline threshold 0-1000 | zdialog_fetch(zd,"line_threshold",line_threshold); // get outline threshold 0-1000 | |||
skipping to change at line 667 | skipping to change at line 660 | |||
} | } | |||
else edit_cancel(0); // discard edit | else edit_cancel(0); // discard edit | |||
zfree(pixcon); | zfree(pixcon); | |||
} | } | |||
return 1; | return 1; | |||
} | } | |||
// thread function to update image | // thread function to update image | |||
void * cartoon::thread(void *) | void * cartoon_thread(void *) | |||
{ | { | |||
using namespace cartoon; | using namespace cartoon; | |||
void cartoon_blur(); | ||||
void cartoon_kuwahara(); | ||||
void cartoon_contrast_map(); | ||||
void cartoon_drawlines(); | ||||
int Fblur, Fkuwa, Fcon; | int Fblur, Fkuwa, Fcon; | |||
Fblur = Fkuwa = Fcon = 0; | Fblur = Fkuwa = Fcon = 0; | |||
if (blur_radius != priorBR) Fblur = Fkuwa = Fcon = 1; | if (blur_radius != priorBR) Fblur = Fkuwa = Fcon = 1; | |||
if (kuwahara_depth != priorKD) Fkuwa = Fcon = 1; | if (kuwahara_depth != priorKD) Fkuwa = Fcon = 1; | |||
priorBR = blur_radius; // capture now, can change during process | priorBR = blur_radius; // capture now, can change during process | |||
priorKD = kuwahara_depth; | priorKD = kuwahara_depth; | |||
progress_reset((Fblur*Fkuwa*Fcon+1)*Eww*Ehh); // 22.30 | progress_reset((Fblur*Fkuwa*Fcon+1)*Eww*Ehh); // 22.30 | |||
if (Fblur) blur(); | if (Fblur) cartoon_blur(); | |||
// E1 + blur >> E8 | // E1 + blur >> E8 | |||
if (Fkuwa) kuwahara(); | if (Fkuwa) cartoon_kuwahara(); | |||
// E8 + kuwahara >> E9 | // E8 + kuwahara >> E9 | |||
if (Fcon) contrast_map(); | if (Fcon) cartoon_contrast_map(); | |||
// compute E9 pixel contrast | // compute E9 pixel contrast | |||
drawlines(); // draw lines where contrast > threshold | cartoon_drawlines(); // draw lines where contrast > threshold | |||
progress_reset(0); | progress_reset(0); | |||
CEF->Fmods++; | CEF->Fmods++; | |||
CEF->Fsaved = 0; | CEF->Fsaved = 0; | |||
Fpaint2(); // update window | Fpaint2(); // update window | |||
return 0; | return 0; | |||
} | } | |||
// Blur the image using blur_radius. E1 + blur >> E8 | // Blur the image using blur_radius. E1 + blur >> E8 | |||
void cartoon::blur() | void cartoon_blur() | |||
{ | { | |||
using namespace cartoon; | using namespace cartoon; | |||
void * cartoon_blur_wthread(void *arg); | ||||
int rad, px, py, qx, qy; | int rad, px, py, qx, qy; | |||
float R, W; | float R, W; | |||
PXM_free(E8pxm); | PXM_free(E8pxm); | |||
E8pxm = PXM_copy(E1pxm); | E8pxm = PXM_copy(E1pxm); | |||
if (blur_radius == 0) return; | if (blur_radius == 0) return; | |||
rad = blur_radius; | rad = blur_radius; | |||
skipping to change at line 726 | skipping to change at line 726 | |||
{ | { | |||
R = sqrtf(qx * qx + qy * qy); | R = sqrtf(qx * qx + qy * qy); | |||
if (R > rad) W = 0.0; | if (R > rad) W = 0.0; | |||
else if (R == 0) W = 1.0; | else if (R == 0) W = 1.0; | |||
else W = 1.0 / R; | else W = 1.0 / R; | |||
py = qy + rad; | py = qy + rad; | |||
px = qx + rad; | px = qx + rad; | |||
Wrad[py][px] = W; | Wrad[py][px] = W; | |||
} | } | |||
do_wthreads(blur_wthread,NWT); // worker threads | do_wthreads(cartoon_blur_wthread,NWT); // worker threads | |||
return; | return; | |||
} | } | |||
void * cartoon::blur_wthread(void *arg) // worker thread function | void * cartoon_blur_wthread(void *arg) // worker thread function | |||
{ | { | |||
using namespace cartoon; | using namespace cartoon; | |||
int index = *((int *) arg); | int index = *((int *) arg); | |||
int rad = blur_radius; | int rad = blur_radius; | |||
int ii, dist = 0, px, py, qx, qy; | int ii, dist = 0, px, py, qx, qy; | |||
float W, Wsum, f1, f2; | float W, Wsum, f1, f2; | |||
float R, G, B, *pix1, *pixq, *pix8; | float R, G, B, *pix1, *pixq, *pix8; | |||
for (py = index + rad; py < Ehh-rad; py += NWT) // loop all image pixels | for (py = index + rad; py < Ehh-rad; py += NWT) // loop all image pixels | |||
for (px = rad; px < Eww-rad; px++) | for (px = rad; px < Eww-rad; px++) | |||
{ | { | |||
if (Fkillfunc) break; | if (Fkillfunc) break; | |||
if (sa_stat == 3) { // select area active | if (sa_stat == 3) { // select area active | |||
ii = py * Eww + px; | ii = py * Eww + px; | |||
dist = sa_pixmap[ii]; // distance from edge | dist = sa_pixmap[ii]; // distance from edge | |||
if (! dist) continue; // pixel is outside area | if (! dist) continue; // pixel is outside area | |||
} | } | |||
skipping to change at line 793 | skipping to change at line 793 | |||
pix8[2] = B; | pix8[2] = B; | |||
progress_add(index,1); // 22.30 | progress_add(index,1); // 22.30 | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
// Perform a kuwahara sharpen of the image. E8 + kuwahara >> E9. | // Perform a kuwahara sharpen of the image. E8 + kuwahara >> E9. | |||
void cartoon::kuwahara() | void cartoon_kuwahara() | |||
{ | { | |||
using namespace cartoon; | using namespace cartoon; | |||
void * cartoon_kuwahara_wthread(void *arg); | ||||
PXM_free(E9pxm); | PXM_free(E9pxm); | |||
E9pxm = PXM_copy(E8pxm); | E9pxm = PXM_copy(E8pxm); | |||
if (kuwahara_depth == 0) return; | if (kuwahara_depth == 0) return; | |||
do_wthreads(kuwahara_wthread,NWT); // worker threads | do_wthreads(cartoon_kuwahara_wthread,NWT); // worker threads | |||
return; | return; | |||
} | } | |||
void * cartoon::kuwahara_wthread(void *arg) // worker thread function | void * cartoon_kuwahara_wthread(void *arg) // worker thread function | |||
{ | { | |||
using namespace cartoon; | using namespace cartoon; | |||
int index = *((int *) arg); | int index = *((int *) arg); | |||
int px, py, qx, qy, rx, ry; | int px, py, qx, qy, rx, ry; | |||
int ii, rad, N, dist = 0; | int ii, rad, N, dist = 0; | |||
float *pix1, *pix8, *pix9; | float *pix1, *pix8, *pix9; | |||
float red, green, blue, red2, green2, blue2; | float red, green, blue, red2, green2, blue2; | |||
float vmin, vall, vred, vgreen, vblue; | float vmin, vall, vred, vgreen, vblue; | |||
float red9, green9, blue9; | float red9, green9, blue9; | |||
skipping to change at line 894 | skipping to change at line 896 | |||
pix9[2] = blue9; | pix9[2] = blue9; | |||
progress_add(index,1); // 22.30 | progress_add(index,1); // 22.30 | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
// Map contrast for E9 image pixels and set threshold scale. | // Map contrast for E9 image pixels and set threshold scale. | |||
void cartoon::contrast_map() | void cartoon_contrast_map() | |||
{ | { | |||
using namespace cartoon; | using namespace cartoon; | |||
int ii, px, py, qx, qy; | int ii, px, py, qx, qy; | |||
double sumcon, pix1con, maxcon; | double sumcon, pix1con, maxcon; | |||
float *pixx, *pixq; | float *pixx, *pixq; | |||
maxcon = 0; | maxcon = 0; | |||
for (py = 1; py < Ehh-1; py++) // make image pixel contrast map | for (py = 1; py < Ehh-1; py++) // make image pixel contrast map | |||
skipping to change at line 935 | skipping to change at line 937 | |||
progress_add(0,1); | progress_add(0,1); | |||
} | } | |||
Fthreshold = maxcon; // threshold scale factor | Fthreshold = maxcon; // threshold scale factor | |||
return; | return; | |||
} | } | |||
// Draw lines on the image where edges are detected. | // Draw lines on the image where edges are detected. | |||
// E9 >> E3, add lines to E3, use E1 for area blend. | // E9 >> E3, add lines to E3, use E1 for area blend. | |||
void cartoon::drawlines() | void cartoon_drawlines() | |||
{ | { | |||
void * cartoon_drawlines_wthread(void *arg); | ||||
PXM_free(E3pxm); | PXM_free(E3pxm); | |||
E3pxm = PXM_copy(E9pxm); | E3pxm = PXM_copy(E9pxm); | |||
do_wthreads(drawlines_wthread,NWT); // worker threads | do_wthreads(cartoon_drawlines_wthread,NWT); // worker threads | |||
} | } | |||
void * cartoon::drawlines_wthread(void *arg) // worker thread function | void * cartoon_drawlines_wthread(void *arg) // worker thread function | |||
{ | { | |||
using namespace cartoon; | using namespace cartoon; | |||
int index = *((int *) arg); | int index = *((int *) arg); | |||
int px, py, qx, qy, ii, dist = 0; | int px, py, qx, qy, ii, dist = 0; | |||
float Fthresh, paint, f1, f2; | float Fthresh, paint, f1, f2; | |||
float *pix1, *pix3, *pix3q; | float *pix1, *pix3, *pix3q; | |||
Fthresh = 0.001 * line_threshold * Fthreshold; // 0 .. 1000 >> 0 .. Fthreshold | Fthresh = 0.001 * line_threshold * Fthreshold; // 0 .. 1000 >> 0 .. Fthreshold | |||
skipping to change at line 1301 | skipping to change at line 1305 | |||
void * emboss_thread(void *); | void * emboss_thread(void *); | |||
F1_help_topic = "emboss"; | F1_help_topic = "emboss"; | |||
Plog(1,"m_emboss \n"); | Plog(1,"m_emboss \n"); | |||
EFemboss.menuname = "Emboss"; | EFemboss.menuname = "Emboss"; | |||
EFemboss.menufunc = m_emboss; | EFemboss.menufunc = m_emboss; | |||
EFemboss.Fscript = 1; // scripting supported | EFemboss.Fscript = 1; // scripting supported | |||
EFemboss.Farea = 2; // select area usable | EFemboss.Farea = 2; // select area usable | |||
EFemboss.Fpaintedits = 1; // can use paint edits 22.50 | ||||
EFemboss.threadfunc = emboss_thread; // thread function | EFemboss.threadfunc = emboss_thread; // thread function | |||
if (! edit_setup(EFemboss)) return; // setup edit | if (! edit_setup(EFemboss)) return; // setup edit | |||
/*** | /*** | |||
__________________________ | __________________________ | |||
| Emboss | | | Emboss | | |||
| | | | | | |||
| Radius [__] Depth [__] | // remove B/W option 22.30 | | Radius [__] Depth [__] | // remove B/W option 22.30 | |||
| | | | | | |||
skipping to change at line 1358 | skipping to change at line 1363 | |||
} | } | |||
else if (zd->zstat == 2) { // [OK] commit edit | else if (zd->zstat == 2) { // [OK] commit edit | |||
edit_addhist("radius:%d depth:%d",radius,depth); // edit parms > edit hist | edit_addhist("radius:%d depth:%d",radius,depth); // edit parms > edit hist | |||
edit_done(0); | edit_done(0); | |||
} | } | |||
else edit_cancel(0); // discard edit | else edit_cancel(0); // discard edit | |||
return 1; | return 1; | |||
} | } | |||
if (zstrstr("blendwidth paint",event)) { | ||||
// area edge blend or mouse paint 22.50 | ||||
zdialog_fetch(zd,"radius",radius); | ||||
// get user inputs | ||||
zdialog_fetch(zd,"depth",depth); | ||||
thread_signal(); | ||||
} | ||||
return 1; | return 1; | |||
} | } | |||
// thread function - use multiple working threads | // thread function - use multiple working threads | |||
void * emboss_thread(void *) | void * emboss_thread(void *) | |||
{ | { | |||
using namespace emboss_names; | using namespace emboss_names; | |||
void * emboss_wthread(void *arg); | void * emboss_wthread(void *arg); | |||
skipping to change at line 1385 | skipping to change at line 1396 | |||
for (dy = -rad; dy <= rad; dy++) // build kernel with radius and depth | for (dy = -rad; dy <= rad; dy++) // build kernel with radius and depth | |||
for (dx = -rad; dx <= rad; dx++) | for (dx = -rad; dx <= rad; dx++) | |||
{ | { | |||
kern = coeff * (dx + dy); | kern = coeff * (dx + dy); | |||
kernel[dx+rad][dy+rad] = kern; | kernel[dx+rad][dy+rad] = kern; | |||
} | } | |||
kernel[rad][rad] = 1; // kernel center cell = 1 | kernel[rad][rad] = 1; // kernel center cell = 1 | |||
get_edit_pixels_init(NWT,0); | ||||
// initz. pixel loop 22.50 | ||||
do_wthreads(emboss_wthread,NWT); // worker threads | do_wthreads(emboss_wthread,NWT); // worker threads | |||
CEF->Fmods++; | CEF->Fmods++; | |||
CEF->Fsaved = 0; | CEF->Fsaved = 0; | |||
Fpaint2(); // update window | if (! Fpaintedits) Fpaint2(); // update window | |||
return 0; | return 0; | |||
} | } | |||
void * emboss_wthread(void *arg) // worker thread function | void * emboss_wthread(void *arg) // worker thread function | |||
{ | { | |||
using namespace emboss_names; | using namespace emboss_names; | |||
void emboss_1pix(int px, int py); | ||||
int index = *((int *) (arg)); | int index = *((int *) (arg)); | |||
int px, py; | int px, py, Fend; | |||
int dx, dy, rad; | ||||
int nc = E1pxm->nc; | ||||
float R1, G1, B1, R3, G3, B3, R9, G9, B9; | ||||
float bright1, bright3; | ||||
float *pix1, *pix3, *pixN; | ||||
float sumpix, kern; | ||||
float blend, max$; | ||||
for (py = index; py < E3pxm->hh; py += NWT) | rad = radius; | |||
// process all pixels | ||||
for (px = 0; px < E3pxm->ww; px++) | ||||
emboss_1pix(px,py); | ||||
return 0; | while (true) | |||
} | { | |||
Fend = get_edit_pixels(index,px,py,blend); | ||||
// 22.50 | ||||
if (Fend) break; | ||||
if (blend == 0) continue; | ||||
void emboss_1pix(int px, int py) | if (px < rad || py < rad) continue; | |||
// process one pixel 22.30 | if (px > E3pxm->ww-rad-1 || py > E3pxm->hh-rad-1) continue; | |||
{ | ||||
using namespace emboss_names; | ||||
int ii, dist = 0; | pix1 = PXMpix(E1pxm,px,py); | |||
float bright1, bright3; | // input pixel | |||
int dx, dy, rad; | pix3 = PXMpix(E3pxm,px,py); | |||
float *pix1, *pix3, *pixN; | // output pixel | |||
float sumpix, kern, dold, dnew; | ||||
float max$; | ||||
int nc = E1pxm->nc; | ||||
if (sa_stat == 3) { | R1 = pix1[0]; | |||
// select area active | G1 = pix1[1]; | |||
ii = py * E3pxm->ww + px; | B1 = pix1[2]; | |||
dist = sa_pixmap[ii]; | ||||
// distance from edge | ||||
if (! dist) return; | ||||
// outside pixel | ||||
} | ||||
rad = radius; | R3 = pix3[0]; | |||
G3 = pix3[1]; | ||||
B3 = pix3[2]; | ||||
sumpix = 0; | ||||
if (px < rad || py < rad) return; | for (dy = -rad; dy <= rad; dy++) | |||
if (px > E3pxm->ww-rad-1 || py > E3pxm->hh-rad-1) return; | // loop surrounding block of pixels | |||
for (dx = -rad; dx <= rad; dx++) | ||||
{ | ||||
pixN = pix1 + (dy * E1pxm->ww + dx) * nc; | ||||
kern = kernel[dx+rad][dy+rad]; | ||||
sumpix += kern * (pixN[0] + pixN[1] + pixN[2]); | ||||
// kern sums to 1.0 | ||||
} | ||||
pix1 = PXMpix(E1pxm,px,py); | bright1 = pix1[0] + pix1[1] + pix1[2] + 1; | |||
// input pixel | bright3 = (sumpix + 1) / bright1; | |||
pix3 = PXMpix(E3pxm,px,py); | // ratio of brightness change | |||
// output pixel | ||||
sumpix = 0; | R9 = bright3 * R1; | |||
G9 = bright3 * G1; | ||||
B9 = bright3 * B1; | ||||
for (dy = -rad; dy <= rad; dy++) | RGBFIX(R9,G9,B9); | |||
// loop surrounding block of pixels | ||||
for (dx = -rad; dx <= rad; dx++) | ||||
{ | ||||
pixN = pix1 + (dy * E1pxm->ww + dx) * nc; | ||||
kern = kernel[dx+rad][dy+rad]; | ||||
sumpix += kern * (pixN[0] + pixN[1] + pixN[2]); | ||||
// kern sums to 1.0 | ||||
} | ||||
bright1 = pix1[0] + pix1[1] + pix1[2] + 1; | if (Fpaintedits) | |||
bright3 = (sumpix + 1) / bright1; | // mouse paint edit | |||
// ratio of brightness change | { | |||
if (blend > 0) | ||||
{ | ||||
// increase edit | ||||
R3 = blend * R9 + (1-blend) * R3; | ||||
G3 = blend * G9 + (1-blend) * G3; | ||||
B3 = blend * B9 + (1-blend) * B3; | ||||
} | ||||
if (sa_stat == 3 && dist < sa_blendwidth) { | else if (blend < 0) | |||
// select area is active, | { | |||
dnew = sa_blendfunc(dist); | // decrease edit | |||
// blend changes over sa_blendwidth | R3 = -blend * R1 + (1+blend) * R3; | |||
dold = 1.0 - dnew; | G3 = -blend * G1 + (1+blend) * G3; | |||
bright3 = dnew * bright3 + dold * 1.0; | B3 = -blend * B1 + (1+blend) * B3; | |||
} | } | |||
} | ||||
pix3[0] = bright3 * pix1[0]; | else | |||
pix3[1] = bright3 * pix1[1]; | // full image edit | |||
pix3[2] = bright3 * pix1[2]; | { | |||
R3 = blend * R9 + (1-blend) * R1; | ||||
G3 = blend * G9 + (1-blend) * G1; | ||||
B3 = blend * B9 + (1-blend) * B1; | ||||
} | ||||
RGBFIX(pix3[0],pix3[1],pix3[2]); | pix3[0] = R3; | |||
pix3[1] = G3; | ||||
pix3[2] = B3; | ||||
} | ||||
return; | return 0; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// convert image to simulate square tiles | // convert image to simulate square tiles | |||
namespace tiles_names | namespace tiles_names | |||
{ | { | |||
editfunc EFtiles; | editfunc EFtiles; | |||
int size, gap, D3; | int size, gap, D3; | |||
skipping to change at line 2342 | skipping to change at line 2372 | |||
zdialog *zd; | zdialog *zd; | |||
F1_help_topic = "texture"; | F1_help_topic = "texture"; | |||
Plog(1,"m_texture \n"); | Plog(1,"m_texture \n"); | |||
EFtexture.menuname = "Texture"; | EFtexture.menuname = "Texture"; | |||
EFtexture.menufunc = m_texture; | EFtexture.menufunc = m_texture; | |||
EFtexture.Farea = 2; // select area OK | EFtexture.Farea = 2; // select area OK | |||
EFtexture.Fpaintedits = 1; // can use paint edits 22.50 | ||||
EFtexture.Fscript = 1; // scripting supported | EFtexture.Fscript = 1; // scripting supported | |||
EFtexture.threadfunc = texture_thread; // thread function | EFtexture.threadfunc = texture_thread; // thread function | |||
if (! edit_setup(EFtexture)) return; // setup edit | if (! edit_setup(EFtexture)) return; // setup edit | |||
e3ww = E3pxm->ww; // image dimensions | e3ww = E3pxm->ww; // image dimensions | |||
e3hh = E3pxm->hh; | e3hh = E3pxm->hh; | |||
/*** | /*** | |||
___________________________________ | ___________________________________ | |||
skipping to change at line 2408 | skipping to change at line 2439 | |||
return 1; | return 1; | |||
} | } | |||
if (zd->zstat == 2) { // commit edit | if (zd->zstat == 2) { // commit edit | |||
edit_addhist("radius:%d power:%d",radius,power); // edit parms > edit hist | edit_addhist("radius:%d power:%d",radius,power); // edit parms > edit hist | |||
edit_done(0); | edit_done(0); | |||
} | } | |||
else edit_cancel(0); // discard edit | else edit_cancel(0); // discard edit | |||
return 1; | return 1; | |||
} | } | |||
if (zstrstr("blendwidth paint",event)) { | ||||
// edge blend or mouse paint 22.50 | ||||
zdialog_fetch(zd,"radius",radius); | ||||
zdialog_fetch(zd,"power",power); | ||||
thread_signal(); | ||||
} | ||||
return 1; | return 1; | |||
} | } | |||
// thread function - update image | // thread function - update image | |||
void * texture_thread(void *) | void * texture_thread(void *) | |||
{ | { | |||
using namespace texturenames; | using namespace texturenames; | |||
void * texture_wthread(void *arg); // worker thread | void * texture_wthread(void *arg); // worker thread | |||
if (sa_stat == 3) progress_reset(sa_Npixel); // initz. progress counter | if (sa_stat == 3) progress_reset(sa_Npixel); // initz. progress counter | |||
else progress_reset(e3ww * e3hh); | else progress_reset(e3ww * e3hh); | |||
get_edit_pixels_init(NWT,0); | ||||
// initz. pixel loop 22.50 | ||||
do_wthreads(texture_wthread,NWT); // worker threads | do_wthreads(texture_wthread,NWT); // worker threads | |||
progress_reset(0); | progress_reset(0); | |||
CEF->Fmods = 1; // image modified | CEF->Fmods = 1; // image modified | |||
CEF->Fsaved = 0; // not saved | CEF->Fsaved = 0; // not saved | |||
Fpaint2(); // update window | if (! Fpaintedits) Fpaint2(); // update window | |||
return 0; | return 0; | |||
} | } | |||
void * texture_wthread(void *arg) // worker thread function | void * texture_wthread(void *arg) // worker thread function | |||
{ | { | |||
using namespace texturenames; | using namespace texturenames; | |||
int index = *((int *) (arg)); | int index = *((int *) (arg)); | |||
int px, py, qx, qy, npix, dist = 0; | int px, py, qx, qy, npix; | |||
int ii, rank1, rank2; | int Fend, rank1, rank2; | |||
float fred, fgreen, fblue; | float R1, G1, B1, R3, G3, B3, R9, G9, B9; | |||
float *pix1, *pix3, *qpix; | float *pix1, *pix3, *qpix; | |||
float pow, ff, f1, f3; | float pow, ff; | |||
float pbright, qbright; | float pbright, qbright; | |||
float max$; | float blend, max$; | |||
pow = 0.001 * powf(power,1.5); // 0.001 ... 1.0 | pow = 0.001 * powf(power,1.5); // 0.001 ... 1.0 | |||
for (py = index+radius; py < e3hh-radius; py += NWT) | while (true) | |||
// loop all image pixels | ||||
for (px = radius; px < e3ww-radius; px++) | ||||
{ | { | |||
if (sa_stat == 3) { | Fend = get_edit_pixels(index,px,py,blend); | |||
// select area active | // 22.50 | |||
ii = py * e3ww + px; | if (Fend) break; | |||
dist = sa_pixmap[ii]; | if (blend == 0) continue; | |||
// distance from edge | ||||
if (! dist) continue; | ||||
// pixel outside area | ||||
} | ||||
pix1 = PXMpix(E1pxm,px,py); // input pixel | pix1 = PXMpix(E1pxm,px,py); // input pixel | |||
pix3 = PXMpix(E3pxm,px,py); | ||||
// output pixel | ||||
R1 = pix1[0]; | ||||
G1 = pix1[1]; | ||||
B1 = pix1[2]; | ||||
R3 = pix3[0]; | ||||
G3 = pix3[1]; | ||||
B3 = pix3[2]; | ||||
pbright = PIXBRIGHT(pix1); // input pixel brightness | pbright = PIXBRIGHT(pix1); // input pixel brightness | |||
npix = 0; | npix = 0; | |||
rank1 = rank2 = 0; | rank1 = rank2 = 0; | |||
for (qy = py-radius; qy <= py+radius; qy++) // loop pixels in neighborhood | for (qy = py-radius; qy <= py+radius; qy++) // loop pixels in neighborhood | |||
for (qx = px-radius; qx <= px+radius; qx++) | for (qx = px-radius; qx <= px+radius; qx++) | |||
{ | { | |||
qpix = PXMpix(E1pxm,qx,qy); // neighbor pixel | qpix = PXMpix(E1pxm,qx,qy); // neighbor pixel | |||
qbright = PIXBRIGHT(qpix); // compare neighbor brightness | qbright = PIXBRIGHT(qpix); // compare neighbor brightness | |||
skipping to change at line 2481 | skipping to change at line 2527 | |||
} | } | |||
if (! pbright) ff = 1; | if (! pbright) ff = 1; | |||
else { | else { | |||
qbright = 255.9 * (rank1 + 0.5 * rank2) / npix; // assigned brightness = 256*rank/npix | qbright = 255.9 * (rank1 + 0.5 * rank2) / npix; // assigned brightness = 256*rank/npix | |||
ff = qbright / pbright; // new/old brightness ratio | ff = qbright / pbright; // new/old brightness ratio | |||
} | } | |||
ff = 1.0 - pow * (1.0 - ff); // 1 ... ff for pow = 0 ... 1 | ff = 1.0 - pow * (1.0 - ff); // 1 ... ff for pow = 0 ... 1 | |||
fred = ff * pix1[0]; | R9 = ff * R1; | |||
// RGB for new brightness level | // RGB for new brightness level | |||
fgreen = ff * pix1[1]; | G9 = ff * G1; | |||
fblue = ff * pix1[2]; | B9 = ff * B1; | |||
RGBFIX(fred,fgreen,fblue) | RGBFIX(R9,G9,B9) | |||
if (sa_stat == 3 && dist < sa_blendwidth) { | if (Fpaintedits) | |||
// select area is active, | // mouse paint edit | |||
f3 = sa_blendfunc(dist); | { | |||
// blend changes over sa_blendwidth | if (blend > 0) | |||
f1 = 1.0 - f3; | { | |||
fred = f3 * fred + f1 * pix1[0]; | // increase edit | |||
fgreen = f3 * fgreen + f1 * pix1[1]; | R3 = blend * R9 + (1-blend) * R3; | |||
fblue = f3 * fblue + f1 * pix1[2]; | G3 = blend * G9 + (1-blend) * G3; | |||
B3 = blend * B9 + (1-blend) * B3; | ||||
} | ||||
else if (blend < 0) | ||||
{ | ||||
// decrease edit | ||||
R3 = -blend * R1 + (1+blend) * R3; | ||||
G3 = -blend * G1 + (1+blend) * G3; | ||||
B3 = -blend * B1 + (1+blend) * B3; | ||||
} | ||||
} | } | |||
pix3 = PXMpix(E3pxm,px,py); | else | |||
// output pixel | // full image edit | |||
pix3[0] = fred; | { | |||
pix3[1] = fgreen; | R3 = blend * R9 + (1-blend) * R1; | |||
pix3[2] = fblue; | G3 = blend * G9 + (1-blend) * G1; | |||
B3 = blend * B9 + (1-blend) * B1; | ||||
} | ||||
pix3[0] = R3; | ||||
pix3[1] = G3; | ||||
pix3[2] = B3; | ||||
progress_add(index,1); | progress_add(index,1); | |||
} | } | |||
return 0; // exit thread | return 0; // exit thread | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// pattern menu function | // pattern menu function | |||
skipping to change at line 4053 | skipping to change at line 4114 | |||
if (strmatch(event,"LOAD")) // load a palette file | if (strmatch(event,"LOAD")) // load a palette file | |||
{ | { | |||
pp = zgetfile("palette file",MWIN,"file",palettes_folder,0); | pp = zgetfile("palette file",MWIN,"file",palettes_folder,0); | |||
if (pp) { | if (pp) { | |||
zdialog_show(zd,0); | zdialog_show(zd,0); | |||
poptext_window(MWIN,"mapping palette ...",200,200,0,1000); | poptext_window(MWIN,"mapping palette ...",200,200,0,1000); | |||
zmainsleep(0.1); | zmainsleep(0.1); | |||
Ncolors = load_palette_map(pp); // CPU loops for a long time | Ncolors = load_palette_map(pp); // CPU loops for a long time | |||
poptext_window(0,0,0,0,0,0); | poptext_window(0,0,0,0,0,0); | |||
if (Ncolors) { | if (Ncolors) { | |||
zmessage_post(Mwin,"parent",3,"palette loaded, %d colors",Ncolors); | zmessage_post_bold(Mwin,"parent",3,"palette loaded, %d colors",Ncolo rs); | |||
pp = strrchr(pp,'/'); | pp = strrchr(pp,'/'); | |||
zdialog_stuff(zd,"palname",pp+1); | zdialog_stuff(zd,"palname",pp+1); | |||
} | } | |||
zdialog_show(zd,1); | zdialog_show(zd,1); | |||
} | } | |||
} | } | |||
return 1; | return 1; | |||
} | } | |||
skipping to change at line 5348 | skipping to change at line 5409 | |||
F1_help_topic = "shift colors"; | F1_help_topic = "shift colors"; | |||
Plog(1,"m_shift_colors \n"); | Plog(1,"m_shift_colors \n"); | |||
EFshiftcolors.menuname = "Shift Colors"; | EFshiftcolors.menuname = "Shift Colors"; | |||
EFshiftcolors.menufunc = m_shift_colors; | EFshiftcolors.menufunc = m_shift_colors; | |||
EFshiftcolors.FprevReq = 1; // use preview | EFshiftcolors.FprevReq = 1; // use preview | |||
EFshiftcolors.Farea = 2; // select area OK | EFshiftcolors.Farea = 2; // select area OK | |||
EFshiftcolors.Fscript = 1; // scripting supported | EFshiftcolors.Fscript = 1; // scripting supported | |||
EFshiftcolors.Fpaintedits = 1; // can use with paint edits 22.50 | ||||
EFshiftcolors.threadfunc = shiftcolors_thread; // thread function | EFshiftcolors.threadfunc = shiftcolors_thread; // thread function | |||
if (! edit_setup(EFshiftcolors)) return; // setup edit | if (! edit_setup(EFshiftcolors)) return; // setup edit | |||
E3ww = E3pxm->ww; | E3ww = E3pxm->ww; | |||
E3hh = E3pxm->hh; | E3hh = E3pxm->hh; | |||
/*** | /*** | |||
Shift Colors | Shift Colors | |||
skipping to change at line 5466 | skipping to change at line 5528 | |||
shiftred = shiftgreen = shiftblue = shiftall; | shiftred = shiftgreen = shiftblue = shiftall; | |||
zdialog_stuff(zd,"red",shiftred); | zdialog_stuff(zd,"red",shiftred); | |||
zdialog_stuff(zd,"green",shiftgreen); | zdialog_stuff(zd,"green",shiftgreen); | |||
zdialog_stuff(zd,"blue",shiftblue); | zdialog_stuff(zd,"blue",shiftblue); | |||
} | } | |||
zdialog_fetch(zd,"red",shiftred); | zdialog_fetch(zd,"red",shiftred); | |||
zdialog_fetch(zd,"green",shiftgreen); | zdialog_fetch(zd,"green",shiftgreen); | |||
zdialog_fetch(zd,"blue",shiftblue); | zdialog_fetch(zd,"blue",shiftblue); | |||
if (zstrstr("red green blue all blendwidth apply",event)) // trigger update thread | if (zstrstr("red green blue all blendwidth apply paint",event)) // trigger update thread | |||
thread_signal(); | thread_signal(); | |||
return 1; | return 1; | |||
} | } | |||
// thread function - launch multiple working threads to update image | // thread function - launch multiple working threads to update image | |||
void * shiftcolors_thread(void *) | void * shiftcolors_thread(void *) | |||
{ | { | |||
using namespace shiftcolors_names; | using namespace shiftcolors_names; | |||
void * shiftcolors_wthread(void *arg); // worker thread | void * shiftcolors_wthread(void *arg); // worker thread | |||
do_wthreads(shiftcolors_wthread,NWT); | get_edit_pixels_init(NWT,0); | |||
// worker threads | // initz. pixel loop | |||
do_wthreads(shiftcolors_wthread,NWT); | ||||
// do worker threads | ||||
CEF->Fmods++; // image modified | CEF->Fmods++; // image modified | |||
CEF->Fsaved = 0; | CEF->Fsaved = 0; | |||
Fpaint2(); // update window | if (! Fpaintedits) Fpaint2(); // update window | |||
return 0; | return 0; | |||
} | } | |||
void * shiftcolors_wthread(void *arg) // worker thread function | void * shiftcolors_wthread(void *arg) // worker thread function | |||
{ | { | |||
using namespace shiftcolors_names; | using namespace shiftcolors_names; | |||
int index = *((int *) (arg)); | int index = *((int *) (arg)); | |||
int px, py, ii, dist = 0; | int px, py, Fend; | |||
float *pix1, *pix3; | float *pix1, *pix3; | |||
float red1, green1, blue1, red3, green3, blue3; | float R1, G1, B1, R3, G3, B3, R9, G9, B9; | |||
float lossR, lossG, lossB, gainR, gainG, gainB; | float lossR, lossG, lossB, gainR, gainG, gainB; | |||
float shift, move, f1, f2; | float shift, move; | |||
float max$; | float blend, max$; | |||
for (py = index; py < E3hh; py += NWT) | while (true) | |||
// loop all image pixels | // 22.50 | |||
for (px = 0; px < E3ww; px++) | ||||
{ | { | |||
if (sa_stat == 3) { | Fend = get_edit_pixels(index,px,py,blend); | |||
// select area active | ||||
ii = py * E3ww + px; | if (Fend) break; | |||
dist = sa_pixmap[ii]; | if (blend == 0) continue; | |||
// distance from edge | ||||
if (! dist) continue; | ||||
// outside pixel | ||||
} | ||||
pix1 = PXMpix(E1pxm,px,py); // input pixel | pix1 = PXMpix(E1pxm,px,py); // input pixel | |||
pix3 = PXMpix(E3pxm,px,py); // output pixel | ||||
red1 = pix1[0]; | R1 = pix1[0]; | |||
green1 = pix1[1]; | G1 = pix1[1]; | |||
blue1 = pix1[2]; | B1 = pix1[2]; | |||
R3 = pix3[0]; | ||||
G3 = pix3[1]; | ||||
B3 = pix3[2]; | ||||
lossR = lossG = lossB = 0; | lossR = lossG = lossB = 0; | |||
gainR = gainG = gainB = 0; | gainR = gainG = gainB = 0; | |||
shift = shiftred; // red shift: green <-- red --> blue | shift = shiftred; // red shift: green <-- red --> blue | |||
if (shift <= 0.5) { // 0.0 ... 0.5 | if (shift <= 0.5) { // 0.0 ... 0.5 | |||
move = red1 * 2.0 * (0.5 - shift); | move = R1 * 2.0 * (0.5 - shift); | |||
lossR += move; | lossR += move; | |||
gainG += move; | gainG += move; | |||
} | } | |||
if (shift > 0.5) { // 0.5 ... 1.0 | if (shift > 0.5) { // 0.5 ... 1.0 | |||
move = red1 * 2.0 * (shift - 0.5); | move = R1 * 2.0 * (shift - 0.5); | |||
lossR += move; | lossR += move; | |||
gainB += move; | gainB += move; | |||
} | } | |||
shift = shiftgreen; // green shift: blue <-- green --> red | shift = shiftgreen; // green shift: blue <-- green --> red | |||
if (shift <= 0.5) { // 0.0 ... 0.5 | if (shift <= 0.5) { // 0.0 ... 0.5 | |||
move = green1 * 2.0 * (0.5 - shift); | move = G1 * 2.0 * (0.5 - shift); | |||
lossG += move; | lossG += move; | |||
gainB += move; | gainB += move; | |||
} | } | |||
if (shift > 0.5) { // 0.5 ... 1.0 | if (shift > 0.5) { // 0.5 ... 1.0 | |||
move = green1 * 2.0 * (shift - 0.5); | move = G1 * 2.0 * (shift - 0.5); | |||
lossG += move; | lossG += move; | |||
gainR += move; | gainR += move; | |||
} | } | |||
shift = shiftblue; // blue shift: red <-- blue --> green | shift = shiftblue; // blue shift: red <-- blue --> green | |||
if (shift <= 0.5) { // 0.0 ... 0.5 | if (shift <= 0.5) { // 0.0 ... 0.5 | |||
move = blue1 * 2.0 * (0.5 - shift); | move = B1 * 2.0 * (0.5 - shift); | |||
lossB += move; | lossB += move; | |||
gainR += move; | gainR += move; | |||
} | } | |||
if (shift > 0.5) { // 0.5 ... 1.0 | if (shift > 0.5) { // 0.5 ... 1.0 | |||
move = blue1 * 2.0 * (shift - 0.5); | move = B1 * 2.0 * (shift - 0.5); | |||
lossB += move; | lossB += move; | |||
gainG += move; | gainG += move; | |||
} | } | |||
pix3 = PXMpix(E3pxm,px,py); | R9 = R1 - lossR + gainR; | |||
// output pixel | // output pixel | |||
G9 = G1 - lossG + gainG; | ||||
B9 = B1 - lossB + gainB; | ||||
red3 = red1 - lossR + gainR; | RGBFIX(R9,G9,B9) | |||
green3 = green1 - lossG + gainG; | ||||
blue3 = blue1 - lossB + gainB; | ||||
RGBFIX(red3,green3,blue3) | if (Fpaintedits) | |||
// mouse paint edit 22.50 | ||||
{ | ||||
if (blend > 0) | ||||
{ | ||||
// increase edit | ||||
R3 = blend * R9 + (1-blend) * R3; | ||||
G3 = blend * G9 + (1-blend) * G3; | ||||
B3 = blend * B9 + (1-blend) * B3; | ||||
} | ||||
if (sa_stat == 3 && dist < sa_blendwidth) { | else if (blend < 0) | |||
// select area is active | { | |||
f1 = sa_blendfunc(dist); | // decrease edit | |||
// blend changes over sa_blendwidth | R3 = -blend * R1 + (1+blend) * R3; | |||
f2 = 1.0 - f1; | G3 = -blend * G1 + (1+blend) * G3; | |||
red3 = f1 * red3 + f2 * red1; | B3 = -blend * B1 + (1+blend) * B3; | |||
green3 = f1 * green3 + f2 * green1; | } | |||
blue3 = f1 * blue3 + f2 * blue1; | ||||
} | } | |||
pix3[0] = red3; | else | |||
pix3[1] = green3; | // full image edit | |||
pix3[2] = blue3; | { | |||
R3 = blend * R9 + (1-blend) * R1; | ||||
G3 = blend * G9 + (1-blend) * G1; | ||||
B3 = blend * B9 + (1-blend) * B1; | ||||
} | ||||
pix3[0] = R3; | ||||
pix3[1] = G3; | ||||
pix3[2] = B3; | ||||
} | } | |||
return 0; | return 0; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// alien colors - displace hue by an angle that varies over the image | // alien colors - displace hue by an angle that varies over the image | |||
namespace alien_colors_names | namespace alien_colors_names | |||
{ | { | |||
editfunc EFaliencolors; | editfunc EFaliencolors; | |||
float BLsz, Ampl; // block size, amplitude | float BLsz, Ampl; // block size, amplitude | |||
float Frand[200][200]; // random numbers | float Frand[200][200]; // random numbers | |||
#define maxblocks 200 | #define maxblocks 200 // max. rows and cols | |||
} | } | |||
// menu function | // menu function | |||
void m_alien_colors(GtkWidget *, cchar *menu) | void m_alien_colors(GtkWidget *, cchar *menu) | |||
{ | { | |||
using namespace alien_colors_names; | using namespace alien_colors_names; | |||
int alien_colors_dialog_event(zdialog* zd, const char *event); | int alien_colors_dialog_event(zdialog* zd, const char *event); | |||
void * alien_colors_thread(void *); | void * alien_colors_thread(void *); | |||
skipping to change at line 5707 | skipping to change at line 5787 | |||
float d1, d7, dx, dy; | float d1, d7, dx, dy; | |||
float W0, W1, W2, W3, W4, W5, W6, W7, W8, Wsum; | float W0, W1, W2, W3, W4, W5, W6, W7, W8, Wsum; | |||
float R1, G1, B1, R3, G3, B3, H, S, L; | float R1, G1, B1, R3, G3, B3, H, S, L; | |||
float theta, f1, f2; | float theta, f1, f2; | |||
float *pix1, *pix3; | float *pix1, *pix3; | |||
Eww = E3pxm->ww; | Eww = E3pxm->ww; | |||
Ehh = E3pxm->hh; | Ehh = E3pxm->hh; | |||
bsize = BLsz; // block size | bsize = BLsz; // block size | |||
if (Eww / bsize >= maxblocks) bsize = Eww / (maxblocks - 1); // stop > maxblocks rows or cols | if (Eww / bsize >= maxblocks) bsize = Eww / (maxblocks - 1); // stop > maxblocks rows or cols | |||
if (Ehh / bsize >= maxblocks) bsize = Ehh / (maxblocks - 1); | if (Ehh / bsize >= maxblocks) bsize = Ehh / (maxblocks - 1); | |||
maxrow = 1 + Ehh / bsize; | maxrow = 1 + Ehh / bsize; | |||
maxcol = 1 + Eww / bsize; | maxcol = 1 + Eww / bsize; | |||
for (py = index; py < Ehh; py += NWT) | for (py = index; py < Ehh; py += NWT) | |||
for (px = 0; px < Eww; px++) | for (px = 0; px < Eww; px++) | |||
{ | { | |||
if (sa_stat == 3) { // select area active | if (sa_stat == 3) { // select area active | |||
int ii = py * Eww + px; | int ii = py * Eww + px; | |||
skipping to change at line 6234 | skipping to change at line 6314 | |||
return 0; // exit thread | return 0; // exit thread | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// process image using a custom kernel | // process image using a custom kernel | |||
namespace anykernel_names | namespace anykernel_names | |||
{ | { | |||
int Eww, Ehh; // image dimensions | int Eww, Ehh; // image dimensions | |||
int kernsize = 5; // kernel size, N x N | int kernsize = 5; // kernel size, N x N | |||
float fmpyer = 1.0; // multiplier | float fmpyer = 1.0; // multiplier | |||
int fadder = 0; // adder | int fadder = 0; // adder | |||
int kernel[15][15]; // up to 15 x 15 | int kernel[15][15]; // up to 15 x 15 | |||
editfunc EFanykernel; | editfunc EFanykernel; | |||
} | } | |||
void m_anykernel(GtkWidget *, cchar *menu) // menu function | void m_anykernel(GtkWidget *, cchar *menu) // menu function | |||
{ | { | |||
using namespace anykernel_names; | using namespace anykernel_names; | |||
skipping to change at line 6262 | skipping to change at line 6342 | |||
EFanykernel.menuname = "Custom Kernel"; | EFanykernel.menuname = "Custom Kernel"; | |||
EFanykernel.menufunc = m_anykernel; | EFanykernel.menufunc = m_anykernel; | |||
EFanykernel.Farea = 2; // select area usable | EFanykernel.Farea = 2; // select area usable | |||
EFanykernel.Fscript = 1; // scripting supported | EFanykernel.Fscript = 1; // scripting supported | |||
EFanykernel.threadfunc = anykernel_thread; // thread function | EFanykernel.threadfunc = anykernel_thread; // thread function | |||
EFanykernel.Frestart = 1; // allow restart | EFanykernel.Frestart = 1; // allow restart | |||
if (! edit_setup(EFanykernel)) return; // setup edit | if (! edit_setup(EFanykernel)) return; // setup edit | |||
Eww = E3pxm->ww; // image dimensions | Eww = E3pxm->ww; // image dimensions | |||
Ehh = E3pxm->hh; | Ehh = E3pxm->hh; | |||
anykernel_make_dialog(); | anykernel_make_dialog(); | |||
return; | return; | |||
} | } | |||
// build the input dialog with the requested array size | // build the input dialog with the requested array size | |||
int anykernel_make_dialog() | int anykernel_make_dialog() | |||
{ | { | |||
End of changes. 85 change blocks. | ||||
178 lines changed or deleted | 260 lines changed or added |