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

   Fotoxx      edit photos and manage collections

   Copyright 2007-2016 Michael Cornelison
   Source URL: http://kornelix.net
   Contact: kornelix@posteo.de

   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.

   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.

   You should have received a copy of the GNU General Public License
   along with this program. If not, see http://www.gnu.org/licenses/.

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

#include <wait.h>
#include <glob.h>
#include <tiffio.h>
#include <png.h>
#include <lcms2.h>
#include "libraw/libraw.h"                                                       //  libraw                                16.07
#include <champlain/champlain.h>                                                 //  OSM libchamplain                      16.05
#include <champlain-gtk/champlain-gtk.h>
#include <clutter-gtk/clutter-gtk.h>

#include "zfuncs.h"


//  Fotoxx definitions

#define Frelease  "Fotoxx 16.08"                                                 //  Fotoxx release version
#define Flicense  "Free software - GNU General Public License v.3"
#define Fhomepage "http://kornelix.net"
#define Fcontact  "Questions and bugs: kornelix@posteo.de"
#define Fsoftware "Software used: \n"        \
         "    GNU, GTK, libtiff, libpng, liblcms, libraw, exiftool"              //  libraw                                16.07
#define Ftranslators "Translators: \n"       \
         "    Doriano Blengino, André Campos Rodovalho, \n"   \
         "    J. A. Miralles Puignau, Xavier Ribes "
#define MEGA (1024 * 1024)                                                       //  1 million as 2**20
#define PI 3.141592654
#define RAD (180.0/PI)

#define PXMpix(PXM,px,py) (PXM->pixels+((py)*(PXM->ww)+(px))*(PXM->nc))          //  PXM and PXB pixel (RGB/RGBA nc = 3/4)
#define PXBpix(PXB,px,py) (PXB->pixels+((py)*(PXB->rs)+(px)*(PXB->nc)))          //    e.g. red = PXMpix(...)[0] 
#define pixbright(pix) (0.25*(pix)[0]+0.65*(pix)[1]+0.10*(pix)[2])               //  overall brightness 0-255

//  color match function for integer/float RGB colors 0-255
//  returns 0.0 to 1.0 = perfect match
#define RGBMATCH(r1,g1,b1,r2,g2,b2)  \
      0.0000000596 * (256.0 - fabsf(r1-r2)) * (256.0 - fabsf(g1-g2)) * (256.0 - fabsf(b1-b2))
#define PIXMATCH(pix1,pix2)            \
      (RGBMATCH(pix1[0],pix1[1],pix1[2],pix2[0],pix2[1],pix2[2]))

//  compile time limits that could be increased

#define wwhh_limit1 20000                                                        //  max. image width or height            15.03
#define wwhh_limit2 (255*MEGA)                                                   //  max. image width x height             16.03
#define max_threads 4                                                            //  max. threads (hyperthreads useless)
#define maxtopdirks 200                                                          //  max. no. of top image directories
#define image_index_max 2000                                                     //  max. image files per image index file
#define indexrecl 2000                                                           //  max. image index rec. (>XFCC >tagFcc)
#define maximages 500000                                                         //  max. image files supported
#define maxgeolocs 20000                                                         //  max. geolocation recs (cities)
#define maxtagcats 200                                                           //  max tag categories
#define tagcc  50                                                                //  max cc for one tag or category ID
#define tagFcc 1000                                                              //  max tag cc for one image file
#define maxtags 10000                                                            //  max total tags and tags/category      15.07
#define tagGcc 200000                                                            //  max tag cc for one category
#define tagMcc 1000                                                              //  max tag cc for batch add tags
#define tagScc 500                                                               //  max tag cc for search tags
#define tagRcc 300                                                               //  max tag cc for recent tags

//  EXIF/IPTC keys for embedded image metadata

#define iptc_keywords_key "Keywords"                                             //  keywords (tags) (IPTC)
#define iptc_rating_key "Rating"                                                 //  star rating (IPTC)
#define exif_size_key "ImageSize"                                                //  image size, NNNNxNNNN
#define exif_date_key "DateTimeOriginal"                                         //  date/time (EXIF)
#define exif_width_key "ImageWidth"                                              //  width, pixels (EXIF)
#define exif_height_key "ImageHeight"                                            //  height, pixels (EXIF)
#define exif_orientation_key "Orientation"                                       //  orientation (EXIF)
#define exif_rollangle_key "RollAngle"                                           //  roll angle - minor level error        15.12
#define exif_editlog_key "ImageHistory"                                          //  edit history log (EXIF)
#define exif_comment_key "Comment"                                               //  image comment (EXIF)                  15.10
#define exif_usercomment_key "UserComment"                                       //  image comment (EXIF)                  15.10
#define iptc_caption_key "Caption-Abstract"                                      //  image caption (IPTC)
#define exif_focal_length_key "FocalLengthIn35mmFormat"                          //  focal length (EXIF)
#define exif_city_key "City"                                                     //  city/location name (geotags)
#define exif_country_key "Country"                                               //  country name
#define exif_lati_key "GPSLatitude"                                              //  latitude in degrees (-180 to +180)
#define exif_longi_key "GPSLongitude"                                            //  longitude in degrees (-180 to +180)
#define exif_maxcc 2000                                                          //  max. cc for exif/iptc text

//  GTK/GDK shortcuts

#define TEXTWIN GTK_TEXT_WINDOW_TEXT
#define NODITHER GDK_RGB_DITHER_NONE
#define ALWAYS GTK_POLICY_ALWAYS
#define NEVER GTK_POLICY_NEVER
#define GDKRGB GDK_COLORSPACE_RGB
#define LINEATTRIBUTES GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER
#define BILINEAR GDK_INTERP_BILINEAR
#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 GdkDeviceManager  *manager;                                            //  knows screen / mouse associations
   extern GdkScreen         *screen;                                             //  monitor (screen)
   extern GdkDevice         *mouse;                                              //  pointer device
   extern GtkSettings       *settings;                                           //  screen settings
   extern int        appfontsize;                                                //  app font size
   extern char       zappname[20];                                               //  app name/version
   extern char       zlang[8];                                                   //  current language lc_RC
   extern char       zicondir[200];                                              //  where application icons live
   extern int        Nmalloc, Nstrdup, Nfree;                                    //  malloc() strdup() free() counters
   extern int        vmenuclickposn;                                             //  vert. menu icon click position, 0-100
   extern int        vmenuclickbutton;                                           //   "" button: 1/3 = left/right mouse
   extern int        zdialog_count;                                              //  zdialog count (new - free)
   extern int        zdialog_busy;                                               //  open zdialogs (run - destroy)
   extern int        open_popup_windows;                                         //  open popup window count
   extern pthread_t  tid_main;                                                   //  main() thread ID
}

//  externals from f.file and f.gallery

enum FTYPE { FNF, FDIR, IMAGE, RAW, THUMB, OTHER };                              //  file types, FNF = file not found
enum GTYPE { NONE, GDIR, SEARCH, METADATA, ALBUM, RECENT, NEWEST };              //  gallery types 

namespace navi {                                                                 //  gallery() data
   extern char    *galleryname;                                                  //  directory path or gallery type name
   extern GTYPE   gallerytype;                                                   //  gallery type: directory, recent, etc.
   extern int     topfileposn;                                                   //  gallery window target scroll position
   extern int     Nfiles;                                                        //  gallery file count (incl. subdirks)
   extern int     Ndirs;                                                         //  gallery subdirectory count
   extern int     Nimages;                                                       //  gallery image file count
   extern char    **mdlist;                                                      //  corresp. metadata list
   extern int     mdrows;                                                        //  text rows in metadata list
   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 *win, cchar *menu);                                //  gallery menu buttons function
   void   changedirk(GtkWidget *widget, GdkEventButton *event);                  //  gallery directory change function
   void   newtop(GtkWidget *widget, GdkEventButton *event);                      //  gallery change top directory function
   void   newalbum(GtkWidget *widget, GdkEventButton *event);                    //  gallery change album function
   void   mouse_event(GtkWidget *, GdkEvent *, void *);                          //  gallery window mouse event function
   char * gallery_dragfile();                                                    //  gallery window file drag function     16.08
   void   gallery_dropfile(int mx, int my, char *file);                          //  gallery window file drop function     16.08
   int    KBrelease(GtkWidget *, GdkEventKey *, void *);                         //  gallery window key release event
}

