/********************************************************************************

   Fotocx - edit photos and manage collections

   Copyright 2007-2026 Michael Cornelison
   source code URL: https://kornelix.net
   contact: mkornelix@gmail.com

   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
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version. See https://www.gnu.org/licenses

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the GNU General Public License for more details.

*********************************************************************************/

#include <clutter-gtk/clutter-gtk.h>
#include <sys/wait.h>
#include <tiffio.h>
#include <png.h>
#include "jpeglib.h"
#include "zfuncs.h"

//  Fotocx definitions

#define Frelease  "fotocx-26.4"                                                        //  current release     26.4
#define Flicense  "Free software - GNU General Public License v.3"
#define Fwebsite  "https://kornelix.net/fotocx/fotocx.html"                            //  fotocx web site
#define Fgitlab   "https://gitlab.com/fotocx"                                          //  GitLab home
#define Fprivacy  "https://gitlab.com/fotocx/fotocx/wikis/privacy"                     //  Gitlab privacy policy
#define Fcontact  "mkornelix@gmail.com"
#define MEGA (1024.0 * 1024.0)                                                         //  2**20
#define GIGA (1024.0 * MEGA)                                                           //  2**30
#define PI 3.141592654
#define RAD (180.0/PI)

//  PXM and PXB pixel address arithmetic                                               //  PXM / PXB >4 GB

#define PXMpix(PXM,px,py) (PXM->pixels+(int64)(1)*(py)*(PXM->rs)+(px)*(PXM->nc))
#define PXBpix(PXB,px,py) (PXB->pixels+(int64)(1)*(py)*(PXB->rs)+(px)*(PXB->nc))
#define PIXBRIGHT(pix) (0.25*(pix)[0]+0.65*(pix)[1]+0.10*(pix)[2])

//  compile time limits that could be increased

#define XSMP 64                                                                        //  max. SMP compute threads to use
#define thumbfilesize 512                                                              //  thumbnail file pixel size
#define maxtopfolders 500                                                              //  max. no. of top image folders
#define indexrecl 2000                                                                 //  max. image index rec. (>XFCC)
#define maximages 1000000                                                              //  max. image files supported
#define maxgallery 100000                                                              //  max. gallery/folder files supported
#define maxworldcities 100000                                                          //  max entries in worldcities.txt
#define SFmax 100000                                                                   //  max files for select_files()
#define ANCC   100                                                                     //  max album name
#define AFCC   300                                                                     //  max album file name (path)
#define maxalbums 300                                                                  //  max total albums
#define maxalbumfiles maxgallery                                                       //  max files in one album

//  metadata tags for embedded image metadata

#define meta_fdate_tag "FileModifyDate"                                                //  yyyy:mm:dd hh:mm:ss
#define meta_fsize_tag "FileSize"                                                      //  bytes
#define meta_pdate_tag "DateTimeOriginal"                                              //  photo date/time
#define meta_psize_tag "ImageSize"                                                     //  image pixel size: 2345 1234
#define meta_bpc_tag "BitsPerSample"                                                   //  8/16/raw BPC
#define meta_rating_tag "Rating"                                                       //  star rating, 0-5 stars
#define meta_keywords_tag "Keywords"                                                   //  comma-delimited list for image search
#define meta_title_tag "Title"                                                         //  others: headline, event, abstract
#define meta_desc_tag "Description"                                                    //  others: imagedescription, subject ...
#define meta_city_tag "City"                                                           //  city or location name (geotags)
#define meta_country_tag "Country"                                                     //  country name
#define meta_gps_tag "GPSposition"                                                     //  GPS coordinates  123.45678 22.34567
#define meta_make_tag "Make"                                                           //  camera make
#define meta_model_tag "Model"                                                         //  camera model
#define meta_lens_tag "Lens"                                                           //  camera lens
#define meta_exp_tag "ExposureTime"                                                    //  photo exposure time
#define meta_fnum_tag "FNumber"                                                        //  F-number or aperture
#define meta_flen_tag "FocalLength"                                                    //  focal length, real
#define meta_iso_tag "ISO"                                                             //  ISO speed/sensitivity
#define meta_fl35_tag "FocalLengthIn35mmFormat"                                        //  35mm equivalent (used by pano)
#define meta_creator_tag "Creator"                                                     //  others: artist, author, photographer ...
#define meta_orientation_tag "Orientation"                                             //  orientation (number format)
#define meta_rollangle_tag "RollAngle"                                                 //  roll angle - canera tilt error
#define meta_edithist_tag "ImageHistory"                                               //  tag for fotocx edit history
#define edithistXcc 200                                                                //  max edit hist cc (per edit step)
#define meta_copyright_tag "Copyright"                                                 //  image copyright

#define maxkeywords 10000                                                              //  max overall keywords
#define maxkeywordcats 200                                                             //  max keyword categories
#define keywordXcc  50                                                                 //  max cc for one keyword or category name
#define catgkeywordsXcc 20000                                                          //  max keywords cc for catg (textwidget limit)
#define filekeywordsXcc 1000                                                           //  max keywords cc for one image file
#define batchkeywordsXcc 1000                                                          //  max keywords cc for batch add tags
#define searchkeywordsXcc 500                                                          //  max keywords cc for search tags
#define recentkeywordsXcc 300                                                          //  max keywords cc for recent tags
#define maxcaptags 20                                                                  //  max tags in image popup captions
#define capsXcc 2000                                                                   //  max text in image popup captions
#define maxbatchtags 50                                                                //  max metadata tags in batch report
#define metatagXcc 80                                                                  //  max cc for metadata tag name
#define metadataXcc 2000                                                               //  max cc for metadata tag data          26.0
#define xmetaXtags 20                                                                  //  max extra indexed metadata tags       26.0
#define xmetaXcc 2000                                                                  //  max extra indexed metadata total cc   26.0

//  GTK/GDK definitions

#define TEXTWIN GTK_TEXT_WINDOW_TEXT
#define NODITHER GDK_RGB_DITHER_NONE
#define ALWAYS GTK_POLICY_ALWAYS
#define NEVER GTK_POLICY_NEVER
#define AUTO GTK_POLICY_AUTOMATIC
#define GDKRGB GDK_COLORSPACE_RGB
#define LINEATTRIBUTES GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER
#define BILINEAR GDK_INTERP_BILINEAR
#define HYPER GDK_INTERP_HYPER
#define NEAREST GDK_INTERP_NEAREST
#define SCROLLWIN GTK_SCROLLED_WINDOW
#define VERTICAL GTK_ORIENTATION_VERTICAL
#define HORIZONTAL GTK_ORIENTATION_HORIZONTAL
#define MWIN GTK_WINDOW(Mwin)

//  externals from zfuncs module

namespace zfuncs {
   extern GdkDisplay    *display;                                                      //  X11 workstation (KB, mouse, screen)
   extern GdkScreen     *screen;                                                       //  monitor (screen)
   extern GdkDevice     *mouse;                                                        //  pointer device
   extern GtkSettings   *settings;                                                     //  screen settings
   extern GtkWidget     *mainwin;                                                      //  main window for zfuncs parent
   extern ch            *build_date_time;                                              //  build date and time
   extern ch            *progexe;                                                      //  executable path name
   extern int           Fescape;                                                       //  zdialog, escape key pressed
   extern int           Fshutdown;                                                     //  app shutdown is underway
   extern int           monitor_ww, monitor_hh;                                        //  monitor pixel dimensions
   extern ch            *appfont;                                                      //  app font ("sans 10")
   extern int           appfontsize;                                                   //  app font size
   extern ch            zappname[40];                                                  //  app name/version
   extern ch            logfile[200];                                                  //  app log file
   extern ch            zimagedir[200];                                                //  where app image files live
   extern int           Nmalloc, Nstrdup, Nfree;                                       //  malloc() strdup() free() counters
   extern int           vmenuclickposn;                                                //  Vmenu icon click position, 0-100
   extern int           vmenuclickbutton;                                              //  Vmenu button: 1/3 = left/right mouse
   extern int           vmenustop;                                                     //  Vmenu setupfunc() stop flag
   extern int           zdialog_count;                                                 //  zdialog count (new - free)
   extern int           zdialog_busy;                                                  //  open zdialog count (run - destroy)
   extern zdialog       *zdialog_list[zdialog_max];                                    //  active zdialog list
   extern pthread_t     tid_main;                                                      //  main() thread ID
   extern float         splcurve_minx;                                                 //  min. anchor point dist, % scale
   extern ch            *zappcrash_context1, *zappcrash_context2;                      //  zappcrash context data
}

//  Image index record - xxrec_tab[]  in-memory info for image files

#define NKX 19                                                                         //  metadata tags in xxrec_tab[]
EX ch   *tagnamex[NKX];                                                                //  initialization in fotocx.cc           25.1
EX ch   *tagname_alt_title[3];                                                         //  alt. image title tag names            ATD
EX ch   *tagname_alt_desc[6];                                                          //  alt. description tag names            ATD

struct xxrec_t
{
   ch          *file = 0;                                                              //  - image filespec
   ch          fdate[20];                                                              //  0 file date, "yyyy:mm:dd hh:mm:ss"
   ch          fsize[16];                                                              //  1 file size, bytes "12345678"
   ch          pdate[20];                                                              //  2 photo date, "yyyy:mm:dd hh:mm:ss"
   ch          psize[16];                                                              //  3 pixel size, "12345 23456"
   ch          bpc[4];                                                                 //  4 bits/color "8" "16" "12" (raw)
   ch          rating[4];                                                              //  5 rating, "0" to "5" stars
   ch          *keywords = 0;                                                          //  6 keywords
   ch          *title = 0;                                                             //  7 title
   ch          *desc = 0;                                                              //  8 description
   ch          location[40];                                                           //  9 city, park, monument ...
   ch          country[40];                                                            //  10 country
   ch          gps_data[24];                                                           //  11 GPS coordinates "123.45678 -23.45678"
   ch          make[20], model[20], lens[20];                                          //  12-14 camera data
   ch          exp[12], fn[12], fl[12], iso[12];                                       //  15-18 exposure data
   ch          *xmeta;                                                                 //  19 extra indexed metadata
};

EX xxrec_t     **xxrec_tab;                                                            //  image index table, filename sequence
EX int         Nxxrec;                                                                 //  count, < maximages

EX ch          *xmeta_tags[xmetaXtags];                                                //  extra indexed metadata tag names
EX int         xmetaNtags;                                                             //  extra indexed metadata tag count      26.0

//  gallery files record

struct Gindex_t  {                                                                     //  gallery index
   ch       *file = 0;                                                                 //  /folder.../filename
   int      folder;                                                                    //  flag, this is a folder
   ch       fdate[16];                                                                 //  file date: yyyymmddhhmmss
   ch       pdate[16];                                                                 //  photo date: yyyymmddhhmmss
   uint     fsize;                                                                     //  file size, bytes
   uint     psize;                                                                     //  image size, pixels
   ch       *mdata1 = 0;                                                               //  fixed text for metadata report
   ch       *mdata2 = 0;                                                               //  variable text for metadata report
};

enum FTYPE { IMAGE, RAW, VIDEO, FDIR, THUMB, OTHER, FNF };                             //  file types, FNF = file not found
enum GTYPE { TNONE, FOLDER, SEARCH, META, RECENT, NEWEST, ALBUM };                     //  gallery types
enum GSORT { SNONE, FNAME, FNUMBER, FDATE, PDATE, FSIZE, PSIZE, MDATA };               //  gallery sort types
enum GSEQ  { QNONE, ASCEND, DESCEND };                                                 //  gallery sort sequence

