"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "f.select.cc" between
fotoxx-23.0.tar.gz and fotoxx-23.1.tar.gz

About: fotoxx is a program for photo editing and collection management.

f.select.cc  (fotoxx-23.0):f.select.cc  (fotoxx-23.1)
/******************************************************************************* * /******************************************************************************* *
Fotoxx edit photos and manage collections Fotoxx - edit photos and manage collections
Copyright 2007-2023 Michael Cornelison Copyright 2007-2023 Michael Cornelison
source code URL: https://kornelix.net source code URL: https://kornelix.net
contact: mkornelix@gmail.com contact: mkornelix@gmail.com
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. See https://www.gnu.org/licenses (at your option) any later version. See https://www.gnu.org/licenses
skipping to change at line 89 skipping to change at line 89
******************************************************************************** */ ******************************************************************************** */
#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)
/******************************************************************************* */ /******************************************************************************* */
// user select area dialog // user select area dialog
// line drawing and selection by color range are combined // line drawing and selection by color range are combined
void m_select_area(GtkWidget *, cchar *menu) // menu function void m_select_area(GtkWidget *, ch *menu) // menu function
{ {
int select_dialog_event(zdialog *, cchar *event); // dialog event and completion funcs int select_dialog_event(zdialog *, ch *event); // dialog event and completion funcs
cchar *title = "Select Area for Edits"; ch *title = "Select Area for Edits";
zdialog *zd; zdialog *zd;
if (menu) F1_help_topic = "select area"; if (menu) F1_help_topic = "select area";
Plog(1,"m_select_area \n"); Plog(1,"m_select_area \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
if (! curr_file) return; // no image if (! curr_file) return; // no image
if (zd_sela) return; // already active if (zd_sela) return; // already active
skipping to change at line 248 skipping to change at line 248
zdialog_stuff(zd,"ckallcolors",0); zdialog_stuff(zd,"ckallcolors",0);
zdialog_run(zd,select_dialog_event,"save"); // run dialog - parallel zdialog_run(zd,select_dialog_event,"save"); // run dialog - parallel
if (sa_stat) sa_show(1,0); // show existing area if (sa_stat) sa_show(1,0); // show existing area
return; return;
} }
// dialog event and completion callback function // dialog event and completion callback function
int select_dialog_event(zdialog *zd, cchar *event) int select_dialog_event(zdialog *zd, ch *event)
{ {
int Nckevents = 8, ii, kk, cc; int Nckevents = 8, ii, kk, cc;
cchar *ckevents[8] = { "ckrect", "ckelips", "ckdraw", "ckfollow", "ckrepl" , ch *ckevents[8] = { "ckrect", "ckelips", "ckdraw", "ckfollow", "ckrepl" ,
"ckmouse", "ckonecolor", "ckallcolors" }; "ckmouse", "ckonecolor", "ckallcolors" };
if (strmatch(event,"escape")) { // escape key if (strmatch(event,"escape")) { // escape key
if (sa_edgecalc_busy) Fescape = 2; if (sa_edgecalc_busy) Fescape = 1;
// kill edge calc. if busy // kill edge calc. if busy
else zd->zstat = -2; else zd->zstat = -2;
// kill dialog // else kill dialog
} }
if (sa_edgecalc_busy) return 1; // block until done if (sa_edgecalc_busy) return 1; // block until done
if (! curr_file) event = "done"; // image went away if (! curr_file) event = "done"; // image went away
if (FGWM != 'F') event = "done"; if (FGWM != 'F') event = "done";
if (strmatch(event,"done") || zd->zstat) // done or cancel if (strmatch(event,"done") || zd->zstat) // done or cancel
{ {
freeMouse(); // disconnect mouse function freeMouse(); // disconnect mouse function
skipping to change at line 339 skipping to change at line 339
if (strmatch(event,"show")) sa_show(1,0); // show area if (strmatch(event,"show")) sa_show(1,0); // show area
if (strmatch(event,"hide")) sa_show(0,0); // hide area if (strmatch(event,"hide")) sa_show(0,0); // hide area
if (strmatch(event,"clear")) sa_clear(); // clear area if (strmatch(event,"clear")) sa_clear(); // clear area
if (strmatch(event,"blendwidth") && sa_stat == 3) { // blend width changed and area finished if (strmatch(event,"blendwidth") && sa_stat == 3) { // blend width changed and area finished
zdialog_fetch(zd,"blendwidth",sa_blendwidth); // update sa_blendwidth zdialog_fetch(zd,"blendwidth",sa_blendwidth); // update sa_blendwidth
if (sa_blendwidth > 0) sa_edgecalc(); // do edge calc. if not already if (sa_blendwidth > 0) sa_edgecalc(); // do edge calc. if not already
if (sa_edgecalc_done && CEF && CEF->zd) // if edit is active, if (sa_edgecalc_done && CEF && CEF->zd) // if edit is active,
zdialog_send_event(CEF->zd,event); // notify new blendwidth zdialog_send_event(CEF->zd,event); // notify new blendwidth
if (! zd_sela) return 1; // dialog canceled if (! zd_sela) return 1; // dialog canceled
if (zd->zstat) { if (zd->zstat) return 1;
// dialog completed // dialog completed
zdialog_send_event(zd,"zstat");
return 1;
}
} }
if (strmatchN(event,"creep",5) && sa_stat == 3) { // edge creep changed and area finished if (strmatchN(event,"creep",5) && sa_stat == 3) { // edge creep changed and area finished
if (event[5] == '+') sa_edgecreep(+1); if (event[5] == '+') sa_edgecreep(+1);
else sa_edgecreep(-1); else sa_edgecreep(-1);
sa_blendwidth = 0; sa_blendwidth = 0;
zdialog_stuff(zd,"blendwidth",0); zdialog_stuff(zd,"blendwidth",0);
} }
if (strmatch(event,"red")) memcpy(LINE_COLOR,RED,3*sizeof(int)); if (strmatch(event,"red")) memcpy(LINE_COLOR,RED,3*sizeof(int));
skipping to change at line 908 skipping to change at line 905
int newdrag; int newdrag;
static int pxcc, mxdown, mydown, dragseq; static int pxcc, mxdown, mydown, dragseq;
int startx, starty, endx, endy; int startx, starty, endx, endy;
float slope; float slope;
if (sa_stat != 1) return; // area gone? if (sa_stat != 1) return; // area gone?
if (sa_mode == mode_allcolors && ! sa_pixselc) { // allocate memory for this mode if (sa_mode == mode_allcolors && ! sa_pixselc) { // allocate memory for this mode
pxcc = Fpxb->ww * Fpxb->hh; pxcc = Fpxb->ww * Fpxb->hh;
sa_stackdirec = (char *) zmalloc(pxcc,"select-area"); sa_stackdirec = (ch *) zmalloc(pxcc,"select-area");
sa_stack = (int *) zmalloc(pxcc * sizeof(int),"select-area"); sa_stack = (int *) zmalloc(pxcc * sizeof(int),"select-area");
sa_maxstack = pxcc; sa_maxstack = pxcc;
sa_Nstack = 0; sa_Nstack = 0;
sa_pixselc = (uint8 *) zmalloc(pxcc,"select-area"); sa_pixselc = (uint8 *) zmalloc(pxcc,"select-area");
} }
if (sa_mode != mode_allcolors && sa_pixselc) { // free memory otherwise if (sa_mode != mode_allcolors && sa_pixselc) { // free memory otherwise
zfree(sa_stackdirec); zfree(sa_stackdirec);
zfree(sa_stack); zfree(sa_stack);
zfree(sa_pixselc); zfree(sa_pixselc);
skipping to change at line 1043 skipping to change at line 1040
void sa_mouse_select1(int mode, int select) void sa_mouse_select1(int mode, int select)
{ {
int mrad, mrad2; int mrad, mrad2;
int rad2, ii, jj; int rad2, ii, jj;
int px, py, rx, ry; int px, py, rx, ry;
int xlo, xhi, ylo, yhi, newpix; int xlo, xhi, ylo, yhi, newpix;
uint8 *pix1; uint8 *pix1;
float match1, match2; float match1, match2;
static float red, green, blue; static float red, green, blue;
static char colorbutt[16]; static ch colorbutt[16];
px = sa_mousex; px = sa_mousex;
py = sa_mousey; py = sa_mousey;
if (px < 0 || px > Fpxb->ww-2) return; // mouse outside image if (px < 0 || px > Fpxb->ww-2) return; // mouse outside image
if (py < 0 || py > Fpxb->hh-2) return; if (py < 0 || py > Fpxb->hh-2) return;
if (mode == 1) // left click if (mode == 1) // left click
{ {
red = green = blue = 0; red = green = blue = 0;
skipping to change at line 1155 skipping to change at line 1152
{ {
int mrad, mrad2, srange2; int mrad, mrad2, srange2;
int rad1, rad2, ii; int rad1, rad2, ii;
int kk, px, py, rx, ry; int kk, px, py, rx, ry;
int ppx, ppy, npx, npy; int ppx, ppy, npx, npy;
int xlo, xhi, ylo, yhi, newpix; int xlo, xhi, ylo, yhi, newpix;
uint8 *pix1; uint8 *pix1;
float red, green, blue, ff1, ff2; float red, green, blue, ff1, ff2;
float match1, match2, match3; float match1, match2, match3;
int thresh, Npixels; int thresh, Npixels;
char direc; ch direc;
struct Ctab_t { // table of pixel colors in mouse circle struct Ctab_t { // table of pixel colors in mouse circle
int count; // count of pixels with this color int count; // count of pixels with this color
float rgb[3]; // RGB color float rgb[3]; // RGB color
}; };
Ctab_t Ctab[1000]; // table Ctab_t Ctab[1000]; // table
int Ntab; // table count int Ntab; // table count
px = sa_mousex; px = sa_mousex;
py = sa_mousey; py = sa_mousey;
skipping to change at line 1257 skipping to change at line 1254
Ctab[ii].rgb[0] = red; // add unmatched pixel color to table Ctab[ii].rgb[0] = red; // add unmatched pixel color to table
Ctab[ii].rgb[1] = green; Ctab[ii].rgb[1] = green;
Ctab[ii].rgb[2] = blue; Ctab[ii].rgb[2] = blue;
Ctab[ii].count = 1; Ctab[ii].count = 1;
Ntab++; Ntab++;
if (Ntab == 1000) goto endmatch; // exit two nested loops if (Ntab == 1000) goto endmatch; // exit two nested loops
} }
} endmatch: } endmatch:
int keys[1][3] = { { 0, sizeof(int), 4 } }; // sort position, length, descending int keys[1][3] = { { 0, sizeof(int), 4 } }; // sort position, length, descending
MemSort((char *) Ctab, sizeof(Ctab_t), Ntab, keys, 1); // sort descending count of matching pixels MemSort((ch *) Ctab, sizeof(Ctab_t), Ntab, keys, 1); // sort descending count of matching pixels
thresh = 0.03 * Ntab; // exclude minority pixels thresh = 0.03 * Ntab; // exclude minority pixels
if (Ntab < 100) thresh = 3; if (Ntab < 100) thresh = 3;
if (Ntab < 40) thresh = 2; if (Ntab < 40) thresh = 2;
for (ii = 0; ii < Ntab; ii++) for (ii = 0; ii < Ntab; ii++)
if (Ctab[ii].count < thresh) break; if (Ctab[ii].count < thresh) break;
Ntab = ii; Ntab = ii;
// search pixels outside mouse radius but within range for matching colors // search pixels outside mouse radius but within range for matching colors
skipping to change at line 1455 skipping to change at line 1452
return; return;
} }
// Finish select area - map pixels enclosed by edge pixels // Finish select area - map pixels enclosed by edge pixels
// into sa_pixmap[ii]: 0/1/2 = outside/edge/inside (ii = py * Fww + px) // into sa_pixmap[ii]: 0/1/2 = outside/edge/inside (ii = py * Fww + px)
// total count = sa_Npixel // total count = sa_Npixel
zdialog *sa_finzd = 0; // finish area zdialog zdialog *sa_finzd = 0; // finish area zdialog
int sa_fincancel; // finish area - user cancel int sa_fincancel; // finish area - user cancel
int sa_finish_dialog_event(zdialog *zd, cchar *event); // private functions int sa_finish_dialog_event(zdialog *zd, ch *event); // private functions
void sa_finish_mousefunc(); void sa_finish_mousefunc();
void sa_finish_mappix(); void sa_finish_mappix();
void sa_finish_color(); void sa_finish_color();
void sa_finish() void sa_finish()
{ {
cchar *fmess = ch *fmess =
"Fill selected areas with color for visual verification. \n" "Fill selected areas with color for visual verification. \n"
"Method 1: left-click in each selected area not already filled. \n" "Method 1: left-click in each selected area not already filled. \n"
"Method 2: right-click OUTSIDE all selected areas. \n" "Method 2: right-click OUTSIDE all selected areas. \n"
"Press [help] button for clarification"; "Press [help] button for clarification";
int zstat, cc; int zstat, cc;
Plog(1,"sa_finish() \n"); Plog(1,"sa_finish() \n");
if (! sa_stat) return; // no area? if (! sa_stat) return; // no area?
if (! sa_validate()) return; // invalid for current image if (! sa_validate()) return; // invalid for current image
sa_finish_auto(); // auto-finish mouse-selected areas 22.16 sa_finish_auto(); // auto-finish mouse-selected areas 22.16
if (sa_stat != 3) return; if (sa_stat != 3) return;
// sa_show(1,0); // zdialog_run() will Fpaint() 22.31 // sa_show(1,0); // zdialog_run() will Fpaint() 22.31
cc = Fpxb->ww * Fpxb->hh; cc = Fpxb->ww * Fpxb->hh;
if (sa_stackdirec) zfree(sa_stackdirec); if (sa_stackdirec) zfree(sa_stackdirec);
sa_stackdirec = (char *) zmalloc(cc,"select-area"); sa_stackdirec = (ch *) zmalloc(cc,"select-area");
if (sa_stack) zfree(sa_stack); if (sa_stack) zfree(sa_stack);
sa_stack = (int *) zmalloc(cc * sizeof(int),"select-area"); sa_stack = (int *) zmalloc(cc * sizeof(int),"select-area");
sa_maxstack = cc; sa_maxstack = cc;
sa_fincancel = 0; sa_fincancel = 0;
sa_Nstack = 0; sa_Nstack = 0;
/*** /***
_________________________________________________________________ _________________________________________________________________
| Finish Area | | Finish Area |
skipping to change at line 1547 skipping to change at line 1544
sa_stat = 3; // area is finished sa_stat = 3; // area is finished
areanumber++; // next sequential number areanumber++; // next sequential number
sa_edgecalc_done = sa_blendwidth = 0; // edge calculation is missing sa_edgecalc_done = sa_blendwidth = 0; // edge calculation is missing
if (zd_sela) zdialog_stuff(zd_sela,"blendwidth",0); if (zd_sela) zdialog_stuff(zd_sela,"blendwidth",0);
Fpaintnow(); Fpaintnow();
return; return;
} }
// dialog event and completion function // dialog event and completion function
int sa_finish_dialog_event(zdialog *zd, cchar *event) int sa_finish_dialog_event(zdialog *zd, ch *event)
{ {
cchar *fmess = ch *fmess =
"Method 1: \n" "Method 1: \n"
" Left-click inside an outlined area that is not already filled. \ n" " Left-click inside an outlined area that is not already filled. \ n"
" Area will be filled with color for visible verification. \n" " Area will be filled with color for visible verification. \n"
" Gaps in the outline will cause overflow outside the area. \n" " Gaps in the outline will cause overflow outside the area. \n"
" Repeat for each outlined area that is not already filled. \n" " Repeat for each outlined area that is not already filled. \n"
"Method 2: \n" "Method 2: \n"
" Right-click outside ALL outlined areas. \n" " Right-click outside ALL outlined areas. \n"
" All areas will be filled with color for visible verification. \n " " All areas will be filled with color for visible verification. \n "
" Gaps in an area outline will cause that area not to be filled. \ n" " Gaps in an area outline will cause that area not to be filled. \ n"
"Gaps in an area outline: \n" "Gaps in an area outline: \n"
skipping to change at line 1650 skipping to change at line 1647
return; return;
} }
// function to map all pixels found within enclosure containing starting pixel // function to map all pixels found within enclosure containing starting pixel
void sa_finish_mappix() void sa_finish_mappix()
{ {
int px, py, ii, jj, kk; int px, py, ii, jj, kk;
int ppx, ppy, npx, npy; int ppx, ppy, npx, npy;
char direc; ch direc;
Plog(1,"sa_finish_mappix() \n"); Plog(1,"sa_finish_mappix() \n");
while (sa_Nstack) // find all pixels within enclosed area(s) while (sa_Nstack) // find all pixels within enclosed area(s)
{ {
kk = sa_Nstack - 1; // get last pixel in stack kk = sa_Nstack - 1; // get last pixel in stack
ii = sa_stack[kk]; ii = sa_stack[kk];
direc = sa_stackdirec[kk]; direc = sa_stackdirec[kk];
py = ii / Fpxb->ww; // reconstruct px, py py = ii / Fpxb->ww; // reconstruct px, py
skipping to change at line 1865 skipping to change at line 1862
if (zd_sela) zdialog_stuff(zd_sela,"blendwidth",0); if (zd_sela) zdialog_stuff(zd_sela,"blendwidth",0);
Fpaint2(); Fpaint2();
return; return;
} }
/******************************************************************************* */ /******************************************************************************* */
// Find the edge pixels surrounding the clicked pixel location. // Find the edge pixels surrounding the clicked pixel location.
// Trace around the edge outline to see if there is a gap. // Trace around the edge outline to see if there is a gap.
void m_select_find_gap(GtkWidget *, cchar *menu) void m_select_find_gap(GtkWidget *, ch *menu)
{ {
int sa_find_gap_dialog_event(zdialog *zd, cchar *event); int sa_find_gap_dialog_event(zdialog *zd, ch *event);
void sa_find_gap_mousefunc(); void sa_find_gap_mousefunc();
cchar *fmess = "Click near any position on the area outline. \n" ch *fmess = "Click near any position on the area outline. \n"
"Possible gaps in the outline will be found. \n" "Possible gaps in the outline will be found. \n"
"Press F1 for help"; "Press F1 for help";
zdialog *zd; zdialog *zd;
F1_help_topic = "find area gap"; F1_help_topic = "find area gap";
Plog(1,"m_select_find_gap \n"); Plog(1,"m_select_find_gap \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
skipping to change at line 1903 skipping to change at line 1900
zdialog_add_widget(zd,"hbox","hbmess","dialog",0,"space=3"); // each enclosed area zdialog_add_widget(zd,"hbox","hbmess","dialog",0,"space=3"); // each enclosed area
zdialog_add_widget(zd,"label","fmess","hbmess",fmess,"space=5"); zdialog_add_widget(zd,"label","fmess","hbmess",fmess,"space=5");
zdialog_run(zd,sa_find_gap_dialog_event,"save"); // run dialog zdialog_run(zd,sa_find_gap_dialog_event,"save"); // run dialog
takeMouse(sa_find_gap_mousefunc,dragcursor); // connect mouse function takeMouse(sa_find_gap_mousefunc,dragcursor); // connect mouse function
return; return;
} }
// dialog event and completion function // dialog event and completion function
int sa_find_gap_dialog_event(zdialog *zd, cchar *event) int sa_find_gap_dialog_event(zdialog *zd, ch *event)
{ {
void sa_find_gap_mousefunc(); void sa_find_gap_mousefunc();
if (strmatch(event,"escape")) zd->zstat = -2; // escape key if (strmatch(event,"escape")) zd->zstat = -2; // escape key
if (strmatch(event,"focus")) if (strmatch(event,"focus"))
takeMouse(sa_find_gap_mousefunc,dragcursor); // connect mouse function takeMouse(sa_find_gap_mousefunc,dragcursor); // connect mouse function
if (! zd->zstat) return 1; // wait for completion if (! zd->zstat) return 1; // wait for completion
zdialog_free(zd); zdialog_free(zd);
skipping to change at line 1929 skipping to change at line 1926
// mouse function - search area outline surrounding mouse click position // mouse function - search area outline surrounding mouse click position
void sa_find_gap_mousefunc() void sa_find_gap_mousefunc()
{ {
int rad, ii, jj, kk, nn, ff, np1, np2, npx; int rad, ii, jj, kk, nn, ff, np1, np2, npx;
static int Fbusy = 0; static int Fbusy = 0;
float angle; float angle;
int ww, hh, cc; int ww, hh, cc;
int mx, my, px, py, rx, ry; int mx, my, px, py, rx, ry;
char *pixmark = 0; ch *pixmark = 0;
cairo_t *cr = 0; cairo_t *cr = 0;
if (! sa_stat) return; if (! sa_stat) return;
if (! LMclick) return; // no left mouse click data if (! LMclick) return; // no left mouse click data
LMclick = 0; LMclick = 0;
sa_map_pixels(); // find edge pixels sa_map_pixels(); // find edge pixels
if (! sa_Npixel) return; if (! sa_Npixel) return;
skipping to change at line 1997 skipping to change at line 1994
if (nn != 2 || np1 == 0 || np2 == 0) { // no edge pixel with 2 neighbor if (nn != 2 || np1 == 0 || np2 == 0) { // no edge pixel with 2 neighbor
zmessage_post_bold(Mwin,"20/20",3,"cannot find area outline"); // edge pixels was found zmessage_post_bold(Mwin,"20/20",3,"cannot find area outline"); // edge pixels was found
goto cleanup; goto cleanup;
} }
sa_show(0,0); // hide area sa_show(0,0); // hide area
Fpaintnow(); Fpaintnow();
cr = draw_context_create(gdkwin,draw_context); cr = draw_context_create(gdkwin,draw_context);
pixmark = (char *) zmalloc(cc,"select_area"); // create pixel mark map pixmark = (ch *) zmalloc(cc,"select_area"); // create pixel mark map
for (ff = 0; ff < 2; ff++) for (ff = 0; ff < 2; ff++)
{ {
memset(pixmark,0,cc); // clear all pixel marks memset(pixmark,0,cc); // clear all pixel marks
pixmark[ii] = 1; // mark edge pixel pixmark[ii] = 1; // mark edge pixel
sa_stack[0] = np1; // put neighbor 1 pixel into stack sa_stack[0] = np1; // put neighbor 1 pixel into stack
sa_Nstack = 1; // stack count sa_Nstack = 1; // stack count
while (sa_Nstack) while (sa_Nstack)
skipping to change at line 2069 skipping to change at line 2066
namespace edgeblend_names namespace edgeblend_names
{ {
editfunc EFedgeblend; // edit function data editfunc EFedgeblend; // edit function data
int Eww, Ehh; // image dimensions int Eww, Ehh; // image dimensions
int radius, blend; int radius, blend;
} }
// menu function // menu function
void m_select_edgeblend(GtkWidget *, const char *menu) void m_select_edgeblend(GtkWidget *, ch *menu)
{ {
using namespace edgeblend_names; using namespace edgeblend_names;
int edgeblend_dialog_event(zdialog* zd, const char *event); int edgeblend_dialog_event(zdialog* zd, ch *event);
void edgeblend_mousefunc(); void edgeblend_mousefunc();
cchar *helptext = "Left-drag mouse along area \n" ch *helptext = "Left-drag mouse along area \n"
"edge to blend-out area edits. \n" "edge to blend-out area edits. \n"
"Right-drag to restore edits."; "Right-drag to restore edits.";
char text[40]; ch text[40];
F1_help_topic = "edge blend"; F1_help_topic = "edge blend";
Plog(1,"m_select_edgeblend \n"); Plog(1,"m_select_edgeblend \n");
if (CEF) { if (CEF) {
zmessageACK(Mwin,"finish current edit first"); zmessageACK(Mwin,"finish current edit first");
return; return;
} }
skipping to change at line 2179 skipping to change at line 2176
zdialog_fetch(zd,"blend",blend); zdialog_fetch(zd,"blend",blend);
takeMouse(edgeblend_mousefunc,0); // take mouse takeMouse(edgeblend_mousefunc,0); // take mouse
zdialog_run(zd,edgeblend_dialog_event,"save"); // run dialog - parallel zdialog_run(zd,edgeblend_dialog_event,"save"); // run dialog - parallel
return; return;
} }
// edgeblend dialog event and completion function // edgeblend dialog event and completion function
int edgeblend_dialog_event(zdialog *zd, const char *event) // edgeblend dialog event function int edgeblend_dialog_event(zdialog *zd, ch *event) // edgeblend dialog event function
{ {
using namespace edgeblend_names; using namespace edgeblend_names;
void edgeblend_mousefunc(); void edgeblend_mousefunc();
char text[40]; ch text[40];
int nn; int nn;
if (sa_stat < 3) { if (sa_stat < 3) {
zmessageACK(Mwin,"select area missing or not finished"); zmessageACK(Mwin,"select area missing or not finished");
zd->zstat = -2; zd->zstat = -2;
} }
if (! sa_edgecalc_done) sa_edgecalc(); if (! sa_edgecalc_done) sa_edgecalc();
if (strmatch(event,"escape")) zd->zstat = -2; // escape key - quit if (strmatch(event,"escape")) zd->zstat = -2; // escape key - quit
skipping to change at line 2356 skipping to change at line 2353
GdkPixbuf *pxbdsel; // pixbuf to show match colo rs GdkPixbuf *pxbdsel; // pixbuf to show match colo rs
int pxbsize, pxbmid, rs; // " size, middle pixel, r ow stride int pxbsize, pxbmid, rs; // " size, middle pixel, r ow stride
uint8 *pixels; // " pixel data uint8 *pixels; // " pixel data
float retRGB[3]; // retouch color for pixels retained float retRGB[3]; // retouch color for pixels retained
int Fretactive; // retouce color active or n ot int Fretactive; // retouce color active or n ot
int saveFBrgb[3]; // save/restore window backg round color int saveFBrgb[3]; // save/restore window backg round color
} }
// menu function // menu function
void m_copy_complex(GtkWidget *, cchar *) // 22.16 void m_copy_complex(GtkWidget *, ch *) // 22.16
{ {
using namespace copy_complex; using namespace copy_complex;
int copy_complex_dialog_event(zdialog *zd, cchar *event); int copy_complex_dialog_event(zdialog *zd, ch *event);
void copy_complex_mousefunc(); void copy_complex_mousefunc();
cchar *title = "Select/Copy Complex Shape"; ch *title = "Select/Copy Complex Shape";
cchar *rettip = "shift + left-click on image to set retouch color"; ch *rettip = "shift + left-click on image to set retouch color";
F1_help_topic = "copy/complex"; F1_help_topic = "copy/complex";
Plog(1,"m_copy_complex \n"); Plog(1,"m_copy_complex \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
if (CEF) { if (CEF) {
zmessageACK(Mwin,"complete pending edit first"); zmessageACK(Mwin,"complete pending edit first");
return; return;
skipping to change at line 2453 skipping to change at line 2450
zdialog_add_widget(zd,"hbox","hbmrad","dialog",0,"space=3"); zdialog_add_widget(zd,"hbox","hbmrad","dialog",0,"space=3");
zdialog_add_widget(zd,"label","labmrad","hbmrad","Mouse Radius","space=3"); zdialog_add_widget(zd,"label","labmrad","hbmrad","Mouse Radius","space=3");
zdialog_add_widget(zd,"hscale","mouserad","hbmrad","3|200|1|30","expand"); zdialog_add_widget(zd,"hscale","mouserad","hbmrad","3|200|1|30","expand");
zdialog_add_widget(zd,"label","mouserad2","hbmrad","30","space=3"); zdialog_add_widget(zd,"label","mouserad2","hbmrad","30","space=3");
zdialog_add_widget(zd,"hbox","hbdes","dialog",0,"space=3"); zdialog_add_widget(zd,"hbox","hbdes","dialog",0,"space=3");
zdialog_add_widget(zd,"label","labdsel","hbdes","deselect colors","space=3"); zdialog_add_widget(zd,"label","labdsel","hbdes","deselect colors","space=3");
zdialog_add_widget(zd,"hscale","dmatchlev","hbdes","10|99|1|85","expand"); zdialog_add_widget(zd,"hscale","dmatchlev","hbdes","10|99|1|85","expand");
zdialog_add_widget(zd,"label","dmatchlev2","hbdes","85","space=3"); zdialog_add_widget(zd,"label","dmatchlev2","hbdes","85","space=3");
zdialog_add_widget(zd,"image","dcolors","hbdes",(cchar *) pxbdsel); zdialog_add_widget(zd,"image","dcolors","hbdes",(ch *) pxbdsel);
zdialog_add_widget(zd,"hbox","hbret","dialog",0,"space=3"); zdialog_add_widget(zd,"hbox","hbret","dialog",0,"space=3");
zdialog_add_widget(zd,"label","labret","hbret","retouch color","space=3"); zdialog_add_widget(zd,"label","labret","hbret","retouch color","space=3");
zdialog_add_widget(zd,"colorbutt","retRGB","hbret","0|0|0"); zdialog_add_widget(zd,"colorbutt","retRGB","hbret","0|0|0");
zdialog_add_widget(zd,"label","space","hbret",0,"space=8"); zdialog_add_widget(zd,"label","space","hbret",0,"space=8");
zdialog_add_widget(zd,"check","retactive","hbret","activate"); zdialog_add_widget(zd,"check","retactive","hbret","activate");
zdialog_add_widget(zd,"hbox","hbtip","dialog"); zdialog_add_widget(zd,"hbox","hbtip","dialog");
zdialog_add_widget(zd,"label","labtip","hbtip",rettip,"space=3"); zdialog_add_widget(zd,"label","labtip","hbtip",rettip,"space=3");
zdialog_add_widget(zd,"hbox","hbtran","dialog",0,"space=15"); zdialog_add_widget(zd,"hbox","hbtran","dialog",0,"space=15");
skipping to change at line 2484 skipping to change at line 2481
zdialog_resize(zd,300,0); // run dialog zdialog_resize(zd,300,0); // run dialog
zdialog_run(zd,copy_complex_dialog_event,"save"); zdialog_run(zd,copy_complex_dialog_event,"save");
takeMouse(copy_complex_mousefunc,dragcursor); // capture mouse takeMouse(copy_complex_mousefunc,dragcursor); // capture mouse
return; return;
} }
// dialog event and completion function // dialog event and completion function
int copy_complex_dialog_event(zdialog *zd, cchar *event) int copy_complex_dialog_event(zdialog *zd, ch *event)
{ {
using namespace copy_complex; using namespace copy_complex;
void copy_complex_mousefunc(); void copy_complex_mousefunc();
int ii, px, py; int ii, px, py;
char text[20]; ch text[20];
cchar *ppc; ch *ppc;
float *pix0; float *pix0;
if (strmatch(event,"escape")) zd->zstat = -2; // escape key if (strmatch(event,"escape")) zd->zstat = -2; // escape key
if (! curr_file) zd->zstat = -2; // image went away if (! curr_file) zd->zstat = -2; // image went away
if (sa_stat < 3) zd->zstat = -2; // area gone if (sa_stat < 3) zd->zstat = -2; // area gone
if (strmatch(event,"cancel")) zd->zstat = 4; // from f_open() if (strmatch(event,"cancel")) zd->zstat = 4; // from f_open()
if (strmatch(event,"focus")) if (strmatch(event,"focus"))
takeMouse(copy_complex_mousefunc,dragcursor); takeMouse(copy_complex_mousefunc,dragcursor);
skipping to change at line 2569 skipping to change at line 2566
zdialog_stuff(zd,"dmatchlev2",text); zdialog_stuff(zd,"dmatchlev2",text);
return 1; return 1;
} }
// mouse function // mouse function
void copy_complex_mousefunc() void copy_complex_mousefunc()
{ {
using namespace copy_complex; using namespace copy_complex;
int copy_complex_ucomp(cchar *, cchar*); int copy_complex_ucomp(ch *, ch *);
int ii, jj, rx, ry, px, py; int ii, jj, rx, ry, px, py;
int mrad, rrad; int mrad, rrad;
uint8 *pix; uint8 *pix;
float *pix0, *pix1; float *pix0, *pix1;
float pixmatch, bestmatch; float pixmatch, bestmatch;
float Dmatchlev; float Dmatchlev;
float Dmatch = 0; float Dmatch = 0;
float f1, f2, alpha; float f1, f2, alpha;
char text[20]; ch text[20];
GdkPixbuf *pxbtemp = 0; GdkPixbuf *pxbtemp = 0;
if (LMclick && KBshiftkey) // shift + left mouse click if (LMclick && KBshiftkey) // shift + left mouse click
{ {
LMclick = 0; LMclick = 0;
pix1 = PXMpix(E1pxm,Mxclick,Myclick); // pick new retouch color from image pix1 = PXMpix(E1pxm,Mxclick,Myclick); // pick new retouch color from image
retRGB[0] = pix1[0]; retRGB[0] = pix1[0];
retRGB[1] = pix1[1]; retRGB[1] = pix1[1];
retRGB[2] = pix1[2]; retRGB[2] = pix1[2];
snprintf(text,20,"%.0f|%.0f|%.0f",retRGB[0],retRGB[1],retRGB[2]); snprintf(text,20,"%.0f|%.0f|%.0f",retRGB[0],retRGB[1],retRGB[2]);
skipping to change at line 2743 skipping to change at line 2740
LMclick = RMclick = Mxdrag = Mydrag = 0; LMclick = RMclick = Mxdrag = Mydrag = 0;
return; return;
} }
/******************************************************************************* */ /******************************************************************************* */
// menu function for show, hide, enable, disable, invert, clear // menu function for show, hide, enable, disable, invert, clear
// (also implemented as buttons in select area dialog) // (also implemented as buttons in select area dialog)
void m_select_show(GtkWidget *, cchar *menu) void m_select_show(GtkWidget *, ch *menu)
{ {
F1_help_topic = "show/hide area"; F1_help_topic = "show/hide area";
Plog(1,"m_select_show \n"); Plog(1,"m_select_show \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
sa_show(1,0); // show area sa_show(1,0); // show area
return; return;
} }
void m_select_hide(GtkWidget *, cchar *menu) void m_select_hide(GtkWidget *, ch *menu)
{ {
F1_help_topic = "show/hide area"; F1_help_topic = "show/hide area";
Plog(1,"m_select_hide \n"); Plog(1,"m_select_hide \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
sa_show(0,0); sa_show(0,0);
return; return;
} }
void m_select_enable(GtkWidget *, cchar *menu) void m_select_enable(GtkWidget *, ch *menu)
{ {
F1_help_topic = "enable/disable area"; F1_help_topic = "enable/disable area";
Plog(1,"m_select_enable \n"); Plog(1,"m_select_enable \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
sa_enable(); sa_enable();
return; return;
} }
void m_select_disable(GtkWidget *, cchar *menu) void m_select_disable(GtkWidget *, ch *menu)
{ {
F1_help_topic = "enable/disable area"; F1_help_topic = "enable/disable area";
Plog(1,"m_select_disable \n"); Plog(1,"m_select_disable \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
sa_disable(); sa_disable();
return; return;
} }
void m_select_invert(GtkWidget *, cchar *menu) void m_select_invert(GtkWidget *, ch *menu)
{ {
F1_help_topic = "invert area"; F1_help_topic = "invert area";
Plog(1,"m_select_invert \n"); Plog(1,"m_select_invert \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
sa_invert(); sa_invert();
return; return;
} }
void m_select_clear(GtkWidget *, cchar *menu) // delete the area void m_select_clear(GtkWidget *, ch *menu) // delete the area
{ {
F1_help_topic = "clear area"; F1_help_topic = "clear area";
Plog(1,"m_select_clear \n"); Plog(1,"m_select_clear \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
sa_clear(); sa_clear();
return; return;
} }
/******************************************************************************* */ /******************************************************************************* */
skipping to change at line 3057 skipping to change at line 3054
Fpaint2(); Fpaint2();
return; return;
} }
// compute distance from all pixels in area to nearest edge // compute distance from all pixels in area to nearest edge
// output: sa_pixmap[*] = 0/1/2+ = outside, edge, inside distance from edge // output: sa_pixmap[*] = 0/1/2+ = outside, edge, inside distance from edge
namespace sa_edgecalc_names namespace sa_edgecalc_names
{ {
uint16 *sa_edgepx, *sa_edgepy, *sa_edgedist; uint16 *sa_edgepx, *sa_edgepy, *sa_edgedist;
int sa_Nedge, edgecalc_thread_busy; int sa_Nedge;
} }
void sa_edgecalc() void sa_edgecalc()
{ {
using namespace sa_edgecalc_names; using namespace sa_edgecalc_names;
void * edgecalc_thread(void *arg); void * edgecalc_thread(void *arg);
int ii, nn, cc, px, py; int ii, nn, cc, px, py;
zdialog *zdp; zdialog *zdp;
if (! sa_stat) return; // area gone? if (! sa_stat) return; // area gone?
if (sa_edgecalc_done) return; // done already if (sa_edgecalc_done) return; // done already
if (sa_stat < 3) return; // area must be finished if (sa_stat < 3) return; // area must be finished
if (sa_stat != 3) return; // failed or canceled if (sa_stat != 3) return; // failed or canceled
if (sa_edgecalc_busy) return; // stop re-entry if (sa_edgecalc_busy) return; // stop re-entry
zdp = zmessage_post_bold(Mwin,"mouse",0,"edge distance calculation"); zdp = zmessage_post_bold(Mwin,"mouse",3,"edge distance calculation");
sa_edgecalc_busy = 1; sa_edgecalc_busy = 1;
cc = Fpxb->ww * Fpxb->hh * sizeof(uint16); // allocate memory for calculations cc = Fpxb->ww * Fpxb->hh * sizeof(uint16); // allocate memory for calculations
sa_edgedist = (uint16 *) zmalloc(cc,"select_area"); sa_edgedist = (uint16 *) zmalloc(cc,"select_area");
for (ii = nn = 0; ii < Fpxb->ww * Fpxb->hh; ii++) // count edge pixels in select area for (ii = nn = 0; ii < Fpxb->ww * Fpxb->hh; ii++) // count edge pixels in select area
if (sa_pixmap[ii] == 1) nn++; if (sa_pixmap[ii] == 1) nn++;
cc = nn * sizeof(uint16); cc = nn * sizeof(uint16);
skipping to change at line 3121 skipping to change at line 3118
sa_edgepx[nn] = px; sa_edgepx[nn] = px;
sa_edgepy[nn] = py; sa_edgepy[nn] = py;
nn++; nn++;
} }
sa_Nedge = nn; sa_Nedge = nn;
progress_reset(sa_Npixel); // progress counter goal progress_reset(sa_Npixel); // progress counter goal
Fescape = 1; Fwatchescape = 1;
// escapable function 22.50 // killable with escape key 23.1
edgecalc_thread_busy = 1; Fescape = 0;
start_detached_thread(edgecalc_thread,0); Ffuncbusy = 1;
while (edgecalc_thread_busy) zmainsleep(0.1);
// keep GTK alive
progress_reset(0); start_detached_thread(edgecalc_thread,0);
while (Ffuncbusy) zmainloop(0.1);
for (int ii = 0; ii < Fpxb->ww * Fpxb->hh; ii++) { if (Fescape) {
// copy sa_edgedist[] to sa_pixmap[] // aborted 23.1
if (sa_pixmap[ii] <= 1) continue; sa_blendwidth = 0;
// skip outside and edge pixels // reset blend width
sa_pixmap[ii] = sa_edgedist[ii]; if (zd_sela) zdialog_stuff(zd_sela,"blendwidth",0);
// interior pixel edge distance
} }
Fwatchescape = Fescape = 0;
progress_reset(0);
zdialog_free(zdp); zdialog_free(zdp);
zfree(sa_edgedist); // free memory zfree(sa_edgedist); // free memory
zfree(sa_edgepx); zfree(sa_edgepx);
zfree(sa_edgepy); zfree(sa_edgepy);
sa_edgecalc_done = 1;
// edge calculation available
if (Fescape > 1) sa_edgecalc_done = 0;
// canceled 22.50
Fescape = 0;
sa_edgecalc_busy = 0; sa_edgecalc_busy = 0;
return; return;
} }
void * edgecalc_thread(void *arg) // edgecalc thread function void * edgecalc_thread(void *arg) // edgecalc thread function
{ {
using namespace sa_edgecalc_names; using namespace sa_edgecalc_names;
void * edgecalc_wthread(void *arg); void * edgecalc_wthread(void *arg);
do_wthreads(edgecalc_wthread,NWT); // do worker threads do_wthreads(edgecalc_wthread,NWT); // do worker threads
edgecalc_thread_busy = 0;
if (! Fescape)
// not cancelled 23.1
{
sa_edgecalc_done = 1;
// edge calc. done
for (int ii = 0; ii < Fpxb->ww * Fpxb->hh; ii++) {
// copy sa_edgedist[] to sa_pixmap[]
if (sa_pixmap[ii] <= 1) continue;
// skip outside and edge pixels
sa_pixmap[ii] = sa_edgedist[ii];
// interior pixel edge distance
}
}
Ffuncbusy = 0;
return 0; return 0;
} }
void * edgecalc_wthread(void *arg) // edgecalc worker thread function void * edgecalc_wthread(void *arg) // edgecalc worker thread function
{ {
using namespace sa_edgecalc_names; using namespace sa_edgecalc_names;
void edgecalc_func(int px, int py); void edgecalc_func(int px, int py);
int index = *((int *) arg); int index = *((int *) arg);
skipping to change at line 3187 skipping to change at line 3196
{ {
for (px = midx-rad; px <= midx+rad; px += 2 * rad) // edges only, interior already done for (px = midx-rad; px <= midx+rad; px += 2 * rad) // edges only, interior already done
for (py = midy-rad+index; py <= midy+rad; py += NWT) for (py = midy-rad+index; py <= midy+rad; py += NWT)
{ {
if (px < 0 || px > Fpxb->ww-1) continue; if (px < 0 || px > Fpxb->ww-1) continue;
if (py < 0 || py > Fpxb->hh-1) continue; if (py < 0 || py > Fpxb->hh-1) continue;
ii = py * Fpxb->ww + px; ii = py * Fpxb->ww + px;
if (! sa_pixmap[ii]) continue; if (! sa_pixmap[ii]) continue;
if (sa_edgedist[ii]) continue; if (sa_edgedist[ii]) continue;
edgecalc_func(px,py); edgecalc_func(px,py);
if (Fescape > 1) break; // killed if (Fescape) break; // killed
} }
for (py = midy-rad; py <= midy+rad; py += 2 * rad) for (py = midy-rad; py <= midy+rad; py += 2 * rad)
for (px = midx-rad+index; px <= midx+rad; px += NWT) for (px = midx-rad+index; px <= midx+rad; px += NWT)
{ {
if (px < 0 || px > Fpxb->ww-1) continue; if (px < 0 || px > Fpxb->ww-1) continue;
if (py < 0 || py > Fpxb->hh-1) continue; if (py < 0 || py > Fpxb->hh-1) continue;
ii = py * Fpxb->ww + px; ii = py * Fpxb->ww + px;
if (! sa_pixmap[ii]) continue; if (! sa_pixmap[ii]) continue;
if (sa_edgedist[ii]) continue; if (sa_edgedist[ii]) continue;
edgecalc_func(px,py); edgecalc_func(px,py);
if (Fescape > 1) break; // killed if (Fescape) break; // killed
} }
} }
return 0; return 0;
} }
// Find the nearest edge pixel for a given pixel. // Find the nearest edge pixel for a given pixel.
// For all pixels in a line from the given pixel to the edge pixel, // For all pixels in a line from the given pixel to the edge pixel,
// the same edge pixel is used to compute edge distance. // the same edge pixel is used to compute edge distance.
skipping to change at line 3377 skipping to change at line 3386
int sacp_porgx, sacp_porgy; // pasted area origin in image int sacp_porgx, sacp_porgy; // pasted area origin in image
int sacp_pww, sacp_phh; // pasted area dimensions int sacp_pww, sacp_phh; // pasted area dimensions
editfunc EFpaste; editfunc EFpaste;
} }
// Save a select area in memory to a disk PNG file. // Save a select area in memory to a disk PNG file.
// For menu "Copy" use default file: ~/.fotoxx/saved_areas/copied_area.png // For menu "Copy" use default file: ~/.fotoxx/saved_areas/copied_area.png
// For menu "Save Area" use file name from user input. // For menu "Save Area" use file name from user input.
void m_select_copysave(GtkWidget *, cchar *menu); void m_select_copysave(GtkWidget *, ch *menu);
void m_select_copy(GtkWidget *, cchar *) void m_select_copy(GtkWidget *, ch *)
{ {
Plog(1,"m_select_copy \n"); Plog(1,"m_select_copy \n");
m_select_copysave(0,"copy"); m_select_copysave(0,"copy");
return; return;
} }
void m_select_save(GtkWidget *, cchar *) void m_select_save(GtkWidget *, ch *)
{ {
Plog(1,"m_select_save \n"); Plog(1,"m_select_save \n");
m_select_copysave(0,"save"); m_select_copysave(0,"save");
return; return;
} }
void m_select_copysave(GtkWidget *, cchar *menu) void m_select_copysave(GtkWidget *, ch *menu)
{ {
using namespace sa_diskfile; using namespace sa_diskfile;
int ii, px1, py1, px2, py2, dist; int ii, px1, py1, px2, py2, dist;
int ww, nc, pcc; int ww, nc, pcc;
float *pix1, *pix2; float *pix1, *pix2;
char *pp, *file; ch *pp, *file;
char filename[100]; ch filename[200];
if (strmatch(menu,"copy")) if (strmatch(menu,"copy"))
F1_help_topic = "copy/paste area"; F1_help_topic = "copy/paste area";
else if (strmatch(menu,"save")) else if (strmatch(menu,"save"))
F1_help_topic = "load/save area"; F1_help_topic = "load/save area";
else Plog(0,"F1 topic error \n"); else Plog(0,"F1 topic error \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
if (! sa_stat) return; // no selected area if (! sa_stat) return; // no selected area
skipping to change at line 3449 skipping to change at line 3458
pix1 = PXMpix(E0pxm,px1,py1); // copy to area PXM pix1 = PXMpix(E0pxm,px1,py1); // copy to area PXM
pix2 = PXMpix(sacp_pxm,px2,py2); pix2 = PXMpix(sacp_pxm,px2,py2);
memcpy(pix2,pix1,pcc); // copy RGB(A) data memcpy(pix2,pix1,pcc); // copy RGB(A) data
ii = py1 * ww + px1; ii = py1 * ww + px1;
dist = sa_pixmap[ii]; // 0/1/2+ = outside/edge/inside edge dist. dist = sa_pixmap[ii]; // 0/1/2+ = outside/edge/inside edge dist.
if (dist == 0) pix2[3] = 0; // outside pixel, transparent if (dist == 0) pix2[3] = 0; // outside pixel, transparent
else pix2[3] = 255; // edge or inside, opaque else pix2[3] = 255; // edge or inside, opaque
} }
if (strmatch(menu,"copy")) { if (strmatch(menu,"copy")) {
snprintf(filename,100,"%s/copied_area.png",saved_areas_folder); // save to default PNG file snprintf(filename,200,"%s/copied_area.png",saved_areas_folder); // save to default PNG file
PXM_PNG_save(sacp_pxm,filename,16); PXM_PNG_save(sacp_pxm,filename,16);
return; return;
} }
pp = zgetfile("save area as a PNG file",MWIN,"save",saved_areas_folder); // get file name from user pp = zgetfile("save area as a PNG file",MWIN,"save",saved_areas_folder); // get file name from user
if (! pp) return; if (! pp) return;
file = zstrdup(pp,"select_area",8); file = zstrdup(pp,"select_area",8);
zfree(pp); zfree(pp);
pp = strrchr(file,'/'); pp = strrchr(file,'/');
pp = strcasestr(pp,".png"); pp = strcasestr(pp,".png");
if (! pp) strcat(file,".png"); if (! pp) strcat(file,".png");
PXM_PNG_save(sacp_pxm,file,16); // use PNG-16 file PXM_PNG_save(sacp_pxm,file,16); // use PNG-16 file
zfree(file); zfree(file);
return; return;
} }
// Read a select area from a disk PNG file. // Read a select area from a disk PNG file.
void m_select_load(GtkWidget *, cchar *menu) void m_select_load(GtkWidget *, ch *menu)
{ {
using namespace sa_diskfile; using namespace sa_diskfile;
void select_paste(GtkWidget *, cchar *); void select_paste(GtkWidget *, ch *);
PXM *pxmtemp; PXM *pxmtemp;
char *file; ch *file;
float *pix1, *pix2; float *pix1, *pix2;
int px, py, nc, pcc; int px, py, nc, pcc;
F1_help_topic = "load/save area"; F1_help_topic = "load/save area";
Plog(1,"m_select_load \n"); Plog(1,"m_select_load \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
PXM_free(sacp_pxm); // free prior if any PXM_free(sacp_pxm); // free prior if any
skipping to change at line 3521 skipping to change at line 3530
} }
PXM_free(pxmtemp); PXM_free(pxmtemp);
select_paste(0,"paste area"); // interactive move/resize area image select_paste(0,"paste area"); // interactive move/resize area image
return; return;
} }
// paste the area last copied on to the current image // paste the area last copied on to the current image
// uses the default file from "copy area" menu (above) // uses the default file from "copy area" menu (above)
void m_select_paste(GtkWidget *, cchar *menu) void m_select_paste(GtkWidget *, ch *menu)
{ {
using namespace sa_diskfile; using namespace sa_diskfile;
void select_paste(GtkWidget *, cchar *); void select_paste(GtkWidget *, ch *);
PXM *pxmtemp; PXM *pxmtemp;
char filename[100]; ch filename[200];
float *pix1, *pix2; float *pix1, *pix2;
int px, py, nc, pcc; int px, py, nc, pcc;
F1_help_topic = "copy/paste area"; F1_help_topic = "copy/paste area";
Plog(1,"m_select_paste \n"); Plog(1,"m_select_paste \n");
if (FGWM != 'F') return; if (FGWM != 'F') return;
PXM_free(sacp_pxm); // free prior if any PXM_free(sacp_pxm); // free prior if any
PXM_free(sacpR_pxm); PXM_free(sacpR_pxm);
snprintf(filename,100,"%s/copied_area.png",saved_areas_folder); snprintf(filename,200,"%s/copied_area.png",saved_areas_folder);
pxmtemp = PXM_load(filename,1); // load image file pxmtemp = PXM_load(filename,1); // load image file
if (! pxmtemp) return; if (! pxmtemp) return;
nc = pxmtemp->nc; nc = pxmtemp->nc;
pcc = nc * sizeof(float); pcc = nc * sizeof(float);
sacp_ww = pxmtemp->ww; // image dimensiona sacp_ww = pxmtemp->ww; // image dimensiona
sacp_hh = pxmtemp->hh; sacp_hh = pxmtemp->hh;
sacp_pxm = PXM_make(sacp_ww,sacp_hh,4); // alpha channel sacp_pxm = PXM_make(sacp_ww,sacp_hh,4); // alpha channel
skipping to change at line 3571 skipping to change at line 3580
} }
PXM_free(pxmtemp); PXM_free(pxmtemp);
select_paste(0,"paste area"); // interactive move/resize area image select_paste(0,"paste area"); // interactive move/resize area image
return; return;
} }
// paste select area in memory into current image // paste select area in memory into current image
// this is an edit function - select area image is copied into main image // this is an edit function - select area image is copied into main image
void select_paste(GtkWidget *, cchar *menu) void select_paste(GtkWidget *, ch *menu)
{ {
using namespace sa_diskfile; using namespace sa_diskfile;
void select_paste_image(); void select_paste_image();
int select_paste_dialog_event(zdialog *, cchar *event); int select_paste_dialog_event(zdialog *, ch *event);
void select_paste_mousefunc(); void select_paste_mousefunc();
cchar *dragmess = "position with mouse click/drag"; ch *dragmess = "position with mouse click/drag";
if (sa_edgecalc_busy) return; // wait until done if (sa_edgecalc_busy) return; // wait until done
if (! sacp_pxm) return; // nothing to paste if (! sacp_pxm) return; // nothing to paste
sa_clear(); // clear area if present sa_clear(); // clear area if present
EFpaste.menufunc = select_paste; EFpaste.menufunc = select_paste;
EFpaste.menuname = "paste area"; EFpaste.menuname = "paste area";
EFpaste.Frestart = 1; // make restartable EFpaste.Frestart = 1; // make restartable
skipping to change at line 3685 skipping to change at line 3694
takeMouse(select_paste_mousefunc,0); // connect mouse function takeMouse(select_paste_mousefunc,0); // connect mouse function
return; return;
} }
// Dialog event and completion callback function. // Dialog event and completion callback function.
// Get dialog values and convert image. When done, commit edited image // Get dialog values and convert image. When done, commit edited image
// (with pasted area) and set up a new select area for the pasted area, // (with pasted area) and set up a new select area for the pasted area,
// allowing further editing of the area. // allowing further editing of the area.
int select_paste_dialog_event(zdialog *zd, cchar *event) int select_paste_dialog_event(zdialog *zd, ch *event)
{ {
using namespace sa_diskfile; using namespace sa_diskfile;
void select_paste_mousefunc(); void select_paste_mousefunc();
void select_paste_image(); void select_paste_image();
void select_paste_adjust(); void select_paste_adjust();
int ww, hh; int ww, hh;
PXM *pxm_temp; PXM *pxm_temp;
 End of changes. 73 change blocks. 
95 lines changed or deleted 105 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)