//  GTK etc. parameters

EX int            screenww, screenhh;                                            //  monitor screen size
EX GtkWidget      *Mwin, *MWvbox;                                                //  main window and vbox
EX GtkWidget      *Fhbox, *Fmenu, *Fvbox, *Fpanel, *Fpanlab, *Fdrawin;           //  F window widgets, file view
EX GtkWidget      *Ghbox, *Gmenu, *Gvbox, *Gsep, *Gpanel, *Gtop, *Galbum;        //  G window widgets, gallery view
EX GtkWidget      *Gscroll, *Gdrawin;
EX GtkAdjustment  *Gadjust;
EX GtkWidget      *Whbox, *Wmenu, *Wvbox, *Wdrawin;                              //  W window widgets, world map view
EX GtkWidget      *Mhbox, *Mmenu, *Mvbox;                                        //  M window widgets, OSM map view        16.05
EX GtkWidget      *Cdrawin;                                                      //  curr. drawing window, Fdrawin/Wdrawin
EX GdkWindow      *gdkwin;                                                       //  corresp. GDK window
EX cairo_t        *mwcr;                                                         //  cairo context for drawing windows
EX PIXBUF         *BGpixbuf;                                                     //  window background pixbuf

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

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

//  user options

EX char        *menu_style;                                                      //  menu style: icons/text/both
EX int         Fbgcolor[3];                                                      //  F view background color, RGB 0-255    16.07
EX int         Gbgcolor[3];                                                      //  G view background color, RGB 0-255    16.08
EX int         gallerysort;                                                      //  1/2/3 = file-name/file-date/photo-date
EX int         iconsize;                                                         //  menu icon size
EX char        *dialog_font;                                                     //  dialog font e.g. "sans 10"            16.05
EX int         thumbfilesize;                                                    //  thumbnail files, pixel size           15.02
EX char        *startdisplay;                                                    //  display: recent/prev/blank/file/dirk
EX char        *startdirk;                                                       //  start directory (startdisplay=dirk)
EX char        *startfile;                                                       //  start image file (startdisplay=file)
EX int         Fdragopt;                                                         //  1/2 = 1x drag / magnified scroll
EX int         Fshowhidden;                                                      //  show hidden directories in gallery view
EX int         Flastversion;                                                     //  prev/next button gets last versions only
EX int         Fshiftright;                                                      //  shift image to right margin           16.01
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     16.01
EX char        *RAWfiletypes;                                                    //  known RAW file types: .raw .rw2 ...
EX char        *myRAWtypes;                                                      //  RAW types encountered

//  general parameters

EX char        *Prelease;                                                        //  prior fotoxx version
EX int         Ffirsttime;                                                       //  first time startup
EX int         mwgeom[4];                                                        //  main window position and size
EX char        PIDstring[8];                                                     //  process PID as string
EX int         NWT;                                                              //  working threads to use
EX int         wthreads_busy;                                                    //  working threads running
EX int         Nval[100];                                                        //  static integer values 0-99
EX char        FGWM;                                                             //  curr. window mode: 'F' 'G' 'W'

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

typedef void   menufunc_t(GtkWidget *,cchar *);                                  //  table of menu names and functions

typedef struct {
   GtkWidget    *topmenu;                                                        //  parent menu
   cchar        *menu;                                                           //  menu text
   cchar        *mtran;                                                          //  translation
   cchar        *icon;                                                           //  menu icon
   cchar        *desc;                                                           //  menu short description (tooltip)
   cchar        *dtran;                                                          //  translation
   menufunc_t   *func;                                                           //  menu function (GtkWidget *, cchar *)
   cchar        *arg;                                                            //  argument
}  menutab_t;

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

#define maxshortcuts 50
EX char        *shortcutkey[50];                                                 //  KB shortcut keys (or combinations)
EX char        *shortcutmenu[50];                                                //  corresponding menu names
EX int         Nshortcuts;                                                       //  count of entries

EX int         Frawtherapee;                                                     //  flag, Raw Therapee available
EX int         Fgrowisofs;                                                       //  flag, growisofs available             16.02
EX int         PTtools;                                                          //  flag, pano tools available

EX int         Fshutdown;                                                        //  app shutdown underway
EX int         Fdebug;                                                           //  debug flag
EX int         Fnoindex;                                                         //  disable image index at startup        15.02
EX int         FindexOK;                                                         //  index function completed OK           15.04
EX int         Fkillfunc;                                                        //  flag, running function should quit
EX int         Fpaintlock;                                                       //  gtimefunc() request from thread:      16.02
EX int         Fpaintunlock;                                                     //    freeze or thaw image window
EX int         Fmetamod;                                                         //  image metadata unsaved changes        15.03
EX int         Fblock;                                                           //  edit functions mutex flag             15.04
EX int         Ffuncbusy;                                                        //  function is busy/working
EX int         Fthreadbusy;                                                      //  thread is busy/working
EX int         Ffullscreen;                                                      //  flag, window is fullscreen
EX int         Fpanelshow;                                                       //  show or hide F view top panel         16.02
EX int         Fpaintrequest;                                                    //  window paint request pending          15.05
EX int         Fimagerefresh;                                                    //  window image refresh needed           15.05
EX int         Fblowup;                                                          //  zoom small images to window size
EX int         Fmashup;                                                          //  flag, mashup function is active
EX int         Fslideshow;                                                       //  flag, slide show is active
EX int         ss_escape;                                                        //  KB escape or F11 >> slide show process
EX int         ss_Larrow;                                                        //  KB left arrow >> slide show process
EX int         ss_Rarrow;                                                        //  KB right arrow >> slide show process
EX int         ss_spacebar;                                                      //  KB space bar >> slide show process
EX int         ss_Bkey;                                                          //  KB B-key >> slide show process
EX int         ss_Xkey;                                                          //  KB X-key >> slide show process
EX int         ss_Nkey;                                                          //  KB N-key >> slide show process        16.01
EX char        *cycledesktop_album;                                              //  cycle desktop wallpaper, album
EX int         cycledesktop_index;                                               //  cycle desktop wallpaper, file index
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 char        *topmenu;                                                         //  latest top-menu selection
EX char        *startmenu;                                                       //  command line, startup menu function
EX char        *startalbum;                                                      //  command line, startup album gallery
EX char        file_errmess[1000];                                               //  error message from low-level file funcs
EX cchar       *F1_help_topic;                                                   //  current function help topic
EX int         Fcaptions;                                                        //  show image captions/comments
EX int         Fscriptbuild;                                                     //  edit script build is in-progress      15.10

EX VOL double  Fbusy_goal, Fbusy_done;                                           //  BUSY message progress tracking
EX char        paneltext[200];                                                   //  top panel application text