//  externals from f.gallery

namespace navi                                                                         //  gallery() data
{
   extern Gindex_t *Gindex;                                                            //  gallery index
   extern int      Gmdrows;                                                            //  text rows in metadata list
   extern int      Gfiles;                                                             //  gallery file count (images + subdirs)
   extern int      Gfolders;                                                           //  gallery subfolder count
   extern int      Gimages;                                                            //  gallery image file count
   extern ch       *galleryname;                                                       //  folder path or gallery type name
   extern GTYPE    gallerytype;                                                        //  gallery type: folder, recent, etc.
   extern GSORT    gallerysort;                                                        //  filename/file-date/photo-date
   extern GSEQ     galleryseq;                                                         //  ascending/descending
   extern int      gallerypainted;                                                     //  gallery paint is complete
   extern int      galleryposn;                                                        //  gallery target scroll position
   extern int      scrollposn;                                                         //  current scroll position
   extern int      xwinW, xwinH;                                                       //  image gallery window size
   extern int      thumbsize;                                                          //  curr. thumbnail display size
   extern int      genthumbs;                                                          //  counts thumbnails generated
   extern double   thumbcache_MB;                                                      //  thumbnail cache size, MB

   int    gallery_paint(GtkWidget *, cairo_t *);                                       //  gallery window paint function
   void   menufuncx(GtkWidget *, ch *menu);                                            //  gallery menu buttons function
   void   changefolder(GtkWidget *widget, GdkEventButton *event);                      //  gallery folder change function
   void   newtop(GtkWidget *widget, GdkEventButton *event);                            //  gallery change top folder function
   int    mouse_event(GtkWidget *, GdkEvent *, void *);                                //  gallery window mouse event function
   ch   * gallery_dragfile();                                                          //  gallery window file drag function
   void   gallery_dropfile(int mx, int my, ch *file);                                  //  gallery window file drop function
   int    KBaction(ch *action);                                                        //  gallery window KB key function
}

EX ch       *SelFiles[SFmax];                                                          //  select_files(), selected files list
EX int      SFcount;                                                                   //  select_files(), file count

//  GTK etc. parameters

EX GtkWidget      *Mwin, *MWhbox, *MWvbox, *MWmenu;                                    //  main window containers
EX GtkWidget      *Fhbox, *Fvbox, *Fpanel, *Fpanlab, *Fdrawin;                         //  F window widgets, file view
EX GtkWidget      *Ghbox, *Gvbox, *Gsep, *Gpanel, *Gtop;                               //  G window widgets, gallery view
EX GtkWidget      *Gscroll, *Gdrawin;
EX GtkAdjustment  *Gadjust;
EX GtkWidget      *Mhbox, *Mvbox;                                                      //  M window widgets, map view
EX GtkWidget      *Cdrawin;                                                            //  curr. drawing window, Fdrawin
EX GdkWindow      *gdkwin;                                                             //  corresp. GDK window
EX PIXBUF         *BGpixbuf;                                                           //  window background pixbuf

EX GdkCursor      *arrowcursor;                                                        //  main window cursors
EX GdkCursor      *dragcursor;
EX GdkCursor      *targcursor;
EX GdkCursor      *drawcursor;
EX GdkCursor      *blankcursor;
EX GdkCursor      *dotcursor;

EX int      BLACK[3], WHITE[3], RED[3], GREEN[3], BLUE[3];                             //  RGB values 0-255
EX int      LINE_COLOR[3];                                                             //  line drawing color, one of the above

EX draw_context_t  draw_context;                                                       //  GDK window drawing context

//  user preferences and settings

EX ch       *menu_style;                                                               //  menu style: icons/text/both
EX int      FBrgb[3];                                                                  //  F view background color, RGB 0-255
EX int      GBrgb[3];                                                                  //  G view background color, RGB 0-255
EX int      MFrgb[3];                                                                  //  menu font color, RGB 0-255
EX int      MBrgb[3];                                                                  //  menu background color, RGB 0-255
EX int      iconsize;                                                                  //  menu icon size
EX int      SMPcount;                                                                  //  SMP processors ('cores') to use
EX ch       *application_font;                                                         //  menu + dialog font e.g. "sans 10"     26.3
EX ch       *startdisplay;                                                             //  startup display option
EX ch       *startalbum;                                                               //  start album: file name
EX ch       *startfolder;                                                              //  start folder
EX ch       *startfile;                                                                //  start file
EX int      Findexlev;                                                                 //  0/1/2 = none/old/old+new image files
EX int      FMindexlev;                                                                //  Findexlev if start via file manager
EX int      Xindexlev;                                                                 //  actual index level, 0/1/2             25.1
EX int      Findexnew;                                                                 //  new/mod files since full index        25.1
EX int      Fdragopt;                                                                  //  1/2 = 1x drag / magnified scroll
EX int      Flastversion;                                                              //  gallery shows last versions only
EX ch       *ImagePosn;                                                                //  F-view image posn: left/center/right
EX int      Faskquit;                                                                  //  ask to quit option
EX int      Fshowhidden;                                                               //  show hidden files option              26.4
EX int      zoomcount;                                                                 //  zoom count to reach 2x (1-8)
EX float    zoomratio;                                                                 //  corresp. zoom ratio: 2**(1/zoomcount)
EX int      map_dotsize;                                                               //  map dot size / mouse capture size
EX int      captext_cc[2];                                                             //  captions text line cc range
EX int      jpeg_def_quality;                                                          //  default jpeg save quality
EX int      tiff_comp_method;                                                          //  TIFF file compression method
EX ch       *raw_loader_command;                                                       //  RAW file loader command
EX int      Fraw_match_embed;                                                          //  match RAW colors to embedded image
EX ch       *RAWfiletypes;                                                             //  recognized RAW files: .raw .rw2 ...
EX ch       *VIDEOfiletypes;                                                           //  recognized video files: .mov .mp4 ...

//  menu name and function table

typedef void menufunc_t(GtkWidget *,ch *);                                             //  menu function type

struct menutab_t {
   GtkWidget    *topmenu;                                                              //  parent menu
   ch           *menu = 0;                                                             //  menu text
   ch           *icon = 0;                                                             //  menu icon
   ch           *desc = 0;                                                             //  menu short description (tooltip)
   menufunc_t   *func;                                                                 //  menu function (GtkWidget *, ch *)
   ch           *arg = 0;                                                              //  argument
};

#define CCC (XFCC*2+200)                                                               //  max. command line size
EX ch       command[CCC];                                                              //  (command, parameters, 2 filespecs)

#define maxmenus 300
EX menutab_t   menutab[maxmenus];
EX int         Nmenus;

//  KB shortcut tables

struct KBsftab_t {                                                                     //  eligible menus for KB shortcut
   ch          *menu = 0;                                                              //  menu name
   menufunc_t  *func;                                                                  //  function
   ch          *arg = 0;                                                               //  argument
};

#define maxkbsf 200                                                                    //  functions that can have KB shortcuts
EX KBsftab_t   KBsftab[maxkbsf];
EX int         Nkbsf;

struct KBsutab_t {                                                                     //  user-defined shortcuts
   ch          *key = 0;                                                               //  key name, e.g. "Shift+U"
   ch          *menu = 0;                                                              //  menu name, e.g. "Redo"
};

#define maxkbsu 100                                                                    //  max. KB shortcuts
EX KBsutab_t   KBsutab[maxkbsu];
EX int         Nkbsu;

//  general parameters

EX int         wwhh_limit1;                                                            //  max. image width or height            26.3
EX int         wwhh_limit2;                                                            //  max. image width x height             26.3
EX int         Fdevelop;                                                               //  flag, show developer menu
EX ch          desktopname[100];                                                       //  locale specific desktop folder
EX ch          *Prelease;                                                              //  prior fotocx version
EX int         mwgeom[4];                                                              //  main window position and size
EX pid_t       fotocxPID;                                                              //  my process PID
EX int         *Nval;                                                                  //  static integer values 0-maximages
EX ch          FGM;                                                                    //  curr. view mode: 'F' 'G' 'M'
EX ch          PFGM;                                                                   //  prior view mode
EX int         Fdcraw;                                                                 //  flag, dcraw installed
EX int         Fexiftool;                                                              //  flag, exiftool installed
EX int         Fheif;                                                                  //  flag, heif-convert installed
EX int         Fjp2;                                                                   //  flag, opj_decompress installed
EX int         Fwebp;                                                                  //  flag, dwebp installed
EX int         Fvlc;                                                                   //  flag, vlc installed
EX int         Ffmpeg;                                                                 //  flag, ffmpeg installed
EX int         Faddr2line;                                                             //  flag, addr2line installed
EX int         Fpaintrequest;                                                          //  window paint request pending
EX int         Fpaintlock;                                                             //  main window paint is blocked
EX int         Fmetamod;                                                               //  image metadata unsaved changes
EX int         Ffullscreen;                                                            //  flag, window is fullscreen
EX int         Fpanelshow;                                                             //  show or hide F view top panel
EX int         Fmashup;                                                                //  flag, mashup function is active
EX int         Fslideshow;                                                             //  flag, slide show is active
EX int         Fview360;                                                               //  flag, view360 function is active
EX int         NFbusy;                                                                 //  no. functions busy/working
EX int         Frecent;                                                                //  start with recent files gallery
EX int         Fnew;                                                                   //  start with newly added files gallery
EX int         Fprev;                                                                  //  start with previous file
EX int         Fblank;                                                                 //  start with blank window
EX int         Fmousevents;                                                            //  show popup text of mouse events
EX ch          *topmenu;                                                               //  latest top-menu selection
EX ch          *initial_menu;                                                          //  menu on command line
EX ch          *initial_file;                                                          //  file name on command line
EX ch          *initial_album;                                                         //  album name on command line
EX ch          *video_command;                                                         //  command to show video file
EX ch          *F1_help_topic;                                                         //  current function help topic
EX int         Fcaps;                                                                  //  toggle captions on or off
EX ch          *topfolders[maxtopfolders];                                             //  user top-level image folders
EX int         Ntopfolders;                                                            //  topfolders[] count
EX ch          *misstops[maxtopfolders];                                               //  missing top folders (not mounted)
EX int         Nmisstops;                                                              //  missing top folders count
EX ch          *blacklist[1000];                                                       //  list of blacklisted folders/files
EX int         Nblacklist;                                                             //  blacklist count
EX ch          *thumbfolder;                                                           //  thumbnails folder
EX ch          *curr_file;                                                             //  current image file
EX ch          curr_file_type[8];                                                      //  jpg / tif / png / jxl / other         jxl
EX int         curr_file_bpc;                                                          //  image file bits/color, 8/16
EX uint        curr_file_size;                                                         //  image file size on disk
EX int         curr_file_posn;                                                         //  position in current gallery, 0-last
EX ch          *curr_album;                                                            //  current or last used album
EX ch          *recent_folders[10];                                                    //  recently used file folders
EX ch          meta_edithist[metadataXcc];                                             //  EXIF edit history text
EX int         meta_edithist_cc0;                                                      //  edit history text cc at file open
EX int         Fmeta_edithist;                                                         //  edit history loaded for curr. file
EX ch          *copymove_loc;                                                          //  last used copy/move to location
EX ch          *clicked_file;                                                          //  image file / thumbnail clicked
EX int         clicked_posn;                                                           //  clicked gallery position (Nth)
EX int         clicked_width;                                                          //  clicked thumbnail position
EX int         clicked_height;                                                         //    (normalized 0-100)
EX ch          *imagefiletypes;                                                        //  supported image types: .jpg .png etc.
EX ch          *colormapfile;                                                          //  curr. printer color map file
EX ch          *RGB_chooser_file;                                                      //  user's color chooser image file
EX ch          paneltext[200];                                                         //  top panel application text
EX int         NSMP;                                                                   //  actual SMP threads to use (<= XSMP)
EX ch          *lc;                                                                    //  language code, default "en"           26.0
EX ch          UGfile[20];                                                             //  userguide file, def. "userguide-en"   26.3