EX double      freemem;                                                          //  near real-time free memory, MB        16.02
EX char        tempdir[100];                                                     //  directory for temp files /tmp/fotoxx...
EX char        *topdirks[maxtopdirks];                                           //  user top-level image directories
EX int         Ntopdirks;                                                        //  topdirk[] count
EX char        *thumbdirk;                                                       //  thumbnails directory
EX char        *curr_file, *curr_dirk;                                           //  current image file and directory
EX char        *initial_file;                                                    //  initial file on command line
EX char        curr_file_type[8];                                                //  jpg / tif / png / other
EX int         curr_file_bpc;                                                    //  image file bits/color, 8/16
EX int         curr_file_size;                                                   //  image file size on disk
EX int         curr_file_posn;                                                   //  position in current gallery, 0-last
EX int         last_file_posn;                                                   //  remember when curr. file deleted      15.05
EX int         curr_file_count;                                                  //  count of images in current set
EX char        *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 char        *rawfile;                                                         //  RAW file passed to raw edit program
EX char        *imagefiletypes;                                                  //  supported image file types, .jpg .png etc.
EX char        *last_curr_file;                                                  //  curr_file in last session
EX char        *last_galleryname;                                                //  galleryname in last session
EX GTYPE       last_gallerytype;                                                 //  gallerytype in last session
EX char        *colormapfile;                                                    //  curr. printer color map file
EX char        *copymove_loc;                                                    //  copy/move directory last used

EX char        f_load_type[8];                                                   //  data set by f_load()
EX int         f_load_bpc, f_load_size;
EX char        *f_save_file;                                                     //  data set by f_save()
EX char        f_save_type[8];
EX int         f_save_bpc;
EX uint        f_save_size;

//  files and directories in /home/<user>/.fotoxx/

EX char        index_dirk[200];                                                  //  image index directory
EX char        tags_defined_file[200];                                           //  tags defined file
EX char        recentfiles_file[200];                                            //  file of recent image files
EX char        albums_dirk[200];                                                 //  directory for saved image albums
EX char        saved_areas_dirk[200];                                            //  directory for saved select area files
EX char        saved_curves_dirk[200];                                           //  directory for saved curve data
EX char        retouch_combo_dirk[200];                                          //  directory for saved retouch combo settings
EX char        custom_kernel_dirk[200];                                          //  directory for saved custom kernel data
EX char        writetext_dirk[200];                                              //  directory for write_text files
EX char        favorites_dirk[200];                                              //  directory for favorites menu
EX char        mashup_dirk[200];                                                 //  directory for mashup projects
EX char        KBshortcuts[200];                                                 //  keyboard shortcuts file
EX char        quickstart_file[200];                                             //  quick start image file
EX char        filecachefile[200];                                               //  albums, file cache file               16.07
EX char        slideshow_dirk[200];                                              //  directory for slide show files
EX char        slideshow_trans_dirk[200];                                        //  directory for slide show transition files
EX char        pattern_dirk[200];                                                //  directory for pattern files
EX char        printer_color_dirk[200];                                          //  directory for printer calibration     15.10
EX char        edit_scripts_dirk[200];                                           //  directory for edit script files       15.10
EX char        searchresults_file[200];                                          //  file for search results
EX char        maps_dirk[200];                                                   //  directory for fotoxx-maps files
EX char        user_maps_dirk[200];                                              //  directory for user-added map files

//  fotoxx PXM and PXB pixmaps

typedef struct  {                                                                //  PXM pixmap, 3 x float per pixel
   char        wmi[8];                                                           //  self-identifier
   int         ww, hh;                                                           //  width, height
   int         nc;                                                               //  channels (3 or more)
   float       *pixels;                                                          //  ww * hh * nc * sizeof(float)
}  PXM;

typedef struct  {                                                                //  PXB pixmap, 3 x uint8/pixel
   char        wmi[8];                                                           //  self-identifier
   PIXBUF      *pixbuf;                                                          //  underlying pixbuf image
   int         ww, hh;                                                           //  width, height, rowstride, channels
   int         rs, nc;                                                           //  rowstride, channels (3/4)
   uint8       *pixels;                                                          //  hh * rs bytes (in pixbuf)
}  PXB;

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

typedef struct  {
   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
}  FWstate;

EX FWstate    Fstate, Wstate;                                                    //  parameters for F and W windows
EX FWstate    *Cstate;                                                           //  current parameters, F or W

#define Fpxb   Fstate.fpxb                                                       //  F window parameter equivalents
#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         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         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 = solid/dotted
};

#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;
   cchar    *text;
   cchar    *font;
};

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

struct topcircle_t {
   int      px, py;
   int      radius;
};

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

//  spline curve data

typedef void t_spcfunc(int spc);                                                 //  callback function, spline curve edit

EX float    splcurve_minx;                                                       //  min. anchor point dist, % scale       15.10

typedef struct {                                                                 //  spline curve data
   GtkWidget   *drawarea;                                                        //  drawing area for spline curves
   t_spcfunc   *spcfunc;                                                         //  callback function when curve changed
   int         Nspc;                                                             //  number of curves, 1-10
   int         fact[10];                                                         //  curve is active                       15.10
   int         vert[10];                                                         //  curve is vert. (1) or horz. (0)
   int         nap[10];                                                          //  anchor points per curve
   float       apx[10][50], apy[10][50];                                         //  up to 50 anchor points per curve
   float       yval[10][1000];                                                   //  y-values for x = 0 to 1 by 0.001
   int         Nscale;                                                           //  no. of fixed scale lines, 0-10
   float       xscale[2][10];                                                    //  2 x-values for end points
   float       yscale[2][10];                                                    //  2 y-values for end points
} spldat;

//  select area data

#define sa_initseq 10                  //  initial sequence number (0/1/2 reserved)
#define sa_maxseq 9999                 //  ultimate limit 64K
#define mode_rect       1              //  select rectangle by drag/click
#define mode_ellipse    2              //  select ellipse by drag
#define mode_draw       3              //  freehand draw by drag/click
#define mode_follow     4              //  follow edge indicated by clicks
#define mode_replace    5              //  adjust edge by dragging mouse
#define mode_mouse      6              //  select area within mouse (radius)
#define mode_onecolor   7              //  select one matching color within mouse
#define mode_allcolors  8              //  select all matching colors within mouse
#define mode_image      9              //  select whole image

EX VOL int     sa_stat;                                                          //  0/1/2/3/4 = none/edit/xx/fini./disab.
EX int         sa_mode;                                                          //  1-7 = curr. select area edit method
EX uint16      sa_endpx[10000], sa_endpy[10000];                                 //  last pixel drawn per seqence 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 float       sa_colormatch;                                                    //  color range to match (0.001 to 1.0)
EX int         sa_calced;                                                        //  edge calculation done
EX int         sa_blend;                                                         //  edge blend width
EX int         sa_minx, sa_maxx;                                                 //  enclosing rectangle for area
EX int         sa_miny, sa_maxy;
EX char        *sa_stackdirec;                                                   //  pixel search stack
EX int         *sa_stackii;
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 char        *sa_pixselc;                                                      //  maps pixels selected in current cycle
EX uint16      *sa_pixmap;                                                       //  0/1/2+ = outside/edge/inside edge dist
EX uint        sa_Npixel;                                                        //  total select area pixel count
EX uint8       *sa_hairy_alpha;                                                  //  m_select_hairy() transparency poop
EX int         sa_fww, sa_fhh;                                                   //  valid image dimensions for select area
EX int         Fshowarea;                                                        //  show select area outline
EX int         areanumber;                                                       //  increasing sequential number

//  grid lines parameters, for each grid lines set [G]

#define GON    0                                                                 //  gridsettings[G][0]  grid lines on/off
#define GX     1                                                                 //              [G][1]  x-lines on/off
#define GY     2                                                                 //              [G][2]  y-lines on/off
#define GXS    3                                                                 //              [G][3]  x-lines spacing
#define GYS    4                                                                 //              [G][4]  y-lines spacing
#define GXC    5                                                                 //              [G][5]  x-lines count
#define GYC    6                                                                 //              [G][6]  y-lines count
#define GXF    7                                                                 //              [G][7]  x-lines offset
#define GYF    8                                                                 //              [G][8]  y-lines offset
#define G9     9                                                                 //              [G][9]  unused
EX int         currgrid;                                                         //  current grid params set, 0-5
EX int         gridsettings[6][10];                                              //  settings for 6 sets of grid lines

//  image index file record.
//  tags, comms, capt, gtags may have "null" (char) as a value.

struct sxrec_t {
   char        *file;                                                            //  image filespec
   char        fdate[16];                                                        //  file date, yyyymmddhhmmss
   char        pdate[16];                                                        //  image (photo) date, yyyymmddhhmmss
   char        size[16];                                                         //  image size, "12345x9876"
   char        rating[4];                                                        //  IPTC rating, '0' to '5' stars
   char        *tags;                                                            //  IPTC tags
   char        *capt;                                                            //  IPTC caption
   char        *comms;                                                           //  EXIF comments
   char        *gtags;                                                           //  EXIF geotags
};

//  image edit function data

typedef struct {                                                                 //  edit function data
   cchar       *menuname;                                                        //  menu name in menutab[*]
   cchar       *funcname;                                                        //  function name, e.g. flatten (< 32 chars)
   int         FprevReq;                                                         //  request to use smaller image if poss.
   int         Farea;                                                            //  area: 0/1/2 = delete/ignore/useable
   int         Fmods;                                                            //  flag, image modifications by this func
   int         Fpreview;                                                         //  flag, using smaller image for edits
   int         Frestart;                                                         //  flag, OK to restart with new file
   int         FusePL;                                                           //  flag, OK to use with paint/lever edits
   int         Fscript;                                                          //  flag, function can be scripted        15.10
   int         Fsaved;                                                           //  current mods are saved to disk
   zdialog     *zd;                                                              //  edit dialog
   spldat      *curves;                                                          //  edit curve data
   void        (*menufunc)(GtkWidget *, cchar *);                                //  edit menu function in menutab[*]
   void *      (*threadfunc)(void *);                                            //  edit thread function
   void        (*mousefunc)();                                                   //  edit mouse function
   int         thread_command, thread_status;
   int         thread_pend, thread_done, thread_hiwater;
}  editfunc;

EX editfunc    *CEF;                                                             //  current active edit function

//  undo/redo stack data

#define maxedits 100                                                             //  undo/redo stack size
EX char        URS_filename[100];                                                //  stack image filename template
EX int         URS_pos;                                                          //  stack position, 0-99
EX int         URS_max;                                                          //  stack max. position, 0-99
EX char        URS_funcs[100][32];                                               //  corresp. edit func. names
EX int         URS_saved[100];                                                   //  corresp. edit saved to disk or not
EX int         URS_reopen_pos;                                                   //  reopen last saved file, stack position

struct textattr_t {                                                              //  attributes for gentext() function
   char     text[1000];                                                          //  text to generate image from
   char     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
   char     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
   PXB      *pxb_text;                                                           //  image with text/outline/shadow        15.04
};

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
   char     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        15.04
};

//  dialogs with global visibility

EX zdialog     *zdbrdist;                                                        //  brightness distribution zdialog
EX zdialog     *zddarkbrite;                                                     //  highlight dark/bright pixels zdialog
EX zdialog     *zdeditmeta;                                                      //  edit metadata zdialog
EX zdialog     *zdbatchtags;                                                     //  batch tags zdialog
EX zdialog     *zdexifview;                                                      //  view EXIF/IPTC zdialog
EX zdialog     *zdexifedit;                                                      //  edit EXIF/IPTC zdialog
EX zdialog     *zdfilesave;                                                      //  file save zdialog
EX zdialog     *zdrename;                                                        //  rename file zdialog
EX zdialog     *zdcopymove;                                                      //  copy/move file zdialog
EX zdialog     *zddeltrash;                                                      //  delete/trash zdialog                  16.06
EX zdialog     *zdupright;                                                       //  upright file zdialog                  16.06
EX zdialog     *zdsela;                                                          //  select area zdialog
EX zdialog     *zdmagnify;                                                       //  magnify image zdialog
EX zdialog     *zd_gallery_getfiles;                                             //  gallery_getfiles zdialog
EX zdialog     *zd_edit_bookmarks;                                               //  bookmarks edit zdialog
EX zdialog     *zd_ss_imageprefs;                                                //  slide show image prefs zdialog

//  method for running thread to send an event to an active zdialog

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

//  edit function parameters

EX int         trimrect[4];                                                      //  trim rectangle, x1, y1, x2, y2
EX int         trimsize[2];                                                      //  trim (crop) width, height
EX char        *trimbuttons[6];                                                  //  trim dialog button labels
EX char        *trimratios[6];                                                   //  corresponding aspect ratios
EX int         editresize[2];                                                    //  edit resize width, height
EX int         jpeg_def_quality;                                                 //  default jpeg save quality (user setting)
EX int         jpeg_1x_quality;                                                  //  file save 1-time quality setting
EX float       lens_mm;                                                          //  pano lens mm setting

//  GTK functions (fotoxx main)

int   main(int argc, char * argv[]);                                             //  main program
int   initzfunc(void *);                                                         //  initializations
int   delete_event();                                                            //  window delete event function
int   destroy_event();                                                           //  window destroy event function
int   state_event(GtkWidget *, GdkEvent *event);                                 //  window state event function
int   gtimefunc(void *arg);                                                      //  periodic function
void  update_Fpanel();                                                           //  update F window information panel
void  paintlock(int lock);                                                       //  block or unblock 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);                                   //  update Mpxb area from updated E3 area
void  Fpaint0(int px, int py, int ww, int hh);                                   //  update Mpxb area from updated E0 area
void  Fpaint4(int px, int py, int ww, int hh);                                   //  update Dpxb area from updated Mpxb
void  mouse_event(GtkWidget *, GdkEventButton *, void *);                        //  mouse event function
void  m_zoom(GtkWidget *, cchar *);                                              //  zoom image +/-
void  KBstate(GdkEventKey *event, int state);                                    //  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
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 (fotoxx main)

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

//  spline curve edit functions (fotoxx main)

spldat * splcurve_init(GtkWidget *frame, void func(int spc));                    //  initialize spline curves
int      splcurve_adjust(void *, GdkEventButton *event, spldat *);               //  curve editing function
int      splcurve_addnode(spldat *, int spc, float px, float py);                //  add a new node to a curve             15.07
int      splcurve_draw(GtkWidget *, cairo_t *, spldat *);                        //  spline curve draw signal function
int      splcurve_generate(spldat *, int spc);                                   //  generate data from anchor points
float    splcurve_yval(spldat *, int spc, float xval);                           //  get curve y-value
int      splcurve_load(spldat *sd, FILE *fid = 0);                               //  load curve from a file
int      splcurve_save(spldat *sd, FILE *fid = 0);                               //  save curve to a file

//  edit support functions (fotoxx main)

int   edit_setup(editfunc &EF);                                                  //  start new edit transaction
void  edit_cancel(int keep);                                                     //  cancel edit (keep zdialog etc.)
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_fullsize();                                                           //  convert to full-size pixmaps
int   edit_load_widgets(editfunc *EF, FILE *fid = 0);                            //  load zdialog widgets from a file      15.10
int   edit_save_widgets(editfunc *EF, FILE *fid = 0);                            //  save zdialog widgets to a file        15.10
int   edit_save_last_widgets(editfunc *EF);                                      //  save last-used zdialog widgets        15.10
int   edit_load_prev_widgets(editfunc *EF);                                      //  load last-used zdialog widgets        15.10
void  m_undo_redo(GtkWidget *, cchar *);                                         //  undo / redo if left / right mouse click
void  m_undo(GtkWidget *, cchar *);                                              //  undo one edit
void  m_redo(GtkWidget *, cchar *);                                              //  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
void  load_undo();                                                               //  undo/redo load function
int   checkpend(cchar *list);                                                    //  check for lock, busy, pending changes

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 (fotoxx main)