EX int         Fscriptbuild;                                                           //  edit script build is in-progress
EX ch          scriptfile[200];                                                        //  current script file name
EX FILE        *script_fid;                                                            //  current script file FID
EX int         Fscriptrun;                                                             //  flag, script file is active

EX ch          f_load_type[8];                                                         //  data set by PXB/PXM_load()
EX int         f_load_bpc;
EX int         f_load_size;
EX ch          *f_save_file;                                                           //  data set by PXB/PXM_save()
EX ch          f_save_type[8];
EX int         f_save_bpc;
EX uint        f_save_size;

//  files and folders in Fotocx home folder (normally /home/<user>/.fotocx)

EX ch          index_folder[200];                                                      //  image index folder
EX ch          image_folders_file[200];                                                //  top image and thumbnail folders
EX ch          image_index_file[200];                                                  //  image index file
EX ch          meta_index_file[200];                                                   //  extra metadata index tags
EX ch          parameters_file[200];                                                   //  fotocx parameters file
EX ch          albums_folder[200];                                                     //  saved image albums
EX ch          custom_kernel_folder[200];                                              //  custom convolution kernels
EX ch          markup_folder[200];                                                     //  saved markup text
EX ch          mashup_folder[200];                                                     //  mashup projects
EX ch          palettes_folder[200];                                                   //  color palett files
EX ch          pattern_folder[200];                                                    //  pattern files
EX ch          printer_color_folder[200];                                              //  printer calibration
EX ch          saved_areas_folder[200];                                                //  saved select area files
EX ch          saved_curves_folder[200];                                               //  saved curve data
EX ch          scripts_folder[200];                                                    //  script files
EX ch          saved_searches_folder[200];                                             //  saved search dialogs
EX ch          slideshow_folder[200];                                                  //  slide show files
EX ch          slideshow_trans_folder[200];                                            //  slide show transition files
EX ch          temp_folder[200];                                                       //  temp. files folder
EX ch          keywords_defined_file[200];                                             //  keywords defined file
EX ch          recentfiles_file[200];                                                  //  file of recent image files
EX ch          recent_folders_file[200];                                               //  file of recently used folders
EX ch          gallerymem_file[200];                                                   //  file for recent galleries memory
EX ch          searchresults_file[200];                                                //  file for search results
EX ch          meta_picklist_file[200];                                                //  metadata tagname picklist
EX ch          meta_view_extras_file[200];                                             //  view metadata optional tagnames
EX ch          meta_report_tags_file[200];                                             //  metadata report tagnames
EX ch          KB_shortcuts_file[200];                                                 //  KB shortcuts file
EX ch          blacklist_file[200];                                                    //  file for blacklisted folders/files
EX ch          capstags_file[200];                                                     //  metadata tags for image captions
EX ch          raw_commands_file[200];                                                 //  file for RAW file loader commands
EX ch          bookmarks_file[200];                                                    //  file for gallery bookmarks
EX ch          custom_menu_file[200];                                                  //  file for user custom menu functions
EX ch          map_regions_file[200];                                                  //  internet map regions file
EX ch          plugins_file[200];                                                      //  plugin menu functions file
EX ch          grid_picklist_file[200];                                                //  grid settings file
EX ch          translations_folder[200];                                               //  contains en.text. de.text ...         26.0

//  fotocx PXM and PXB pixmaps

struct PXM {                                                                           //  PXM pixmap, 3|4 x float per pixel
   ch          wmi[8];                                                                 //  self-identifier
   int         ww, hh, nc, rs;                                                         //  width, height, channels, row stride
   float       *pixels;                                                                //  ww * hh * nc * sizeof(float)
};

struct PXB {                                                                           //  PXB pixmap, 3|4 x uint8/pixel
   ch          wmi[8];                                                                 //  self-identifier
   int         ww, hh, nc, rs;                                                         //  width, height, channels, row stride
   uint8       *pixels;                                                                //  hh * rs bytes (in pixbuf)
   PIXBUF      *pixbuf;                                                                //  parallel GDK pixbuf sharing pixels
};

//  parameters for F/W image window painting (functions Fpaint() etc.)

struct Fstate_t {
   PXB         *fpxb;                                                                  //  image PXB, size = 1x
   PXB         *mpxb;                                                                  //  image PXB, size = Mscale
   int         morgx, morgy;                                                           //  Dpxb origin in Mpxb image
   int         dorgx, dorgy;                                                           //  Dpxb origin in drawing window
   float       fzoom;                                                                  //  image zoom scale (0 = fit window)
   float       mscale;                                                                 //  scale factor, 1x image to window image
   float       pscale;                                                                 //  prior scale factor
};

EX Fstate_t    Fstate;                                                                 //  parameters for F view windows
EX Fstate_t    *Cstate;

#define Fpxb   Fstate.fpxb                                                             //  F/W window parameters
#define Mpxb   Fstate.mpxb
#define Morgx  Fstate.morgx
#define Morgy  Fstate.morgy
#define Dorgx  Fstate.dorgx
#define Dorgy  Fstate.dorgy
#define Fzoom  Fstate.fzoom
#define Mscale Fstate.mscale
#define Pscale Fstate.pscale

EX PXM         *E0pxm;                                                                 //  edit pixmap, original image
EX PXM         *E1pxm;                                                                 //  edit pixmap, base image for editing
EX PXM         *E3pxm;                                                                 //  edit pixmap, edited image
EX PXM         *ERpxm;                                                                 //  edit pixmap, undo/redo image
EX PXM         *E8pxm;                                                                 //  scratch image for some functions
EX PXM         *E9pxm;                                                                 //  scratch image for some functions

EX int         Dww, Dhh;                                                               //  main/drawing window size
EX int         dww, dhh;                                                               //  Dpxb size in drawing window, <= Dww, Dhh
EX int         zoomx, zoomy;                                                           //  req. zoom center of window

EX int         Mbutton;                                                                //  mouse button, 1/3 = left/right
EX int         Mwxposn, Mwyposn;                                                       //  mouse position, window space
EX int         Mxposn, Myposn;                                                         //  mouse position, image space
EX int         LMclick, RMclick;                                                       //  mouse left, right click
EX int         Mxclick, Myclick;                                                       //  mouse click position, image space
EX int         Mdrag;                                                                  //  mouse drag underway
EX int         mouse_dragtime;                                                         //  current drag duration, milliseconds
EX double      wacom_pressure;                                                         //  Wacom tablet, stylus pressure 0.0 to 1.0
EX int         Mwdragx, Mwdragy;                                                       //  drag increment, window space
EX int         Mxdown, Mydown, Mxdrag, Mydrag;                                         //  mouse drag vector, image space
EX int         Fmousemain;                                                             //  mouse acts on main window not dialog
EX int         Mcapture;                                                               //  mouse captured by edit function
EX int         Mradius;                                                                //  mouse circle radius
EX int         MCpower, MEpower;                                                       //  mouse paint power, center and edge

EX int         KBcapture;                                                              //  KB key captured by edit function
EX int         KBkey;                                                                  //  active keyboard key
EX int         KBcontrolkey;                                                           //  keyboard key states, 1 = down
EX int         KBshiftkey;
EX int         KBaltkey;

//  lines, text and circles drawn over window image whenever repainted

struct topline_t {
   int      x1, y1, x2, y2;                                                            //  endpoint coordinates in image space
   int      type;                                                                      //  1/2/3/4 = black/white/both/dash
};

#define maxtoplines 8                                                                  //  max. top lines
EX topline_t   toplines[8], ptoplines[8];                                              //  top lines, prior top lines
EX int         Ntoplines, Nptoplines;                                                  //  current counts

struct toptext_t {
   int      ID, px, py;
   ch       *text = 0;
   ch       *font = 0;
};

#define maxtoptext 100                                                                 //  max. text strings
EX toptext_t   toptext[100];                                                           //  text strings
EX int         Ntoptext;                                                               //  current count

struct topcircle_t {                                                                   //  circle drawn over image
   int      px, py;
   int      radius;
};

#define maxtopcircles 200                                                              //  max. circles on image
EX topcircle_t    topcircles[200];                                                     //  circles
EX int            Ntopcircles;                                                         //  current count

//  select area data

#define sa_initseq 10                           //  initial sequence number (0/1/2 reserved)
#define sa_maxseq 9999                          //  ultimate limit 64K

#define sa_mode_rect       1                    //  select rectangle by drag/click
#define sa_mode_ellipse    2                    //  select ellipse by drag
#define sa_mode_draw       3                    //  freehand draw by drag/click
#define sa_mode_follow     4                    //  follow edge indicated by clicks
#define sa_mode_mouse      5                    //  select area within mouse (radius)
#define sa_mode_onecolor   6                    //  select one matching color within mouse
#define sa_mode_allcolors  7                    //  select all matching colors within mouse

#define sa_stat_none       0                    //  no select area present
#define sa_stat_edit       1                    //  select area edit mode
#define sa_stat_fini       2                    //  select area finished, enabled
#define sa_stat_disab      3                    //  select area finished, disabled

EX VOL int     sa_stat;                                                                //  select area status
EX int         sa_mode;                                                                //  select area edit method
EX uint16      sa_endpx[10000], sa_endpy[10000];                                       //  last pixel drawn per sequence no.
EX int         sa_thresh;                                                              //  mouse pixel distance threshold
EX int         sa_mouseradius;                                                         //  mouse selection radius
EX int         sa_searchrange;                                                         //  search range (* mouse radius)
EX int         sa_mousex, sa_mousey;                                                   //  mouse position in image
EX int         sa_lastx, sa_lasty;                                                     //  last selected mouse position
EX float       sa_colormatch;                                                          //  color range to match (0.001 to 1.0)
EX int         sa_edgecalc_done;                                                       //  edge distance calculation done
EX int         sa_edgecalc_busy;                                                       //  edge distance calculation busy
EX int         sa_minx, sa_maxx;                                                       //  enclosing rectangle for area
EX int         sa_miny, sa_maxy;
EX ch          *sa_stackdirec;                                                         //  pixel search stack
EX int         *sa_stack;
EX int         sa_maxstack;
EX int         sa_Nstack;
EX int         sa_currseq;                                                             //  current select sequence no.
EX int         sa_Ncurrseq;                                                            //  current sequence pixel count
EX uint8       *sa_pixselc;                                                            //  maps pixels selected in current cycle
EX uint16      *sa_pixmap;                                                             //  0/1/2+ = outside/edge/inside edge dist
EX uint8       *sa_pixmap2;                                                            //  maps mouse-selected pixels
EX uint        sa_Npixel;                                                              //  total select area pixel count
EX int         sa_fww, sa_fhh;                                                         //  valid image dimensions for select area
EX int         Fshowarea;                                                              //  show/hide select area outline
EX int         areanumber;                                                             //  increasing sequential number