typedef void * threadfunc(void *);                                               //  edit thread function
void  start_thread(threadfunc func, void *arg);                                  //  start edit thread
void  signal_thread();                                                           //  signal thread, work is pending
void  wait_thread_idle();                                                        //  wait for work complete
void  wrapup_thread(int command);                                                //  wait for exit or command exit
void  thread_idle_loop();                                                        //  thread: wait for work or exit command
void  thread_exit();                                                             //  thread: exit unconditionally
void  start_wthread(threadfunc func, void *arg);                                 //  start working thread (per proc. core)
void  exit_wthread();                                                            //  exit working thread
void  wait_wthreads(int block = 1);                                              //  wait for working threads

//  other support functions (fotoxx main)

void  save_params();                                                             //  save parameters for next session
void  load_params();                                                             //  load parameters from prior session
void  free_resources(int fkeepundo = 0);                                         //  free all allocated resources
int   sigdiff(float d1, float d2, float signf);                                  //  test for significant difference

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

void  build_widgets();                                                           //  build widgets for F/G/W/M view modes
void  popup_menufunc(GtkWidget *, cchar *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 *, cchar *fgw);                                       //  set current F/G/W/M view mode
void  m_favorites(GtkWidget *, cchar *);                                         //  graphic popup menu, user favorites

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

void  m_clone(GtkWidget *, cchar *);                                             //  start parallel fotoxx instance
void  m_recentfiles(GtkWidget *, cchar *);                                       //  open recently accessed file
void  add_recent_file(cchar *file);                                              //  add file to recent file list
void  m_newfiles(GtkWidget *, cchar *);                                          //  open newly added file
void  m_open(GtkWidget *, cchar *);                                              //  open image file in same window
void  m_open_drag(int x, int y, char *file);                                     //  open drag-drop file
void  m_previous(GtkWidget *, cchar *);                                          //  open previously accessed file
void  m_ufraw(GtkWidget *, cchar *);                                             //  open, edit RAW file with ufraw
void  m_rawtherapee(GtkWidget *, cchar *);                                       //  open, edit RAW file with Raw Therapee
int   f_open(cchar *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
void  f_preload(int next);                                                       //  start preload of next file
void  m_create(GtkWidget *, cchar *);                                            //  create new blank image file, dialog
int   create_blank_file(cchar *file, int ww, int hh, int RGB[3]);                //  create new blank image file, callable
void  m_rename(GtkWidget *, cchar *);                                            //  rename an image file (same location)
void  m_copy_move(GtkWidget *, cchar *);                                         //  copy or move image file to new location
void  m_copyto_clip(GtkWidget *, cchar *file);                                   //  copy an image file to the clipboard
void  m_delete_trash(GtkWidget *, cchar *);                                      //  delete or trash an image file
void  m_print(GtkWidget *, cchar *);                                             //  print an image file
void  m_print_calibrated(GtkWidget *, cchar *);                                  //  print an image file with adjusted colors
void  m_quit(GtkWidget *, cchar *);                                              //  exit application with checks
void  quitxx();                                                                  //  exit unconditionally
void  m_file_save(GtkWidget *, cchar *);                                         //  save modified image file to disk
void  m_file_save_version(GtkWidget *, cchar *menu);                             //  for KB shortcut Save File Version
char * file_new_version(char *file);                                             //  get next avail. file version name
int   f_save(char *outfile, cchar *type, int bpc, int Fack = 1);                 //  save current image file to disk
int   f_save_as();                                                               //  save_as dialog (choose file and bpc)
void  m_prev(GtkWidget *, cchar *);                                              //  open previous file in gallery
void  m_next(GtkWidget *, cchar *);                                              //  open next file in gallery
void  m_prev_next(GtkWidget *, cchar *);                                         //  open prev/next if left/right icon click
void  m_help(GtkWidget *, cchar *menu);                                          //  various help menu functions
int   find_imagefiles(cchar *dir, char **&f, int &n, int t, int z = 1);          //  find all image files within a directory
                                   
//  image file load and save functions (f.file.cc)

char * raw_to_tiff(cchar *rawfile);                                              //  RAW filespec >> corresp. tiff filespec
PXB * PXB_load(cchar *filespec, int fack = 0);                                   //  load file to PXB pixmap, 8 bpc
PXM * PXM_load(cchar *filespec, int fack = 0);                                   //  load file to PXM pixmap, 8/16 bpc
PXB * TIFF_PXB_load(cchar *filespec);                                            //  TIFF file to PXB, 8 bpc
PXM * TIFF_PXM_load(cchar *filespec);                                            //  TIFF file to PXM, 8/16 bpc
int   PXM_TIFF_save(PXM *pxm, cchar *filespec, int bpc);                         //  PXM to TIFF file, 8/16 bpc
PXB * PNG_PXB_load(cchar *filespec);                                             //  PNG file to PXB, 8 bpc, keep alpha
PXM * PNG_PXM_load(cchar *filespec);                                             //  PNG file to PXM, 8/16 bpc
int   PXM_PNG_save(PXM *pxm, cchar *filespec, int bpc);                          //  PXM to PNG file, 8/16 bpc
PXB * ANY_PXB_load(cchar *filespec);                                             //  ANY file to PXB, 8 bpc
PXM * ANY_PXM_load(cchar *filespec);                                             //  ANY file to PXM, 8 bpc
int   PXM_ANY_save(PXM *pxm, cchar *filespec);                                   //  PXM to ANY file, 8 bpc
PXB * RAW_PXB_load(cchar *filespec);                                             //  RAW file to PXB, 8 bpc
PXM * RAW_PXM_load(cchar *filespec);                                             //  RAW file to PXM, 16 bpc

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

void  meta_view(int type);                                                       //  popup metadata report
void  m_meta_view_short(GtkWidget *, cchar *);                                   //  view selected EXIF/IPTC data
void  m_meta_view_long(GtkWidget *, cchar *);                                    //  view all EXIF/IPTC data
void  m_captions(GtkWidget *, cchar *);                                          //  show caption/comments at the top
void  m_edit_metadata(GtkWidget *, cchar *);                                     //  edit date/rating/tags dialog
void  m_meta_edit_any(GtkWidget *, cchar *);                                     //  add or change any EXIF/IPTC data
void  m_meta_delete(GtkWidget *, cchar *);                                       //  delete EXIF/IPTC data
void  m_batch_tags(GtkWidget *, cchar *);                                        //  add/remove tags for selected files
void  m_batch_rename_tags(GtkWidget *, cchar *);                                 //  rename tags for all image files 
void  m_batch_change_metadata(GtkWidget *, cchar *);                             //  add/change/delete metadata, many files
void  m_batch_report_metadata(GtkWidget *, cchar *);                             //  batch metadata report
void  metadate_pdate(cchar *metadate, char *pdate, char *ptime);                 //  "yyyymmddhhmm" > "yyyy-mm-dd" + "hh:mm"
void  load_filemeta(cchar *file);                                                //  load metadata for image file
void  save_filemeta(cchar *file);                                                //  save metadata in EXIF and image index
void  update_image_index(cchar *file);                                           //  update image index for image file
void  delete_image_index(cchar *file);                                           //  delete image index for image file

void  m_batch_geotags(GtkWidget *, cchar *menu);                                 //  batch add geotags
void  geomap_paint_dots();                                                       //  paint red dots on map where images 
void  geomap_mousefunc();                                                        //  mouse function for geomap view mode
void  free_geomap();                                                             //  free memory used by geomap image
void  m_load_geomap(GtkWidget *, cchar *);                                       //  load a geomap chosen by user (W view)
void  m_mapsearch_range(GtkWidget *, cchar *);                                   //  set search range from a geomap position
void  m_load_OSM_map(GtkWidget *, cchar *);                                      //  load the initial OSM map (M view)
void  m_OSM_zoomin(GtkWidget *, cchar *);                                        //  zoom OSM map to given location
void  m_search_images(GtkWidget *, cchar *);                                     //  search image metadata
void  m_locations(GtkWidget *, cchar *);                                         //  report images by location [date-span]
void  m_timeline(GtkWidget *, cchar *);                                          //  report images by month

int   exif_get(cchar *file, cchar **keys, char **kdat, int nk);                  //  get EXIF/IPTC data for given keys
int   exif_put(cchar *file, cchar **keys, cchar **kdat, int nk);                 //  put EXIF/IPTC data for given keys
int   exif_copy(cchar *f1, cchar *f2, cchar **keys, cchar **kdat, int nk);       //  copy EXIF/IPTC data from file to file
int   exif_server(int Nrecs, char **inputs, char **outputs);                     //  run exiftool as a server process
void  exif_tagdate(cchar *exifdate, char *tagdate);                              //  yyyy:mm:dd:hh:mm:ss to yyyymmddhhmmss
void  tag_exifdate(cchar *tagdate, char *exifdate);                              //  yyyymmddhhmmss to yyyy:mm:dd:hh:mm:ss

int   get_sxrec(sxrec_t &sxrec, cchar *file);                                    //  get image index rec.
int   get_sxrec_min(cchar *file, char *fdate, char *pdate, char *size);          //  get image index rec. for gallery paint
int   put_sxrec(sxrec_t *sxrec, cchar *file);                                    //  add/update image index rec.
int   read_sxrec_seq(sxrec_t &sxrec, int &ftf);                                  //  read image index recs. 1-last
int   write_sxrec_seq(sxrec_t *sxrec, int &ftf);                                 //  write image index recs. 1-last

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

void  m_select(GtkWidget *, cchar *);                                            //  select area within image
void  m_select_find_gap(GtkWidget *, cchar *);                                   //  find gap in area outline
void  m_select_hairy(GtkWidget *, cchar *);                                      //  select hairy or irregular edge
void  m_select_show(GtkWidget *, cchar *);                                       //  enable area for subsequent edits
void  m_select_hide(GtkWidget *, cchar *);                                       //  show area outline
void  m_select_enable(GtkWidget *, cchar *);                                     //  hide area outline
void  m_select_disable(GtkWidget *, cchar *);                                    //  disable area
void  m_select_invert(GtkWidget *, cchar *);                                     //  invert area
void  m_select_unselect(GtkWidget *, cchar *);                                   //  unselect area
void  m_select_save(GtkWidget *, cchar *);                                       //  copy area or save area to a file
void  m_select_paste(GtkWidget *, cchar *);                                      //  paste last copied area into image
void  m_select_open(GtkWidget *, cchar *);                                       //  open file and paste as area in 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);                          //  draw a connected line
void  sa_draw1pix(int px, int py);                                               //  add one pixel to select area
void  sa_redraw();                                                               //  redraw area edge 
void  sa_mouse_select();                                                         //  select by mouse (opt. color match)
void  sa_nextseq();                                                              //  start next sequence number
void  sa_unselect_pixels();                                                      //  remove current selection
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);                                                         //  show or hide area outline
void  sa_show_rect(int px1, int py1, int ww, int hh);                            //  show area outline inside a rectangle
int   sa_validate();                                                             //  validate area for curr. image context
void  sa_enable();                                                               //  enable area
void  sa_disable();                                                              //  disable area
void  sa_invert();                                                               //  invert area
void  sa_unselect();                                                             //  unselect area
void  sa_edgecalc();                                                             //  calculate edge distances
void  sa_edgecreep(int);                                                         //  adjust area edge +/-
float sa_blendfunc(int edgedist);                                                //  calculate edge blend factor

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