EX int         gridsettings[5];                                                        //  grid line settings
#define GON    0                                                                       //    [0]  grid lines on/off
#define GXC    1                                                                       //    [1]  x-lines count
#define GYC    2                                                                       //    [2]  y-lines count
#define GXF    3                                                                       //    [3]  x-lines offset
#define GYF    4                                                                       //    [4]  y-lines offset

//  image edit function data

struct editfunc {                                                                      //  edit function data
   ch          *menuname = 0;                                                          //  menu name in menutab[*]
   ch          edit_hist[edithistXcc];                                                 //  metadata edit history text
   int         FprevReq;                                                               //  request to use smaller image if poss.
   int         Farea;                                                                  //  area: 0/1/2 = delete/ignore/usable
   int         Fmods;                                                                  //  flag, image modifications by this func
   int         Fpreview;                                                               //  flag, using smaller image for edits
   int         Fpaintedits;                                                            //  flag, OK to use with paint edits
   int         Fscript;                                                                //  flag, function can be scripted
   int         Fsaved;                                                                 //  current mods are saved to disk
   zdialog     *zd = 0;                                                                //  edit dialog
   spldat      *sd = 0;                                                                //  edit curve data
   void        (*menufunc)(GtkWidget *, ch *);                                         //  edit menu function in menutab[*]
   void *      (*threadfunc)(void *);                                                  //  edit thread function
   void        (*mousefunc)();                                                         //  edit mouse function
};

EX editfunc *CEF;                                                                      //  current active edit function

EX int         Eww, Ehh;                                                               //  dimensions of image being edited
EX int         Fpaintedits;                                                            //  paint_edits() is active
EX int         editrescale[2];                                                         //  edit rescale width, height
EX int         Fupright;                                                               //  flag, image was uprighted
EX int         Flevel;                                                                 //  flag, image was levelled

EX int         editpixels_pxlo;                                                        //  get_edit_pixels() image area:
EX int         editpixels_pxhi;                                                        //   - mouse circle box enclosure
EX int         editpixels_pylo;                                                        //   - select area box enclosure
EX int         editpixels_pyhi;                                                        //   - full image

#define cropmem 5                                                                      //  depth of crop memory below
EX ch          *cropsizes[5];                                                          //  crop size buttons, "2000x1200" etc.
EX ch          *cropratios[5];                                                         //  crop ratio buttons, "3:2" etc.
EX int         cropx1, cropy1, cropx2, cropy2;                                         //  crop rectangle NW and SE corners

//  edit undo/redo stack data

#define maxedits 100                                                                   //  undo/redo stack size
EX ch          URS_filename[200];                                                      //  stack image filename template
EX int         URS_pos;                                                                //  stack position, 0-99
EX int         URS_max;                                                                //  stack max. position, 0-99
EX ch          URS_menu[100][32];                                                      //  edit function menu name
EX ch          URS_parms[100][edithistXcc];                                            //  edit parameters or null
EX int         URS_saved[100];                                                         //  flag, edit saved to file or not

struct textattr_t {                                                                    //  attributes for gentext() function
   ch       text[1000];                                                                //  text to generate image from
   ch       font[80];                                                                  //  font name
   int      size;                                                                      //  font size
   int      tww, thh;                                                                  //  generated image size, unrotated
   float    angle;                                                                     //  text angle, degrees
   float    sinT, cosT;                                                                //  trig funcs for text angle
   ch       color[4][20];                                                              //  text, backing, outline, shadow "R|G|B"
   int      transp[4];                                                                 //  corresponding transparencies 0-255
   int      towidth;                                                                   //  outline width, pixels
   int      shwidth;                                                                   //  shadow width
   int      shangle;                                                                   //  shadow angle -180...+180
   int      emboss[2];                                                                 //  emboss radius, depth
   PXB      *pxb_text;                                                                 //  image with text/outline/shadow
};

struct lineattr_t {                                                                    //  attributes for genline() function
   int      length, width;                                                             //  line length and width, pixels
   int      larrow, rarrow;                                                            //  left/right arrow head size (0 = no arrow)
   int      lww, lhh;                                                                  //  generated image size, unrotated
   float    angle;                                                                     //  line angle, degrees
   float    sinT, cosT;                                                                //  trig funcs for line angle
   ch       color[4][20];                                                              //  line, background, outline, shadow "R|G|B"
   int      transp[4];                                                                 //  corresponding transparencies 0-255
   int      towidth;                                                                   //  outline width, pixels
   int      shwidth;                                                                   //  shadow width
   int      shangle;                                                                   //  shadow angle -180...+180
   PXB      *pxb_line;                                                                 //  image with line/outline/shadow
};

//  dialogs with global visibility

EX zdialog     *zd_paintedits;                                                         //  m_paint_edits(), control dialog
EX zdialog     *zd_RGB_hist;                                                           //  brightness histogram window
EX zdialog     *zd_darkbrite;                                                          //  highlight dark/bright pixels zdialog
EX zdialog     *zd_editmeta;                                                           //  edit metadata zdialog
EX zdialog     *zd_editanymeta;                                                        //  edit any metadata zdialog
EX zdialog     *zd_deletemeta;                                                         //  delete metadata zdialog
EX zdialog     *zd_batchkeywords;                                                      //  batch keywords zdialog
EX zdialog     *zd_metaview;                                                           //  view metadata zdialog
EX zdialog     *zd_filesave;                                                           //  file save zdialog
EX zdialog     *zd_rename;                                                             //  rename file zdialog
EX zdialog     *zd_copymove;                                                           //  copy/move file zdialog
EX zdialog     *zd_deltrash;                                                           //  delete/trash zdialog
EX zdialog     *zd_sela;                                                               //  select area zdialog
EX zdialog     *zd_magnify;                                                            //  magnify image zdialog
EX zdialog     *zd_album_update;                                                       //  album_replacefile zdialog
EX zdialog     *zd_select_files1;                                                      //  select_files1 zdialog
EX zdialog     *zd_select_files;                                                       //  select_files zdialog
EX zdialog     *zd_edit_bookmarks;                                                     //  bookmarks edit zdialog
EX zdialog     *zd_ss_imageprefs;                                                      //  slide show image prefs zdialog

//  method for created threads to send events to an active zdialog

EX zdialog     *zd_thread;                                                             //  active zdialog
EX ch          *zd_thread_event;                                                       //  event to send

//  initialization and GTK functions (fotocx main)

int   main(int argc, ch * argv[]);                                                     //  main program
int   check_outboards(int fshow);                                                      //  check required/optional program installs
void  first_index();                                                                   //  initial user indexing decision
int   delete_event();                                                                  //  window delete event function
int   destroy_event();                                                                 //  window destroy event function
int   state_event(GtkWidget *, GdkEvent *event);                                       //  window state event function
void  drop_event(int mousex, int mousey, ch *file);                                    //  file drag-drop event function

void  progress_setgoal(double goal);                                                   //  reset progress counters, set goal value
void  progress_addvalue(double value);                                                 //  increment progress value
void  progress_addvalue(int index, double value);                                      //  increment thread progress value
int   progress_getvalue();                                                             //  get progress value, 0 - goal
int   progress_percent();                                                              //  get progress value as percent 0-100

int   timerfunc(void *arg);                                                            //  periodic function for panel update
void  update_Fpanel();                                                                 //  update top panel information
void  panelmessage(int red, int secs, ch *format, ...);                                //  post application message in top panel
void  panelmessage(int secs);                                                          //  clear top panel message (secs = 0)

int   Fblock(ch *funcname);                                                            //  block/unblock mutex functions
int   paintlock(int lock);                                                             //  block/unblock main window updates

int   Fpaint(GtkWidget *, cairo_t *);                                                  //  F and W drawing area paint function
void  Fpaintnow();                                                                     //  window repaint synchronously
void  Fpaint2();                                                                       //  window repaint (thread callable)
void  Fpaint3(int px, int py, int ww, int hh, cairo_t *cr);                            //  update Mpxb area from updated E3 area
void  Fpaint0(int px, int py, int ww, int hh, cairo_t *cr);                            //  update Mpxb area from updated E0 area
void  Fpaint4(int px, int py, int ww, int hh, cairo_t *cr);                            //  update Dpxb area from updated Mpxb
void  Fpaint3_thread(int px, int py, int ww, int hh);                                  //  Fpaint3 for threads (define update area)
void  Fpaint3_main();                                                                  //  update Fpaint3 area in main thread
void  Fpaintmouse(int mxposn, int mypons, int radius);                                 //  update Mpxb area for mouse painted E3 area

void  mouse_event(GtkWidget *, GdkEventButton *, void *);                              //  mouse event function
void  m_zoom(GtkWidget *, ch *);                                                       //  zoom image +/-
void  KBevent(GdkEventKey *event);                                                     //  pass dialog KB events to main app
int   KBpress(GtkWidget *, GdkEventKey *, void *);                                     //  KB key press event function
int   KBrelease(GtkWidget *, GdkEventKey *, void *);                                   //  KB key release event function
void  win_fullscreen(int hidemenu);                                                    //  full screen without menu/panel
void  win_unfullscreen();                                                              //  restore to prior size with menu etc.
void  set_mwin_title();                                                                //  main window title = curr_file path

//  cairo drawing functions (fotocx main)

void  draw_pixel(int px, int py, cairo_t *cr, int mode = 0);                           //  draw pixel
void  erase_pixel(int px, int py, cairo_t *cr);                                        //  erase pixel
void  draw_line(int x1, int y1, int x2, int y2, int type, cairo_t *cr);                //  draw line or dotted line (type 1/2)
void  erase_line(int x1, int y1, int x2, int y2, cairo_t *cr);                         //  erase line
void  draw_toplines(int arg, cairo_t *cr);                                             //  draw all pre-set overlay lines
void  draw_gridlines(cairo_t *cr);                                                     //  draw grid lines on image
void  add_toptext(int ID, int px, int py, ch *text, ch *font);                         //  add text string with ID on window
void  draw_toptext(cairo_t *cr);                                                       //  draw text strings when window repainted
void  erase_toptext(int ID);                                                           //  remove all text strings with ID
void  draw_text(int px, int py, ch *text, ch *font, cairo_t *cr);                      //  draw text on window
void  add_topcircle(int px, int py, int radius);                                       //  draw circle on window
void  draw_topcircles(cairo_t *cr);                                                    //  draw circles when window repainted
void  erase_topcircles();                                                              //  remove all circles
void  draw_mousecircle(int cx, int cy, int rad, int Ferase, cairo_t *cr);              //  draw circle around mouse pointer
void  draw_mousecircle2(int cx, int cy, int rad, int Ferase, cairo_t *cr);             //  2nd circle for m_copypixels1()
void  draw_mousearc(int cx, int cy, int ww, int hh, int Ferase, cairo_t *cr);          //  draw ellipse around pointer

float RGBmatch(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2);            //  match two RGB values
float RGBmatch(float r1, float g1, float b1, float r2, float g2, float b2);            //    0 - 1.0 = perfect match
float RGBmatch(float r1, float g1, float b1, uint8 r2, uint8 g2, uint8 b2);
float PIXmatch(uint8 *pix1, uint8 *pix2);                                              //  match two RGB pixels
float PIXmatch(float *pix1, float *pix2);                                              //    0 - 1.0 = perfect match
float PIXmatch(float *pix1, uint8 *pix2);
int   RGBfix(float &R, float &G, float &B);                                            //  fix overflows, preserve colors
int   RGBfix(int &R, int &G, int &B);

//  edit support functions (fotocx main)

int   edit_wwhhOK(int ww, int hh);                                                     //  check image size within limits
int   edit_setup(editfunc &EF);                                                        //  start new edit transaction
void  edit_cancel(int keep);                                                           //  cancel edit (keep zdialog etc.)
void  edit_fullsize();                                                                 //  convert to full-size pixmaps
void  edit_done(int keep);                                                             //  commit edit, add undo stack
void  edit_undo();                                                                     //  undo edit, back to org. image
void  edit_redo();                                                                     //  redo the edit after undo
void  edit_reset();                                                                    //  reset to initial status
void  edit_addhist(ch *format, ...);                                                   //  edit params > editfunc.edit_hist

void  m_undo_redo(GtkWidget *, ch *);                                                  //  undo / redo if left / right mouse click
void  m_undo(GtkWidget *, ch *);                                                       //  undo one edit
void  m_redo(GtkWidget *, ch *);                                                       //  redo one edit
void  undo_all();                                                                      //  undo all edits of current image
void  redo_all();                                                                      //  redo all edits of current image
void  save_undo();                                                                     //  undo/redo save function
PXM * load_undo(int posn);                                                             //  load image from undo/redo stack

typedef void mcbFunc();                                                                //  callback function type
EX mcbFunc   *mouseCBfunc;                                                             //  current edit mouse function
void  takeMouse(mcbFunc func, GdkCursor *);                                            //  capture mouse for edit dialog
void  freeMouse();                                                                     //  free mouse for main window

//  thread support functions (fotocx main)

typedef void * threadfunc(void *);                                                     //  thread function type
void  thread_start(threadfunc func, void *arg);                                        //  start thread in idle state
void  thread_signal();                                                                 //  signal thread that work is pending
void  thread_stop();                                                                   //  stop thread and wait for exit
void  thread_wait();                                                                   //  wait for thread to become idle
void  do_wthreads(threadfunc func, int Nt);                                            //  thread: start worker threads and wait

//  save and load parameters (fotocx main)

void  save_params();                                                                   //  save parameters for next session
void  load_params();                                                                   //  load parameters from prior session

void  free_resources(int fkeepundo = 0);                                               //  free resources associated with curr file

//  window and menu builder (f.widgets.cc)

void  build_widgets();                                                                 //  build widgets for F/G/W/M view modes
void  popup_menufunc(GtkWidget *, ch *menu);                                           //  image/thumb right-click menu func
void  image_Rclick_popup();                                                            //  popup menu for image right-click
void  gallery_Lclick_func(int Nth);                                                    //  function for thumbnail left-click
void  gallery_Rclick_popup(int Nth);                                                   //  popup menu for thumbnail right-click
void  m_viewmode(GtkWidget *, ch *fgm);                                                //  set F/G/M view mode - menu func
void  viewmode(ch fgm);                                                                //  set F/G/M view mode - callable
void  m_custom_menu(GtkWidget *, ch *);                                                //  build custom user menu
void  m_edit_script(GtkWidget *, ch *);                                                //  build script file with N edit funcs
void  edit_script_addfunc(editfunc *);                                                 //  edit_done() hook to add script func
void  m_run_script(GtkWidget *, ch *);                                                 //  run script on current image file
void  m_batch_script(GtkWidget *, ch *);                                               //  run script on batch of image files
void  m_plugins(GtkWidget *, ch *);                                                    //  plugins menu function
void  m_edit_plugins(GtkWidget *, ch *);                                               //  edit plugin function
void  m_run_plugin(GtkWidget *, ch *);                                                 //  run plugin function

//  pixmap/pixbuf memory image and file I/O functions (f.pixmap.cc)

int64 imagesize(int ww, int hh, int nc, int pz);                                       //  get image size (pz = 1/4 for PXB/PXM)
PXM * PXM_make(int ww, int hh, int nc);                                                //  create a PXM pixmap
void  PXM_free(PXM *&pxm);                                                             //  free PXM pixmap
void  PXM_audit(PXM *pxm);                                                             //  audit contents of a PXM pixmap
void  PXM_clear(PXM *pxm, int BW);                                                     //  clear PXM pixmap to value BW (0/255)
void  PXM_addalpha(PXM *pxm);                                                          //  add alpha channel to PXM pixmap
void  PXM_subalpha(PXM *pxm);                                                          //  remove alpha channel from PXM pixmap
void  PXM_applyalpha(PXM *pxm);                                                        //  apply alpha channel to RGB values
PXM * PXM_copy(PXM *pxm);                                                              //  copy PXM pixmap >> created PXM
void  PXM_copy(PXM *pxm1, PXM *pxm2);                                                  //  copy PXM to existing PXM of equal size
PXM * PXM_copy_area(PXM *pxm, int orgx, int orgy, int ww, int hh);                     //  copy PXM section to a new PXM
void  PXM_copy_area(PXM *pxm1, PXM *pxm2, int orgx, int orgy, int ww, int hh);         //  copy PXM section into another PXM
void  PXM_copy_area(PXM *pxm1, PXM *pxm2, int orgx1, int orgy1,                        //  copy PXM section into another PXM
                      int orgx2, int orgy2, int ww, int hh);                           //    (with destination offset)
PXM * PXM_rescale(PXM *pxm, int ww, int hh);                                           //  rescale PXM pixmap (ww/hh)
PXM * PXM_rotate(PXM *pxm, float angle, int fast = 0);                                 //  rotate PXM pixmap
PXM * PXM_upright(PXM *pxm, int angle, int mirror);                                    //  upright PXM pixmap (rotate and mirror)
void  PXM_blur(PXM *pxm, int radius);                                                  //  blur PXM pixmap image using blur radius
void  PXM_rgbdepth(PXM *pxm, int depth);                                               //  set PXM pixmap image RGB color depth 1-16

PXB * PXB_make(int ww, int hh, int nc);                                                //  create a PXB pixmap
void  PXB_free(PXB *&pxb);                                                             //  free PXB pixmap
void  PXB_clear(PXB *pxb);                                                             //  clear PXB pixmap to zeros (black)
int   PXB_addalpha(PXB *pxb);                                                          //  add alpha channel to PXB pixmap
int   PXB_subalpha(PXB *pxb);                                                          //  remove alpha channel from PXB pixmap
PXB * PXB_copy(PXB *pxb);                                                              //  copy (duplicate) PXB pixmap
void  PXB_copy_area(PXB *, int, int, int, int, PXB *, int, int);                       //  copy area from one PXB to another
PXB * PXB_subpxb(PXB *pxb1, int px1, int py1, int ww, int hh);                         //  create new PXB from PXB section
PXB * PXB_half(PXB *pxb1);                                                             //  rescale PXB pixmap to 1/2 size
PXB * PXB_rescale(PXB *pxb, int ww, int hh);                                           //  rescale PXB pixmap (ww/hh)
PXB * PXB_rescale_fast(PXB *pxb1, int ww, int hh);                                     //  rescale  " " faster, less quality
PXB * PXB_rescale(PXB *pxb1, int size);                                                //  rescale PXB pixmap to max. ww/hh
PXB * PXB_rescale_fast(PXB *pxb1, int size);                                           //  rescale PXB pixmap to max. ww/hh
PXB * PXB_rotate(PXB *pxb, float angle);                                               //  rotate PXB pixmap

int   vpixel(PXB *pxb, float px, float py, uint8 *vpix);                               //  get PXB virtual pixel at (px,py)
int   vpixel(PXM *pxm, float px, float py, float *vpix);                               //  get PXM virtual pixel at (px,py)

PXB * PXM_PXB_copy(PXM *pxm);                                                          //  PXM to pixbuf, same scale
void  PXM_PXB_update(PXM *, PXB *, int px3, int py3, int ww3, int hh3);                //  update PXB area from PXM, same scale
void  PXB_PXB_update(PXB *, PXB *, int px3, int py3, int ww3, int hh3);                //  update PXB area from PXB, any scale

PXB * PXB_load(ch *filespec, int fack);                                                //  load file to PXB pixmap, 8 bpc
PXM * PXM_load(ch *filespec, int fack);                                                //  load file to PXM pixmap, 8/16 bpc
int   PXB_save(PXB *pxb, ch *filespec, int bpc, int quality, int fack);                //  save PXB pixmap to file
int   PXM_save(PXM *pxm, ch *filespec, int bpc, int quality, int fack);                //  save PXM pixmap to file

PXB * JPG_PXB_load(ch *file, int size = 0);                                            //  JPG file to PXB, 8 bpc
PXM * JPG_PXM_load(ch *file);                                                          //  JPG file to PXM, 8 bpc
int   PXB_JPG_save(PXB *pxb, ch *file, int quality);                                   //  PXB to JPG file, 8 bpc
int   PXM_JPG_save(PXM *pxm, ch *file, int quality);                                   //  PXM to JPG file, 8 bpc

PXB * TIFF_PXB_load(ch *filespec);                                                     //  TIFF file to PXB, 8 bpc
PXM * TIFF_PXM_load(ch *filespec);                                                     //  TIFF file to PXM, 8/16 bpc
int   PXB_TIFF_save(PXB *pxb, ch *filespec, int bpc);                                  //  PXB to TIFF file, 8/16 bpc
int   PXM_TIFF_save(PXM *pxm, ch *filespec, int bpc);                                  //  PXM to TIFF file, 8/16 bpc

PXB * PNG_PXB_load(ch *filespec);                                                      //  PNG file to PXB, 8 bpc
PXM * PNG_PXM_load(ch *filespec);                                                      //  PNG file to PXM, 8/16 bpc
int   PXB_PNG_save(PXB *pxb, ch *filespec, int bpc);                                   //  PXB to PNG file, 8/16 bpc
int   PXM_PNG_save(PXM *pxm, ch *filespec, int bpc);                                   //  PXM to PNG file, 8/16 bpc

PXB * JXL_PXB_load(ch *file);                                                          //  JXL file to PXB, 8 bpc                jxl
PXM * JXL_PXM_load(ch *file);                                                          //  JXL file to PXM, 16 bpc
int   PXB_JXL_save(PXB *pxb, ch *file);                                                //  PXB to JXL file, 8 bpc
int   PXM_JXL_save(PXM *pxm, ch *file);                                                //  PXM to JXL file, 16 bpc

PXB * HEIC_PXB_load(ch *file, int size = 0);                                           //  HEIC file to PXB, 8 bpc
PXM * HEIC_PXM_load(ch *file);                                                         //  HEIC file to PXM, 8 bpc
int   PXB_HEIC_save(PXB *pxb, ch *file);                                               //  PXB to HEIC file, 8 bpc
int   PXM_HEIC_save(PXM *pxm, ch *file);                                               //  PXM to HEIC file, 8 bpc

PXB * JP2_PXB_load(ch *file);                                                          //  JP2 file to PXB, 8 bpc
PXM * JP2_PXM_load(ch *file);                                                          //  JP2 file to PXM, 8 bpc
int   PXB_JP2_save(PXB *pxb, ch *file);                                                //  PXB to JP2 file, 8 bpc
int   PXM_JP2_save(PXM *pxm, ch *file);                                                //  PXM to JP2 file, 8 bpc