void  m_trimrotate(GtkWidget *, cchar *);                                        //  combined trim/rotate function
void  m_upright(GtkWidget *, cchar *);                                           //  upright rotated image
void  m_voodoo1(GtkWidget *, cchar *);                                           //  automatic image retouch
void  m_voodoo2(GtkWidget *, cchar *);                                           //  automatic image retouch
void  m_combo(GtkWidget *, cchar *);                                             //  combo function, brightness/contrast/color
void  m_britedist(GtkWidget *, cchar *);                                         //  edit brightness distribution
void  m_zonal_flatten(GtkWidget *, cchar *);                                     //  flatten zonal brightness distribution
void  m_tonemap(GtkWidget *, cchar *);                                           //  tone mapping
void  m_resize(GtkWidget *, cchar *);                                            //  resize image
void  m_flip(GtkWidget *, cchar *);                                              //  flip horizontally or vertically
void  m_write_text(GtkWidget *, cchar *);                                        //  write 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_write_line(GtkWidget *, cchar *);                                        //  write line/arrow on image
int   genline(lineattr_t *attr);                                                 //  generate line/arrow image from attributes
void  m_paint_edits(GtkWidget *, cchar *);                                       //  select and edit in parallel
void  m_lever_edits(GtkWidget *, cchar *);                                       //  leverage edits by pixel bright/color
void  m_plugins(GtkWidget *, cchar *);                                           //  edit plugins menu or run a plugin function

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

void  m_sharpen(GtkWidget *, cchar *);                                           //  sharpen image
void  m_blur(GtkWidget *, cchar *);                                              //  blur image
void  m_denoise(GtkWidget *, cchar *);                                           //  image noise reduction
void  m_smart_erase(GtkWidget *, const char *);                                  //  smart erase object
void  m_redeye(GtkWidget *, cchar *);                                            //  red-eye removal
void  m_paint_clone(GtkWidget *, cchar *);                                       //  paint pixels with the mouse
void  m_paint_transp(GtkWidget *, cchar *);                                      //  paint transparnecy with the mouse
void  m_add_transp(GtkWidget *, cchar *);                                        //  add transparency based on image attributes
void  m_color_mode(GtkWidget *, cchar *);                                        //  B+W/color, negative/positive, sepia
void  m_shift_colors(GtkWidget *, cchar *);                                      //  shift one color into another color
void  m_colorsat(GtkWidget *, cchar *);                                          //  adjust color saturation
void  m_adjust_RGB(GtkWidget *, cchar *);                                        //  color adjust using RGB or CMY colors
void  m_adjust_HSL(GtkWidget *, cchar *);                                        //  color adjust with HSL
void  m_ramp_brightness(GtkWidget *, cchar *);                                   //  ramp brightness across image
void  m_ramp_color(GtkWidget *, cchar *);                                        //  ramp RGB color across image
void  m_match_color(GtkWidget *, cchar *);                                       //  set image2 colors to match image1
void  m_color_profile(GtkWidget *, cchar *);                                     //  convert to another color profile
void  m_remove_dust(GtkWidget *, const char *);                                  //  remove dust
void  m_anti_alias(GtkWidget *, const char *);                                   //  anti-alias
void  m_color_fringes(GtkWidget *, const char *);                                //  reduce chromatic abberation
void  m_stuck_pixels(GtkWidget *, const char *);                                 //  fix stuck pixels

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

void  m_unbend(GtkWidget *, cchar *);                                            //  fix perspective problems
void  m_perspective(GtkWidget *, cchar *);                                       //  warp tetragon into rectangle
void  m_warp_area(GtkWidget *, cchar *);                                         //  warp image within an area
void  m_warp_curved(GtkWidget *, cchar *);                                       //  warp image, curved transform
void  m_warp_linear(GtkWidget *, cchar *);                                       //  warp image, linear transform
void  m_warp_affine(GtkWidget *, cchar *);                                       //  warp image, affine transform
void  m_flatbook(GtkWidget *, cchar *);                                          //  flatten a photographed book page
void  m_sphere(GtkWidget *, cchar *);                                            //  image spherical projection
void  m_selective_rescale(GtkWidget *, cchar *);                                 //  rescale image, selected areas unchanged

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