PXB * WEBP_PXB_load(ch *file);                                                         //  WEBP file to PXB, 8 bpc
PXM * WEBP_PXM_load(ch *file);                                                         //  WEBP file to PXM, 8 bpc
int   PXB_WEBP_save(PXB *pxb, ch *file);                                               //  PXB to WEBP file, 8 bpc
int   PXM_WEBP_save(PXM *pxm, ch *file);                                               //  PXM to WEBP file, 8 bpc

PXB * PDF_PXB_load(ch *file);                                                          //  PDF/PS/EPS file to PXB, 8 bpc
PXM * PDF_PXM_load(ch *file);                                                          //  PDF/PS/EPS file to PXM, 8 bpc
int   PXB_PDF_save(PXB *pxb, ch *file);                                                //  PXB to PDF/PS/EPS file, 8 bpc
int   PXM_PDF_save(PXM *pxm, ch *file);                                                //  PXM to PDF/PS/EPS file, 8 bpc

PXB * ANY_PXB_load(ch *filespec);                                                      //  ANY file to PXB, 8 bpc
PXM * ANY_PXM_load(ch *filespec);                                                      //  ANY file to PXM, 8 bpc

PXB * RAW_PXB_load(ch *rawfile, int matchthumb);                                       //  RAW file to PXB, 8 bpc
PXM * RAW_PXM_load(ch *rawfile, int matchthumb);                                       //  RAW file to PXM, 16 bpc
PXB * RAW_thumb_pxb(ch *rawfile);                                                      //  RAW file to PXB for thumbnail creation

void pixelvert(uint8  *buff1, uint8  *buff2, int ww, int hh, int nc1, int nc2);        //  convert pixel buffer format
void pixelvert(uint8  *buff1, uint16 *buff2, int ww, int hh, int nc1, int nc2);        //    and/or channel count
void pixelvert(uint8  *buff1, float  *buff2, int ww, int hh, int nc1, int nc2);
void pixelvert(uint16 *buff1, uint8  *buff2, int ww, int hh, int nc1, int nc2);
void pixelvert(uint16 *buff1, uint16 *buff2, int ww, int hh, int nc1, int nc2);
void pixelvert(uint16 *buff1, float  *buff2, int ww, int hh, int nc1, int nc2);
void pixelvert(float  *buff1, uint8  *buff2, int ww, int hh, int nc1, int nc2);
void pixelvert(float  *buff1, uint16 *buff2, int ww, int hh, int nc1, int nc2);
void pixelvert(float  *buff1, float  *buff2, int ww, int hh, int nc1, int nc2);

//  file menu functions (f.file.cc)

void  m_new_session(GtkWidget *, ch *);                                                //  start parallel fotocx session
void  new_session(ch *args);                                                           //  callable function
void  m_open_file(GtkWidget *, ch *);                                                  //  file open dialog
void  m_open_drag(int x, int y, ch *file);                                             //  open drag-drop file
void  m_cycle2files(GtkWidget *, ch *);                                                //  open/cycle 2 previous files
void  m_cycle3files(GtkWidget *, ch *);                                                //  open/cycle 3 previous files
void  m_view360(GtkWidget *, ch *);                                                    //  view a 360 degree panorama
int   f_open(ch *file, int n=0, int kp=0, int ak=1, int z=0);                          //  open new current image file
int   f_open_saved();                                                                  //  open saved file, retain undo/redo stack
int   f_remove(ch *file, ch *opt);                                                     //  delete/trash file/index/thumb/gallery
void  f_preload(int next);                                                             //  start preload of next file
void  m_prev(GtkWidget *, ch *);                                                       //  open previous file in gallery
void  m_next(GtkWidget *, ch *);                                                       //  open next file in gallery
void  m_prev_next(GtkWidget *, ch *);                                                  //  left/right mouse >> prev/next image
void  m_zoom_menu(GtkWidget *, ch *);                                                  //  left/right mouse >> image/thumb zoom
void  m_rename(GtkWidget *, ch *);                                                     //  rename an image file (same location)
void  m_blank_image(GtkWidget *, ch *);                                                //  create new blank image file
int   create_blank_file(ch *file, int ww, int hh, int RGB[3]);                         //  create new blank image file, callable
void  play_gif(ch *file);                                                              //  play GIF file animation
void  m_copy_move(GtkWidget *, ch *);                                                  //  copy or move image file to new location
void  m_copyto_desktop(GtkWidget *, ch *);                                             //  copy image file to desktop
void  m_copyto_clip(GtkWidget *, ch *file);                                            //  copy an image file to the clipboard
void  m_delete_trash(GtkWidget *, ch *);                                               //  delete or trash an image file
void  m_wallpaper(GtkWidget *, ch *file);                                              //  current file >> desktop wallpaper
void  set_wallpaper(ch *file);                                                         //  set wallpaper (GNOME, KDE ...)        26.3
void  m_print_image(GtkWidget *, ch *);                                                //  print an image file
void  m_print_calibrated(GtkWidget *, ch *);                                           //  print an image file with adjusted colors
void  m_calibrate_printer(GtkWidget *, ch *);                                          //  calibrate printer colors
void  m_quit(GtkWidget *, ch *);                                                       //  exit application with checks
void  quitxx();                                                                        //  exit unconditionally
void  m_uninstall(GtkWidget *, ch *);                                                  //  uninstall fotocx
void  m_help(GtkWidget *, ch *menu);                                                   //  various help menu functions

void  m_file_save(GtkWidget *, ch *);                                                  //  save modified image file to disk
void  m_file_save_replace(GtkWidget *, ch *menu);                                      //  for KB shortcut Save File (replace)
void  m_file_save_version(GtkWidget *, ch *menu);                                      //  for KB shortcut Save File Version
int   f_save(ch *outfile, ch *type, int bpc, int qual, int ack);                       //  save current image file to disk
int   f_save_as();                                                                     //  save_as dialog (choose file and bpc)

ch * f_realpath(ch *infile);                                                           //  get real path for file with symlinks
ch * file_rootname(ch *file);                                                          //  get root name without .vNN.ext
ch * file_basename(ch *file);                                                          //  get base name /.../filename.ext
ch ** file_all_versions(ch *file, int &nf);                                            //  get all versions for given file
ch * file_new_version(ch *file);                                                       //  get next avail. file version name
ch * file_newest_version(ch *file);                                                    //  get newest version or original file
ch * file_prior_version(ch *file);                                                     //  get prior version or original file

int  find_imagefiles(ch *dir, int flags, ch **&files, int &Nf);                        //  find all image files within a folder

int  regfile(ch *file, struct stat *statb = 0);                                        //  test file is regular file, opt. return stat
int  dirfile(ch *file, struct stat *statb = 0);                                        //  test file is directory, opt. return stat
int  hasperm(ch *file, ch rw);                                                         //  test file exists with 'r'/'w' permission

int  set_permissions(GtkWidget *win, ch *file, ch *p1, ch *p2);                        //  show and set file permissions
int  conv_permissions(ch *perms, mode_t &mode);                                        //  conv. "read+write" etc. to mode_t
int  conv_permissions(mode_t mode, ch *perms);                                         //  conv. mode_t to "read+write" etc.

//  thumbnail gallery and navigation functions (f.gallery.cc)

ch     * gallery(ch *filez, ch *action, int Nth);                                      //  display image gallery window, navigate
void     gallery_memory(ch *action);                                                   //  save/recall gallery sort and posn.
void     set_gwin_title();                                                             //  main window title = gallery name
ch     * prev_next_file(int index, int lastver);                                       //  get prev/next file with last version option
ch     * prev_next_gallery(int index);                                                 //  get prev/next gallery (physical folder)
int      file_position(ch *file, int Nth);                                             //  get rel. position of file in gallery

void     image_file_type_init(void);                                                   //  initialization for image_file_type()
FTYPE    image_file_type(ch *file);                                                    //  FNF folder IMAGE RAW THUMB OTHER
ch     * thumb2imagefile(ch *thumbfile);                                               //  get image file for thumbnail file
ch     * image2thumbfile(ch *imagefile);                                               //  get thumbnail file for image file
int      thumbfile_OK(ch *imagefile);                                                  //  check thumbnail file exists and not stale
int      update_thumbfile(ch *imagefile);                                              //  create or refresh thumbnail file
int      thumbfile_set_mod_time(ch *imagefile);                                        //  set thumbnail mod time from image file
void     delete_thumbfile(ch *imagefile);                                              //  delete thumbnail for file
PIXBUF * get_thumb_pixbuf(ch *imagefile);                                              //  get thumbnail pixbuf for image file
void     gallery_popimage();                                                           //  popup big image of clicked thumbnail

ch     * select_files1(ch *gfolder);                                                   //  select one file from gallery window
void     select_files1_Lclick_func(int Nth);                                           //  select_files1, thumbnail left-click
void     select_files(int fclear = 0);                                                 //  select files from gallery window
void     add_file_to_selection(ch *file);                                              //  add file to selection
void     select_files_Lclick_func(int Nth);                                            //  select_files, thumbnail left-click
void     select_files_Rclick_func(int Nth);                                            //  select_files, thumbnail right-click

void  m_thumbview(GtkWidget *, ch *);                                                  //  gallery, thumbnails + file data
void  m_metaview(GtkWidget *, ch *);                                                   //  gallery, thumbnails + basic metadata
void  m_recentfiles(GtkWidget *, ch *);                                                //  gallery of recently viewed files
void  add_recent_file(ch *file);                                                       //  add file to recent file list
void  m_newest_files(GtkWidget *, ch *);                                               //  gallery of newest files
void  m_gallery_sort(GtkWidget *, ch *);                                               //  sort gallery by file, date, size ...
void  m_gallery_filter(GtkWidget *, ch *);                                             //  filter gallery for new/old/pattern
void  m_current_folder(GtkWidget *, ch *);                                             //  set gallery to current file folder
void  m_recent_folders(GtkWidget *, ch *);                                             //  set gallery to chosen recent folder
void  add_recent_folder(ch *foldername);                                               //  add current folder to top of list
void  m_folder_tree(GtkWidget *, ch *);                                                //  list folders, click for gallery
void  m_select_files(GtkWidget *, ch *);                                               //  files for album/batch/script funcs

void  m_bookmarks(GtkWidget *, ch *);                                                  //  select bookmark, goto gallery posn
void  m_edit_bookmarks(GtkWidget *, ch *);                                             //  edit bookmarks (gallery/file position)
void  edit_bookmarks_Lclick_func(int Nth);                                             //  thumbnail click response function

void  m_thumbframe(GtkWidget *, ch *);                                                 //  set video frame for video thumbnail
void  m_show_hidden(GtkWidget *, ch *);                                                //  for KB shortcut "show hidden files"
void  m_current_album(GtkWidget *, ch *);                                              //  for KB shortcut "Current Album"

int   popup_image(ch *imagefile, GtkWindow *parent, int Fnewin, int size);             //  popup window with image

//  albums menu (f.albums.cc)

void  m_album_create(GtkWidget *, ch *);                                               //  create a new album
int   album_create_from_gallery(ch *newalbumfile);                                     //  create album from current gallery
void  m_album_rename(GtkWidget *, ch *);                                               //  rename an album
void  m_album_delete(GtkWidget *, ch *);                                               //  delete an album
void  m_album_choose(GtkWidget *, ch *);                                               //  choose an album, show as gallery
void  album_show(ch *albumfile = 0);                                                   //  set/show current album gallery
void  m_album_current(GtkWidget *, ch *);                                              //  show current (last used) album
void  m_gallery_to_album(GtkWidget *, ch *);                                           //  save current gallery as album
void  album_add_selfiles(int mode);                                                    //  add selected files to album
void  album_add_currfile(int mode);                                                    //  add current file to album
void  album_add_file(ch *file, int posn);                                              //  add one file to album (drag/drop)
void  album_remove_file(int posn);                                                     //  remove file from album
void  album_move_file(int pos1, int pos2);                                             //  move file position (drag/drop)
void  album_folder_rename(ch *oldname, ch *newname);                                   //  fix album files after folder rename
void  album_purge_replace(ch *album, int Nt, ch **tfile, ch **rfile);                  //  purge missing, replace target files
void  album_purge_replace(ch *album, ch *targfile, ch *repfile);                       //  version for single target file
void  m_update_albums(GtkWidget *, ch *);                                              //  update albums for new file version
void  update_albums_Lclick_func(int Nth);                                              //  m_update_albums() thumbnail click
void  m_album_mass_update(GtkWidget *, ch *);                                          //  album mass update tools
void  m_cycle_wallpaper(int argc, ch *argv[]);                                         //  cycle wallpaper (command line, no menu)

//  slide show menu (f.albums.cc)

void  m_slideshow(GtkWidget *, ch *);                                                  //  enter or leave slideshow mode
void  ss_imageprefs_Lclick_func(int Nth);                                              //  slideshow image prefs thumbnail click func
void  ss_KBfunc(int KBkey);                                                            //  slideshow keyboard input

//  metadata menu functions (f.meta.cc)

int select_meta_tags(zlist_t *mlist, int maxout, int exclude);                         //  dialog to select metadata tags
void meta_view(int type);                                                              //  refresh current metadata report
void m_meta_view_main(GtkWidget *, ch *menu);                                          //  metadata short report
void m_meta_view_all(GtkWidget *, ch *menu);                                           //  report all metadata
void m_meta_edit_main(GtkWidget *, ch *menu);                                          //  primary edit main metadata dialog
void m_meta_edit_any(GtkWidget *, ch *menu);                                           //  dialog to fetch and save any metadata by name
void m_meta_delete(GtkWidget *, ch *menu);                                             //  dialog to delete any image file metadata by name
void m_meta_copy(GtkWidget *, ch *menu);                                               //  copy metadata from one image file to another
void m_meta_fix(GtkWidget *, ch *menu);                                                //  fix file with malformed metadata
void m_meta_manage_keywords(GtkWidget *, ch *menu);                                    //  define keywords for image searching
void m_meta_choose_caps(GtkWidget *, ch *menu);                                        //  choose metadata tags for image captions
void meta_show_caps(int show);                                                         //  show captions on current image
void meta_popup_title(int onoff);                                                      //  show title & description in popup window
void m_meta_toggle_caps(GtkWidget *, ch *menu);                                        //  toggle display of image captions on/off

void m_batch_keywords(GtkWidget *, ch *menu);                                          //  batch add and delete keywords for selected files
void m_batch_rename_keywords(GtkWidget *, ch *menu);                                   //  rename or delete keywords using a from-to list
void m_batch_purge_keywords(GtkWidget *, ch *menu);                                    //  purge keyword names from all image files
void m_batch_photo_date_time(GtkWidget *, ch *menu);                                   //  change or shift photo date/time
void m_batch_change_meta(GtkWidget *, ch *menu);                                       //  add/change or delete metadata for selected files
void m_batch_report_meta(GtkWidget *, ch *menu);                                       //  batch metadata report to text file
void m_batch_geotags(GtkWidget *, ch *menu);                                           //  add given geotag to selected set of images

void m_meta_places_dates(GtkWidget *, ch *);                                           //  find images by location and date range
void m_meta_timeline(GtkWidget *, ch *);                                               //  find images by year and month
void m_meta_tags(GtkWidget *, ch *);                                                   //  find images by tag name and value
void m_autosearch(GtkWidget *, ch *);                                                  //  search function for use with scripts
void m_search_images(GtkWidget *, ch *);                                               //  find images using any metadata and/or file names

void m_worldmap(GtkWidget *, ch *menu);                                                //  initialize internet world map
void m_map_regions(GtkWidget *, ch *);                                                 //  add custom map regions, goto region
void m_map_location(GtkWidget *, ch *);                                                //  input (part) location name, goto map location
void m_set_map_markers(GtkWidget *, ch *);                                             //  show map markers, all images or curr. gallery
void m_map_zoomin(GtkWidget *, ch *menu);                                              //  zoom map in on an image location

int meta_get(ch *file, ch **tagname, ch **tagval, int NK);                             //  get image file metadata from list of tags
int meta_getN(ch **files, int NF, ch **tagname, ch **tagval, int NK, int Fall);        //  same for multiple files, using multiple threads
int meta_put(ch *file, ch **tagname, ch **tagval, int ntags);                          //  update image metadata from list of tags and data
int meta_copy(ch *file1, ch *file2, ch **tagname, ch **tagval, int NK);                //  copy metadata file1 >> file2, with revisions

int file_to_xxrec(ch *file);                                                           //  update xxrec_tab[] record from file metadata
int xxrec_index(ch *file);                                                             //  return xxrec_tab[] index for input file
xxrec_t * get_xxrec(ch *file);                                                         //  get image xxrec_tab[] for image file
xxrec_t * read_xxrec_seq(int &ftf);                                                    //  read xxrec_tab[] records sequentially
int write_xxrec_seq(xxrec_t *xxrec, int &ftf);                                         //  write xxrec_tab[] records sequentially

//  select area menu functions (f.select.cc)

void  m_select_area(GtkWidget *, ch *);                                                //  select area to edit within image
void  m_select_find_gap(GtkWidget *, ch *);                                            //  find gap in area outline
void  m_select_blend(GtkWidget *, ch *);                                               //  blend area edits using mouse
void  m_select_show(GtkWidget *, ch *);                                                //  enable area for subsequent edits
void  m_select_hide(GtkWidget *, ch *);                                                //  show area outline
void  m_select_enable(GtkWidget *, ch *);                                              //  hide area outline
void  m_select_disable(GtkWidget *, ch *);                                             //  disable area
void  m_select_invert(GtkWidget *, ch *);                                              //  invert area
void  m_select_clear(GtkWidget *, ch *);                                               //  clear area
void  m_select_copy(GtkWidget *, ch *);                                                //  copy area to default file
void  m_select_save(GtkWidget *, ch *);                                                //  copy area to designated file
void  select_copysave(GtkWidget *, ch *menu);                                          //  common function for above two
void  m_select_load(GtkWidget *, ch *);                                                //  load file and paste as area in image
void  m_select_paste(GtkWidget *, ch *);                                               //  paste last copied area into image

void  sa_geom_mousefunc();                                                             //  select rectangle or ellipse
void  sa_draw_mousefunc();                                                             //  edge line drawing function
int   sa_nearpix(int mx, int my, int rad, int &px, int &py, int fx);                   //  find nearest pixel
void  sa_draw_line(int px1, int py1, int px2, int py2, cairo_t *cr);                   //  draw a connected line
void  sa_draw1pix(int px, int py, cairo_t *cr);                                        //  add one pixel to select area
void  sa_mouse_select();                                                               //  select by mouse (opt. color match)
void  sa_nextseq();                                                                    //  start next sequence number
void  sa_unselect_pixels(cairo_t *cr);                                                 //  remove current selection
void  sa_pixmap_create();                                                              //  create area pixel maps
void  sa_finish();                                                                     //  finish - map interior pixels
void  sa_finish_auto();                                                                //  finish - interior pixels already known
void  sa_unfinish();                                                                   //  set finished area back to edit mode
void  sa_map_pixels();                                                                 //  map edge and interior pixels
void  sa_show(int flag, cairo_t *cr);                                                  //  show or hide area outline
void  sa_show_rect(int px1, int py1, int ww, int hh, cairo_t *cr);                     //  show area outline inside a rectangle
int   sa_validate();                                                                   //  validate area for curr. image
void  sa_enable();                                                                     //  enable area
void  sa_disable();                                                                    //  disable area
void  sa_invert();                                                                     //  invert area
void  sa_clear();                                                                      //  clear area
void  sa_edgecalc();                                                                   //  calculate area edge distances
void  sa_edgecreep(int);                                                               //  adjust area edge +/-
void  sa_postfix();                                                                    //  copy E1 to E3 outside area, blend E3 edges

//  image edit functions - Edit menu (f.edit.cc)

void  get_edit_pixels_init(int Nthreads, int margin);                                  //  get edit pixels initz. (mouse/area/full)
int   get_edit_pixels(int thread, int &px, int &py, float &blend);                     //  get edit pixels from image, area, or mouse
void  m_rotate(GtkWidget *, ch *);                                                     //  rotate or level image
void  m_upright(GtkWidget *, ch *);                                                    //  1-button image upright function
void  m_crop(GtkWidget *, ch *);                                                       //  crop image margins
void  m_retouch(GtkWidget *, ch *);                                                    //  brightness, contrast, color
void  blackbodyRGB(int K, float &R, float &G, float &B);                               //  convert deg. K to RGB factors
void  m_rescale(GtkWidget *, ch *);                                                    //  rescale image
void  m_split_screen1(GtkWidget *, ch *);                                              //  view edit before/after using split-screen
void  m_split_screen2(GtkWidget *, ch *);                                              //  view image differences using split-screen
void  m_margins(GtkWidget *, ch *);                                                    //  add margins around image
void  m_markup(GtkWidget *, ch *);                                                     //  draw text/line/box/oval on image
void  m_draw_text(GtkWidget *, ch *);                                                  //  draw text on image
void  load_text(zdialog *zd);                                                          //  load text and attributes from a file
void  save_text(zdialog *zd);                                                          //  save text and attributes to a file
int   gentext(textattr_t *attr);                                                       //  generate text image from attributes
void  m_draw_line(GtkWidget *, ch *);                                                  //  draw line/arrow on image
void  load_line(zdialog *zd);                                                          //  load line attributes from a file
void  save_line(zdialog *zd);                                                          //  save line attributes to a file
int   genline(lineattr_t *attr);                                                       //  generate line/arrow image from attributes
void  m_draw_box(GtkWidget *, ch *);                                                   //  draw box on image
void  m_draw_oval(GtkWidget *, ch *);                                                  //  draw oval on image
void  m_color_mode(GtkWidget *, ch *);                                                 //  B+W/color, negative/positive, sepia
void  m_paint_edits(GtkWidget *, ch *);                                                //  paint edits gradually by mouse painting
void  m_paint_image(GtkWidget *, ch *);                                                //  paint on image with the mouse
int   RGB_chooser(zdialog *zd, ch *butt, uint8 rgb[3]);                                //  dialog, get color from color file
int   HSL_chooser(zdialog *zd, ch *butt, uint8 RGB[3]);                                //  dialog, get color from HSL dialog
void  HSLtoRGB(float H, float S, float L, float &R, float &G, float &B);               //  convert HSL color space to RGB
void  RGBtoHSL(float R, float G, float B, float &H, float &S, float &L);               //  convert RGB color space to HSL
void  m_paint_transp(GtkWidget *, ch *);                                               //  paint transparency with the mouse
void  m_area_fill(GtkWidget *, ch *);                                                  //  fill selected areas or transparent areas
void  m_copy_in_image(GtkWidget *, ch *);                                              //  copy pixels within one image
void  m_copy_from_image(GtkWidget *, ch *);                                            //  copy pixels from one image to another
void  m_copy_from_image_slave(GtkWidget *, ch *);                                      //  source image slave process for the above
void  m_copy_prior_edit(GtkWidget *, ch *);                                            //  undo prior edits by mouse painting
void  m_template(GtkWidget *, ch *);                                                   //  edit function template (developer menu)