void  m_colordep(GtkWidget *, cchar *);                                          //  set color depth 1-16 bits/color
void  m_sketch(GtkWidget *, cchar *);                                            //  convert image to pencil sketch
void  m_cartoon(GtkWidget *, cchar *);                                           //  convert image into a cartoon drawing
void  m_linedraw(GtkWidget *, cchar *);                                          //  comvert image to outline drawing
void  m_colordraw(GtkWidget *, cchar *);                                         //  convert image to solid color drawing
void  m_gradblur(GtkWidget *, cchar *);                                          //  graduated blur tool
void  m_emboss(GtkWidget *, cchar *);                                            //  convert image to simulated embossing
void  m_tiles(GtkWidget *, cchar *);                                             //  convert image to tile array (pixelate)
void  m_dots(GtkWidget *, cchar *);                                              //  convert image to dots (Roy Lichtenstein)
void  m_painting(GtkWidget *, cchar *);                                          //  convert image to simulated painting
void  m_vignette(GtkWidget *, cchar *);                                          //  vignette tool
void  m_texture(GtkWidget *, cchar *);                                           //  add texture to image
void  m_pattern(GtkWidget *, cchar *);                                           //  tile image with a pattern
void  m_mosaic(GtkWidget *, cchar *);                                            //  create mosaic using tiles made from images
void  m_anykernel(GtkWidget *, cchar *);                                         //  operate on image using a custom kernel
void  m_waves(GtkWidget *, cchar *);                                             //  warp image using a wave pattern
void  m_dirblur(GtkWidget *, cchar *);                                           //  blur image in the direction of mouse drags
void  m_blur_BG(GtkWidget *, cchar *);                                           //  blur image outside of selected areas

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

void  m_HDR(GtkWidget *, cchar *);                                               //  make HDR composite image
void  m_HDF(GtkWidget *, cchar *);                                               //  make HDF composite image
void  m_STP(GtkWidget *, cchar *);                                               //  stack / paint image
void  m_STN(GtkWidget *, cchar *);                                               //  stack / noise reduction
void  m_pano(GtkWidget *, cchar *);                                              //  make panorama composite image
void  m_vpano(GtkWidget *, cchar *);                                             //  make vertical panorama
void  m_pano_PT(GtkWidget *, cchar *);                                           //  make panorama via pano tools

//  mashup function - f.mashup.cc

void  m_mashup(GtkWidget *, cchar *);                                            //  arrange images on a background image

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

void  m_index(GtkWidget *, cchar *);                                             //  rebuild image index and thumbnails
void  index_rebuild(int menu);                                                   //  index rebuild function
void  m_options(GtkWidget *, cchar *);                                           //  user options
void  m_KBshortcuts(GtkWidget *, cchar *);                                       //  edit KB shortcuts, update file
int   KBshortcuts_load();                                                        //  load KB shortcuts at startup time
void  m_show_brdist(GtkWidget *, cchar *);                                       //  show brightness distribution graph
void  brdist_drawgraph(GtkWidget *drawin, cairo_t *cr, int *);                   //  draw brightness distribution graph
void  brdist_drawscale(GtkWidget *drawarea, cairo_t *cr, int *);                 //  draw brightness scale, black to white band
void  m_gridlines(GtkWidget *, cchar *);                                         //  grid lines setup dialog
void  toggle_grid(int action);                                                   //  set grid off/on or toggle (0/1/2)
void  m_line_color(GtkWidget *, cchar *);                                        //  foreground line color (area/mouse/trim...)
void  m_show_RGB(GtkWidget *, cchar *);                                          //  show RGB values at mouse click
void  m_magnify(GtkWidget *, cchar *);                                           //  magnify image within a radius of the mouse
void  m_darkbrite(GtkWidget *, cchar *);                                         //  highlight the darkest and brightest pixels
void  darkbrite_paint();                                                         //  paint function called from Fpaint()
void  m_moncolor(GtkWidget *, cchar *);                                          //  check monitor brightness and color
void  m_mongamma(GtkWidget *, cchar *);                                          //  adjust monitor gamma
void  m_changelang(GtkWidget *, cchar *);                                        //  change language
void  m_untranslated(GtkWidget *, cchar *);                                      //  report missing translations
void  m_calibrate_printer(GtkWidget *, cchar *);                                 //  calibrate printer colors
void  print_calibrated();                                                        //  print image with adjusted colors      15.10
void  m_resources(GtkWidget *, cchar *);                                         //  report CPU and memory usage
void  m_zappcrash(GtkWidget *, cchar *);                                         //  deliberate zappcrash (test function)

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

char  * gallery(cchar *filez, cchar *action, int Nth = 0);                       //  display image gallery window, navigate
void    set_gwin_title();                                                        //  main window title = gallery name
char  * gallery_getnext(int index, int lastver);                                 //  get prev/next file with last version option
char  * prev_next_gallery(int index);                                            //  get prev/next gallery (physical directory)
int     gallery_position(cchar *file, int Nth);                                  //  get rel. position of file in gallery
FTYPE   image_file_type(cchar *file);                                            //  file type: FNF DIRK IMAGE RAW THUMB OTHER
char  * thumb2imagefile(cchar *thumbfile);                                       //  get image file for thumbnail file
char  * image2thumbfile(cchar *imagefile);                                       //  get thumbnail file for image file
char  * image_thumbfile(char *imagefile, int *ind = 0);                          //  get thumbnail filespec, create if missing
PIXBUF * image_thumbnail(char *imagefile, int size = 0);                         //  get thumbnail pixbuf, create if nec.
void    image_thumbnail_delete(char *thumbfile);                                 //  delete thumbnail, file and cache
PIXBUF * get_thumbnail_pixbuf(char *imagefile, int size);                        //  make thumbnail pixbuf from image file
void    popimage();                                                              //  popup big image of clicked thumbnail
void    gallery_monitor(cchar *action);                                          //  start/stop gallery directory monitor
char ** gallery_getfiles(char **initfiles = 0);                                  //  select files from gallery window
void    gallery_getfiles_Lclick_func(int Nth);                                   //  get files, thumbnail left-click
void    gallery_getfiles_Rclick_func(int Nth);                                   //  get files, thumbnail right-click
void    m_edit_bookmarks(GtkWidget *, cchar *);                                  //  edit bookmarks (gallery/file position)
void    m_goto_bookmark(GtkWidget *, cchar *);                                   //  select bookmarked image, goto gallery posn
void    bookmarks_Lclick_func(int Nth);                                          //  thumbnail click response function

//  albums menu (f.albums.cc)

void  m_manage_albums(GtkWidget *, cchar *);                                     //  create and edit image albums
void  album_pastefile(char *file, int posn);                                     //  insert file at position               16.08
void  album_movefile(int pos1, int pos2);                                        //  move file position in album           16.08
void  album_show(char *file = 0);                                                //  show current album in gallery
void  conv_albums(char **, char **, int);                                        //  convert after files renamed/moved
void  m_copyto_cache(GtkWidget *, cchar *);                                      //  copy an image file to the file cache
void  m_album_removefile(GtkWidget *, cchar *);                                  //  remove image from album
void  m_album_cutfile(GtkWidget *, cchar *);                                     //  remove image from album, add to cache
void  m_album_pastecache(GtkWidget *, cchar *);                                  //  paste image cache to album position

void  m_slideshow(GtkWidget *, cchar *);                                         //  enter or leave slideshow mode
void  ss_imageprefs_Lclick_func(int Nth);                                        //  slideshow image prefs thumbnail click func
void  slideshow_next(cchar *);                                                   //  show prev/next image
void  m_setdesktop(GtkWidget *, cchar *);                                        //  set desktop wallpaper from curr. file
void  m_cycledesktop(GtkWidget *, cchar *);                                      //  cycle desktop wallpaper from a Fotoxx album
void  run_cycledesktop(cchar *album, cchar *secs);                               //  cycle desktop wallpaper function

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