//  image edit functions - Repair menu (f.repair.cc)

void  m_sharpen(GtkWidget *, ch *);                                                    //  sharpen image
void  sharp_AC(int amount, int thresh);                                                //  callable amplify contrast
void  m_fix_motionblur(GtkWidget *, ch *);                                             //  reduce blur from camera motion
void  m_blur(GtkWidget *, ch *);                                                       //  blur image - main menu
void  m_blur_normal(GtkWidget *, ch *);                                                //  submenu, normal blur
void  m_blur_radial(GtkWidget *, ch *);                                                //  submenu, radial blur
void  m_blur_directed(GtkWidget *, ch *);                                              //  submenu, mouse-directed blur
void  m_blur_graduated(GtkWidget *, ch *);                                             //  submenu, graduated blur
void  m_blur_background(GtkWidget *, ch *);                                            //  submenu, background blur
void  m_denoise(GtkWidget *, ch *);                                                    //  image noise reduction
void  m_defog(GtkWidget *, ch *);                                                      //  add/remove fog/haze based on brightness
void  m_redeyes(GtkWidget *, ch *);                                                    //  red-eye removal
void  m_smart_erase(GtkWidget *, ch *);                                                //  smart erase object
void  m_remove_halo(GtkWidget *, ch *);                                                //  remove halo left by other edits
void  m_jpeg_artifacts(GtkWidget *, ch *);                                             //  suppress jpeg compression artifacts
void  m_anti_alias(GtkWidget *, ch *);                                                 //  suppress jaggies on feature edges
void  m_adjust_RGB(GtkWidget *, ch *);                                                 //  color adjust using RGB or CMY colors
void  m_adjust_HSL(GtkWidget *, ch *);                                                 //  color adjust with HSL color model
void  m_remove_dust(GtkWidget *, ch *);                                                //  remove dust spots
void  m_fringes(GtkWidget *, ch *);                                                    //  reduce lateral chromatic aberration

//  image edit functions - Refine menu (f.refine.cc)

void  m_flat_hist(GtkWidget *, ch *);                                                  //  flatten brightness histogram
void  m_localcon(GtkWidget *, ch *);                                                   //  increase local contrast
void  m_amplifycon(GtkWidget *, ch *);                                                 //  amplify existing contrast levels
void  m_gretinex(GtkWidget *, ch *);                                                   //  rescale RGB levels - global
void  m_lretinex(GtkWidget *, ch *);                                                   //  rescale RGB levels - local
void  m_saturation(GtkWidget *, ch *);                                                 //  adjust saturation based on brightness
void  m_soft_focus(GtkWidget *, ch *);                                                 //  apply lens soft focus effect
void  m_match_colors(GtkWidget *, ch *);                                               //  set image2 colors to match image1
void  m_brite_ramp(GtkWidget *, ch *);                                                 //  add brightness ramp across image
void  m_vignette(GtkWidget *, ch *);                                                   //  vignette tool

//  image edit functions - Effects menu (f.effects.cc)

void  m_outlines(GtkWidget *, ch *);                                                   //  outline drawing
void  m_sketch1(GtkWidget *, ch *);                                                    //  simulated sketch (1)
void  m_sketch2(GtkWidget *, ch *);                                                    //  simulated sketch (2)
void  m_cartoon(GtkWidget *, ch *);                                                    //  cartoon drawing
void  m_emboss(GtkWidget *, ch *);                                                     //  simulated embossing
void  m_tiles1(GtkWidget *, ch *);                                                     //  square tiles
void  m_tiles2(GtkWidget *, ch *);                                                     //  irregular tiles matching image
void  m_painting(GtkWidget *, ch *);                                                   //  simulated painting
void  m_texture(GtkWidget *, ch *);                                                    //  add texture to image
void  m_fusion(GtkWidget *, ch *);                                                     //  suppress fine details, retaining sharpness
void  m_pattern(GtkWidget *, ch *);                                                    //  tile image with a pattern
void  m_crosshatch(GtkWidget *, ch *);                                                 //  crosshatch drawing
void  m_dither(GtkWidget *, ch *);                                                     //  dithered dots - main menu
void  m_dither0(GtkWidget *, ch *);                                                    //  submenu, Roy Lichtenstein dots
void  m_dither1(GtkWidget *, ch *);                                                    //  submenu, pure RGB or B&W dots
void  m_dither2(GtkWidget *, ch *);                                                    //  submenu, RGB reduced bit-depth dots
void  m_dither3(GtkWidget *, ch *);                                                    //  submenu, custom palette color dots
void  m_dither4(GtkWidget *, ch *);                                                    //  submenu, pixels condense into blobs
void  m_engrave(GtkWidget *, ch *);                                                    //  engrave - black/white lines
void  m_addglare(GtkWidget *, ch *);                                                   //  add glare around bright objects
void  m_mosaic(GtkWidget *, ch *);                                                     //  make mosaic with tiles from images
void  m_add_noise(GtkWidget *, ch *);                                                  //  add random_noise to image
void  m_set_colors(GtkWidget *, ch *);                                                 //  set no. colors for R/G/B or total
void  m_shift_colors(GtkWidget *, ch *);                                               //  shift colors into other colors
void  m_alien_colors(GtkWidget *, ch *);                                               //  revise hues using an algorithm
void  m_anykernel(GtkWidget *, ch *);                                                  //  apply custom convolution kernel

//  image edit functions - Warp menu (f.warp.cc)

void  m_unbend(GtkWidget *, ch *);                                                     //  unbend panoramas
void  m_perspective(GtkWidget *, ch *);                                                //  warp tetragon into rectangle
void  m_warp_area(GtkWidget *, ch *);                                                  //  warp image within an area
void  m_warp_curved(GtkWidget *, ch *);                                                //  warp image, curved transform
void  m_warp_affine(GtkWidget *, ch *);                                                //  warp image, affine transform
void  m_warp_radial(GtkWidget *, ch *);                                                //  add/remove barrel/pincushion distortion
void  m_unwarp_closeup(GtkWidget *, ch *);                                             //  warp image within closeup face area
void  m_makewaves(GtkWidget *, ch *);                                                  //  warp image using a wave pattern
void  m_twist(GtkWidget *, ch *);                                                      //  twist image centered at mouse
void  m_sphere(GtkWidget *, ch *);                                                     //  image spherical projection
void  m_inside_out(GtkWidget *, ch *);                                                 //  turn an image inside-out
void  m_tiny_planet(GtkWidget *, ch *);                                                //  convert image to tiny planet
void  m_escher_spiral(GtkWidget *, ch *);                                              //  generate inward spiraling image
void  m_flatphoto(GtkWidget *, ch *);                                                  //  flatten photo of a curved surface

//  image edit functions - Combine menu (f.combine.cc)

void  m_HDR(GtkWidget *, ch *);                                                        //  make HDR combined image
void  m_HDF(GtkWidget *, ch *);                                                        //  make HDF combined image
void  m_stack_paint(GtkWidget *, ch *);                                                //  stack / paint images
void  m_stack_noise(GtkWidget *, ch *);                                                //  stack / noise reduction
void  m_stack_layers(GtkWidget *, ch *);                                               //  stack / paint image layers
void  m_panorama(GtkWidget *, ch *);                                                   //  make panorama combined image
void  m_cim_show_files(GtkWidget *, ch *);                                             //  show input files for cim edit function

//  image edit functions - mashup and image_array (f.mashup.cc)

void  m_mashup(GtkWidget *, ch *);                                                     //  arrange images and text in custom layout
void  m_image_array(GtkWidget *, ch *);                                                //  combine images into a array layout
void  image_array_Lclick_func(int mx, int my);                                         //  array image click function

//  batch menu functions (f.batch.cc)

void  m_batch_convert(GtkWidget *, ch *);                                              //  rename/convert/rescale/export image files
void  m_batch_copy_move(GtkWidget *, ch *);                                            //  copy/move image files to new folder
void  m_batch_upright(GtkWidget *, ch *);                                              //  upright rotated image files
void  m_batch_deltrash(GtkWidget *, ch *);                                             //  delete or trash selected files
void  m_batch_overlay(GtkWidget *, ch *);                                              //  add overlay image to selected host images
void  m_export_filelist(GtkWidget *, ch *);                                            //  create file of selected image files
void  m_export_files(GtkWidget *, ch *);                                               //  export image files to a folder

//  tools menu functions (f.tools.cc)

void  m_index(GtkWidget *, ch *);                                                      //  rebuild image index and thumbnails
void  index_rebuild(int level, int keepopen);                                          //  index rebuild function
void  index_rebuild_old();                                                             //  index, no search for updates, no log
void  m_move_fotocx_home(GtkWidget *, ch *);                                           //  $HOME/.fotocx_home --> home folder    26.2
void  m_settings(GtkWidget *, ch *);                                                   //  user preferences and settings
void  m_KB_shortcuts(GtkWidget *, ch *);                                               //  edit KB shortcuts, update file
void  KB_shortcuts_load();                                                             //  load KB shortcuts at startup time
void  m_RGB_hist(GtkWidget *, ch *);                                                   //  show brightness histogram graph
void  brightness_scale(GtkWidget *drawarea, cairo_t *cr, int *);                       //  draw black to white horizontal band
void  m_magnify(GtkWidget *, ch *);                                                    //  magnify image within a radius of the mouse
void  m_measure_image(GtkWidget *, ch *);                                              //  measure distances within an image
void  m_show_RGB(GtkWidget *, ch *);                                                   //  show RGB values at mouse click
void  m_grid_settings(GtkWidget *, ch *);                                              //  grid lines settings dialog
void  m_toggle_grid(GtkWidget *, ch *);                                                //  toggle grid lines on and off
void  m_line_color(GtkWidget *, ch *);                                                 //  foreground line color (area/mouse/crop...)
void  m_darkbrite(GtkWidget *, ch *);                                                  //  highlight the darkest and brightest pixels
void  darkbrite_paint();                                                               //  paint function called from Fpaint()
void  m_monitor_color(GtkWidget *, ch *);                                              //  check monitor brightness and color
void  m_duplicates(GtkWidget *, ch *);                                                 //  find duplicate image files
void  m_resources(GtkWidget *, ch *);                                                  //  report CPU and memory usage
void  m_translations(GtkWidget *, ch *);                                               //  create en.text translation file       26.0

//  developer menu (f.tools.cc)

void  m_zmalloc_report(GtkWidget *, ch *);                                             //  popup report, zmalloc allocations by tag
void  m_zmalloc_growth(GtkWidget *, ch *);                                             //  same, only tags with allocation growth
void  m_mouse_events(GtkWidget *, ch *);                                               //  show mouse events popup text
void  m_zappcrash_test(GtkWidget *, ch *);                                             //  zappcrash test function
void  m_audit_userguide(GtkWidget *, ch *);                                            //  audit user guide