void  m_batch_convert(GtkWidget *, cchar *);                                     //  rename/convert/resize/export image files
int   batch_sharp_func(PXM *pxm, int amount, int thresh);                        //  callable sharpen func used by batch funcs
void  m_batch_upright(GtkWidget *, cchar *);                                     //  upright rotated image files
void  m_batch_deltrash(GtkWidget *, cchar *);                                    //  delete or trash selected files
void  m_batch_raw(GtkWidget *, cchar *);                                         //  convert RAW files with libraw         16.07
void  m_batch_rawtherapee(GtkWidget *, cchar *);                                 //  convert RAW files with Raw Therapee
void  m_scriptfiles(GtkWidget *, cchar *);                                       //  build and run edit script files       15.10
int   addscript(editfunc *);                                                     //  add edit function to script           15.10
void  m_burn(GtkWidget *, cchar *);                                              //  burn selected images to CD/DVD
void  m_duplicates(GtkWidget *, cchar *);                                        //  find duplicate image files
void  m_imagelist(GtkWidget *, cchar *);                                         //  create a file of selected images      16.02

//  PXM and PXB pixmap image functions (f.image.cc)

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)

void  PXM_audit(PXM *pxm);                                                       //  audit contents of a PXM pixmap
PXM * PXM_make(int ww, int hh, int nc);                                          //  create a PXM pixmap
void  PXM_free(PXM *&pxm);                                                       //  free PXM pixmap
void  PXM_addalpha(PXM *pxm);                                                    //  add alpha channel to PXM pixmap       15.08
PXM * PXM_copy(PXM *pxm);                                                        //  copy PXM pixmap
PXM * PXM_copy_area(PXM *pxm, int orgx, int orgy, int ww, int hh);               //  copy section of PXM pixmap
void  PXM_fixblue(PXM *pxm);                                                     //  set blue = 0 pixels to blue = 2
PXM * PXM_rescale(PXM *pxm, int ww, int hh);                                     //  rescale PXM pixmap (ww/hh)
PXM * PXM_rotate(PXM *pxm, float angle);                                         //  rotate PXM pixmap

PXB * PXB_make(int ww, int hh, int ac);                                          //  create a PXB pixmap
PXB * PXB_make(PIXBUF *pixbuf);                                                  //  create a PXB pixmap from a pixbuf
void  PXB_free(PXB *&pxb);                                                       //  free PXB pixmap
void  PXB_addalpha(PXB *pxb);                                                    //  add alpha channel to PXB pixmap       15.08
PXB * PXB_copy(PXB *pxb);                                                        //  copy PXB
PXB * PXB_rescale(PXB *pxb, int ww, int hh);                                     //  rescale PXB pixmap (ww/hh)
PXB * PXB_rotate(PXB *pxb, float angle);                                         //  rotate PXB pixmap                     15.04

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

PIXBUF * pixbuf_rescale_fast(PIXBUF *pixbuf1, int ww, int hh);                   //  faster gdk_pixbuf_scale_simple()


//  translatable strings used in multiple dialogs

#define Badd ZTX("Add")
#define Baddall ZTX("Add All")
#define Ball ZTX("All")
#define Bamount ZTX("Amount")
#define Bangle ZTX("Angle")
#define Bapply ZTX("Apply")
#define Bauto ZTX("Auto")
#define Bblack ZTX("Black")
#define Bblendwidth ZTX("Blend Width")
#define Bblue ZTX("Blue")
#define Bbottom ZTX("Bottom")
#define Bbrightness ZTX("Brightness")
#define Bbrowse ZTX("Browse")
#define Bcancel ZTX("Cancel")
#define Bcenter ZTX("Center")
#define Bchoose ZTX("Choose")
#define Bclear ZTX("Clear")
#define Bclose ZTX("Close")
#define Bcolor ZTX("Color")
#define Bcompleted ZTX("COMPLETED")
#define Bcontinue ZTX("continue")
#define Bcontrast ZTX("Contrast")
#define Bcopy ZTX("Copy")
#define Bcreate ZTX("Create")
#define Bcurvefile ZTX("Curve File:")
#define Bcut ZTX("Cut")
#define Bdeband ZTX("Deband")
#define Bdelete ZTX("Delete")
#define Bdisable ZTX("Disable")
#define Bdone ZTX("Done")
#define Bedge ZTX("edge")
#define Bedit ZTX("Edit")
#define Benable ZTX("Enable")
#define Berase ZTX("Erase")
#define Bfetch ZTX("Fetch")
#define Bfileexists ZTX("output file already exists")
#define Bfileselected ZTX("%d files selected")
#define Bfind ZTX("Find")
#define Bfinish ZTX("Finish")
#define Bflatten ZTX("Flatten")
#define Bfont ZTX("Font")
#define Bgreen ZTX("Green")
#define Bgrid ZTX("Grid")
#define Bheight ZTX("Height")
#define Bhelp ZTX("Help")
#define Bhide ZTX("Hide")
#define Bimage ZTX("Image")
#define Bimages ZTX("Images")
#define Binsert ZTX("Insert")
#define Binvert ZTX("Invert")
#define Bkeep ZTX("Keep")
#define Bleft ZTX("Left")
#define Blimit ZTX("limit")
#define Bload ZTX("Load")
#define Bmake ZTX("Make")
#define Bmanagetags ZTX("Manage Tags")
#define Bmap ZTX("Map")
#define Bmatchlev ZTX("Match Level")
#define Bmax ZTX("Max")
#define Bnegative ZTX("Negative")
#define Bnew ZTX("New")
#define Bnext ZTX("Next")
#define Bno ZTX("No")
#define Bnoimages ZTX("no images")
#define Bnofileselected ZTX("no files selected")
#define Bnoselection ZTX("no selection")
#define BOK ZTX("OK")
#define Bopen ZTX("Open")
#define Bpaste ZTX("Paste")
#define Bpause ZTX("Pause")
#define Bpercent ZTX("Percent")
#define Bpower ZTX("Power")
#define Bpresets ZTX("Presets")
#define Bprev ZTX("Prev")
#define Bproceed ZTX("Proceed")
#define Bradius ZTX("Radius")
#define Brange ZTX("range")
#define Bred ZTX("Red")
#define Bredo ZTX("Redo")
#define Breduce ZTX("Reduce")
#define Bremove ZTX("Remove")
#define Brename ZTX("Rename")
#define Breplace ZTX("Replace")
#define Breserved ZTX("Reserved")
#define Breset ZTX("Reset")
#define Bright ZTX("Right")
#define Brotate ZTX("Rotate")
#define Brun ZTX("Run")
#define Bsave ZTX("Save")
#define Bsearch ZTX("Search")
#define Bseconds ZTX("Seconds")
#define Bselect ZTX("Select")
#define Bselectfiles ZTX("Select Files")
#define Bshow ZTX("Show")
#define Bsize ZTX("Size")
#define Bstart ZTX("Start")
#define Bstrength ZTX("Strength")
#define Bthresh ZTX("Threshold")
#define Btoomanyfiles ZTX("exceed %d files")
#define Btop ZTX("Top")
#define Btransparency ZTX("Transparency")
#define Btrash ZTX("Trash")
#define Btrim ZTX("Trim")
#define Bundoall ZTX("Undo All")
#define Bundolast ZTX("Undo Last")
#define Bundo ZTX("Undo")
#define Bunfinish ZTX("Unfinish")
#define Bunselect ZTX("Unselect")
#define Bview ZTX("View")
#define Bweb ZTX("Web")
#define Bwhite ZTX("White")
#define Bwidth ZTX("Width")
#define Bxoffset ZTX("x-offset")
#define Byoffset ZTX("y-offset")
#define Byes ZTX("Yes")


