f.meta.cc (fotoxx-22.30) | : | f.meta.cc (fotoxx-22.35) | ||
---|---|---|---|---|
skipping to change at line 508 | skipping to change at line 508 | |||
if (pp && strlen(pp) > 7 && pp[7] == ':') pp[7] = '-'; | if (pp && strlen(pp) > 7 && pp[7] == ':') pp[7] = '-'; | |||
pp = keyval[3]; | pp = keyval[3]; | |||
if (pp && strlen(pp) > 4 && pp[4] == ':') pp[4] = '-'; | if (pp && strlen(pp) > 4 && pp[4] == ':') pp[4] = '-'; | |||
if (pp && strlen(pp) > 7 && pp[7] == ':') pp[7] = '-'; | if (pp && strlen(pp) > 7 && pp[7] == ':') pp[7] = '-'; | |||
textwidget_append(widget,0,"File %s \n",filen); | textwidget_append(widget,0,"File %s \n",filen); | |||
textwidget_append(widget,0,"Size %s %s \n",keyval[0],chsize); | textwidget_append(widget,0,"Size %s %s \n",keyval[0],chsize); | |||
textwidget_append(widget,0,"Dates photo: %s file: %s \n",keyval[2],key val[3]); | textwidget_append(widget,0,"Dates photo: %s file: %s \n",keyval[2],key val[3]); | |||
if (keyval[4] || keyval[5]) | if (keyval[4] || keyval[5]) | |||
textwidget_append(widget,0,"Camera %s %s \n",keyval[4],keyval[5]); | textwidget_append(widget,0,"Camera make: %s model: %s \n",keyval[4], keyval[5]); | |||
if (keyval[6] || keyval[7] || keyval[8] || keyval[9] || keyval[10]) // photo exposure data | if (keyval[6] || keyval[7] || keyval[8] || keyval[9] || keyval[10]) // photo exposure data | |||
{ | { | |||
if (keyval[6]) focallength = keyval[6]; // focal length, 35mm equivalent | if (keyval[6]) focallength = keyval[6]; // focal length, 35mm equivalent | |||
else if (keyval[7]) focallength = keyval[7]; // focal length, actual mm | else if (keyval[7]) focallength = keyval[7]; // focal length, actual mm | |||
else focallength = 0; // missing | else focallength = 0; // missing | |||
strcpy(chsec,"null"); | strcpy(chsec,"null"); | |||
if (keyval[8]) { | if (keyval[8]) { | |||
fsecs = atofz(keyval[8]); // convert 0.008 seconds to 1/125 etc. | fsecs = atofz(keyval[8]); // convert 0.008 seconds to 1/125 etc. | |||
if (fsecs > 0 && fsecs <= 0.5) { | if (fsecs > 0 && fsecs <= 0.5) { | |||
skipping to change at line 1731 | skipping to change at line 1731 | |||
zdialog_fetch(zd,"kall",kall); | zdialog_fetch(zd,"kall",kall); | |||
zdialog_fetch(zd,"key1",key1); | zdialog_fetch(zd,"key1",key1); | |||
zdialog_fetch(zd,"keyname",keyname,80); | zdialog_fetch(zd,"keyname",keyname,80); | |||
strCompress(keyname); | strCompress(keyname); | |||
if (! kall && ! key1) return 1; | if (! kall && ! key1) return 1; | |||
file = zescape_quotes(curr_file); | file = zescape_quotes(curr_file); | |||
if (kall) // update file metadata | if (kall) // update file metadata | |||
zshell("ack","exiftool -m -q -overwrite_original -all= \"%s\"",file); | zshell("log ack","exiftool -m -q -overwrite_original -all= \"%s\"",file); | |||
else if (key1) | else if (key1) | |||
zshell("ack","exiftool -m -q -overwrite_original -%s= \"%s\"",keyname,fil e); | zshell("log ack","exiftool -m -q -overwrite_original -%s= \"%s\"",keyname ,file); | |||
zfree(file); | zfree(file); | |||
load_filemeta(curr_file); // update image index in case a | load_filemeta(curr_file); // update image index in case a | |||
update_image_index(curr_file); // searchable metadata deleted | update_image_index(curr_file); // searchable metadata deleted | |||
if (zd_metaview) meta_view(0); // update exif view if active | if (zd_metaview) meta_view(0); // update exif view if active | |||
return 1; | return 1; | |||
} | } | |||
skipping to change at line 5379 | skipping to change at line 5379 | |||
int nt, cc1, cc2, ff, nf; | int nt, cc1, cc2, ff, nf; | |||
char *pp1, *pp2; | char *pp1, *pp2; | |||
char entertag[tagcc], matchtags[20][tagcc]; | char entertag[tagcc], matchtags[20][tagcc]; | |||
char matchtagstext[(tagcc+2)*20]; | char matchtagstext[(tagcc+2)*20]; | |||
char catgname[tagcc]; | char catgname[tagcc]; | |||
char albumfile[200]; | char albumfile[200]; | |||
zlist_t *ZLsearch; | zlist_t *ZLsearch; | |||
if (strmatch(event,"escape")) { // escape key | if (strmatch(event,"escape")) { // escape key | |||
if (Fescape) Fescape++; // kill running search | if (Fescape) Fescape++; // kill running search | |||
else zd->zstat = -1; // kill dialog | else zd->zstat = -1; // else kill dialog | |||
return 1; | return 1; | |||
} | } | |||
if (strmatch(event,"proceed")) zd->zstat = 4; // "proceed" from autosearch | if (strmatch(event,"proceed")) zd->zstat = 4; // "proceed" from autosearch | |||
if (strmatch(event,"addmeta")) | ||||
// get other metadata criteria | ||||
Fmeta = searchimages_metadata_dialog(zd); | ||||
if (Fmeta) zdialog_stuff(zd,"metadata#","(*)"); | ||||
// show presence of metadata criteria | ||||
else zdialog_stuff(zd,"metadata#","(_)"); | ||||
if (zd->zstat == 1) { // [load] settings from file | if (zd->zstat == 1) { // [load] settings from file | |||
zd->zstat = 0; | zd->zstat = 0; | |||
zdialog_load_widgets(zd,null,"saved_searches",null); | zdialog_load_widgets(zd,null,"saved_searches",null); | |||
zdialog_fetch(zd,"searchtags",searchtags,tagScc); | zdialog_fetch(zd,"searchtags",searchtags,tagScc); | |||
strcat(searchtags," "); // trailing blank after "tagname," | strcat(searchtags," "); // trailing blank after "tagname," | |||
return 1; | ||||
} | } | |||
if (zd->zstat == 2) { // [save] settings to file | if (zd->zstat == 2) { // [save] settings to file | |||
zd->zstat = 0; | zd->zstat = 0; | |||
zdialog_save_widgets(zd,null,"saved_searches",null); | zdialog_save_widgets(zd,null,"saved_searches",null); | |||
return 1; | ||||
} | } | |||
if (zd->zstat == 3) // [clear] selection criteria | if (zd->zstat == 3) // [clear] selection criteria | |||
{ | { | |||
zd->zstat = 0; // keep dialog active | ||||
zdialog_stuff(zd,"allimages",1); | zdialog_stuff(zd,"allimages",1); | |||
zdialog_stuff(zd,"currset",0); | zdialog_stuff(zd,"currset",0); | |||
zdialog_stuff(zd,"newset",1); | zdialog_stuff(zd,"newset",1); | |||
zdialog_stuff(zd,"addset",0); | zdialog_stuff(zd,"addset",0); | |||
zdialog_stuff(zd,"remset",0); | zdialog_stuff(zd,"remset",0); | |||
zdialog_stuff(zd,"repgallery",1); | zdialog_stuff(zd,"repgallery",1); | |||
zdialog_stuff(zd,"repmeta",0); | zdialog_stuff(zd,"repmeta",0); | |||
zdialog_stuff(zd,"lastver",0); | zdialog_stuff(zd,"lastver",0); | |||
zdialog_stuff(zd,"org+last",0); | zdialog_stuff(zd,"org+last",0); | |||
zdialog_stuff(zd,"allvers",0); | zdialog_stuff(zd,"allvers",0); | |||
skipping to change at line 5434 | skipping to change at line 5431 | |||
zdialog_stuff(zd,"photodate",1); | zdialog_stuff(zd,"photodate",1); | |||
zdialog_stuff(zd,"filedate",0); | zdialog_stuff(zd,"filedate",0); | |||
zdialog_stuff(zd,"ratingfrom",""); | zdialog_stuff(zd,"ratingfrom",""); | |||
zdialog_stuff(zd,"ratingto",""); | zdialog_stuff(zd,"ratingto",""); | |||
zdialog_stuff(zd,"searchtags",""); | zdialog_stuff(zd,"searchtags",""); | |||
zdialog_stuff(zd,"searchtext",""); | zdialog_stuff(zd,"searchtext",""); | |||
zdialog_stuff(zd,"searchfiles",""); | zdialog_stuff(zd,"searchfiles",""); | |||
zdialog_stuff(zd,"searchlocs",""); | zdialog_stuff(zd,"searchlocs",""); | |||
*searchtags = 0; | *searchtags = 0; | |||
Flocs = 0; | Flocs = 0; | |||
*searchLocations = 0; | *searchLocations = 0; | |||
zdialog_stuff(zd,"metadata#","( )"); | ||||
Fmeta = 0; | Fmeta = 0; | |||
Nsearchkeys = 0; | Nsearchkeys = 0; | |||
zdialog_stuff(zd,"metadata#","( )"); | ||||
return 1; | ||||
} | ||||
if (zd->zstat == 4) { // [proceed] with search | ||||
zd->zstat = 0; // keep dialog active | zd->zstat = 0; // keep dialog active | |||
return 1; | goto proceed; | |||
} | } | |||
if (zd->zstat < 0 || zd->zstat == 5) return 1; | ||||
// [x] or [cancel] | ||||
if (strmatch(event,"addmeta")) | ||||
// get other metadata criteria | ||||
Fmeta = searchimages_metadata_dialog(zd); | ||||
if (Fmeta) zdialog_stuff(zd,"metadata#","(*)"); | ||||
// show presence of metadata criteria | ||||
else zdialog_stuff(zd,"metadata#","(_)"); | ||||
if (zstrstr("lastver org+last allvers nochange",event)) { // if any selected, | if (zstrstr("lastver org+last allvers nochange",event)) { // if any selected, | |||
zdialog_stuff(zd,"lastver",0); // deselect the others | zdialog_stuff(zd,"lastver",0); // deselect the others | |||
zdialog_stuff(zd,"org+last",0); | zdialog_stuff(zd,"org+last",0); | |||
zdialog_stuff(zd,"allvers",0); | zdialog_stuff(zd,"allvers",0); | |||
zdialog_stuff(zd,"nochange",0); | zdialog_stuff(zd,"nochange",0); | |||
zdialog_stuff(zd,event,1); | zdialog_stuff(zd,event,1); | |||
} | } | |||
if (strmatch(event,"entertag")) // new tag is being typed in | if (strmatch(event,"entertag")) // new tag is being typed in | |||
{ | { | |||
skipping to change at line 5516 | skipping to change at line 5522 | |||
zdialog_stuff(zd,"matchtags",matchtagstext); // stuff matchtags in dialog | zdialog_stuff(zd,"matchtags",matchtagstext); // stuff matchtags in dialog | |||
return 1; | return 1; | |||
} | } | |||
if (strmatch(event,"defcats")) { // new tag category selection | if (strmatch(event,"defcats")) { // new tag category selection | |||
zdialog_fetch(zd,"defcats",catgname,tagcc); | zdialog_fetch(zd,"defcats",catgname,tagcc); | |||
deftags_stuff(zd,catgname); | deftags_stuff(zd,catgname); | |||
} | } | |||
if (zd->zstat != 4) return 1; | return 1; | |||
// cancel if not [proceed] | // wait for dialog completion | |||
proceed: | ||||
// Inputs are complete. Validate all inputs. ---------------------------------- - | // Inputs are complete. Validate all inputs. ---------------------------------- - | |||
zdialog_fetch(zd,"allimages",Fscanall); // search all images | zdialog_fetch(zd,"allimages",Fscanall); // search all images | |||
zdialog_fetch(zd,"currset",Fscancurr); // search current set (gallery) | zdialog_fetch(zd,"currset",Fscancurr); // search current set (gallery) | |||
zdialog_fetch(zd,"newset",Fnewset); // matching images --> new set | zdialog_fetch(zd,"newset",Fnewset); // matching images --> new set | |||
zdialog_fetch(zd,"addset",Faddset); // add matching image to set | zdialog_fetch(zd,"addset",Faddset); // add matching image to set | |||
zdialog_fetch(zd,"remset",Fremset); // remove matching images from set | zdialog_fetch(zd,"remset",Fremset); // remove matching images from set | |||
if (Fremset && Fscanall) { // illogical search | if (Fremset && Fscanall) { // illogical search | |||
skipping to change at line 5973 | skipping to change at line 5981 | |||
gallery(0,"paint",0); // position at top | gallery(0,"paint",0); // position at top | |||
m_viewmode(0,"G"); | m_viewmode(0,"G"); | |||
zdialog_free(zd); | zdialog_free(zd); | |||
return 1; | return 1; | |||
usercancel: // cancel via escape key | usercancel: // cancel via escape key | |||
zmessage_post_bold(Mwin,"parent",1,"function canceled"); | zmessage_post_bold(Mwin,"parent",1,"function canceled"); | |||
zadd_locked(Ffuncbusy,-1); | zadd_locked(Ffuncbusy,-1); | |||
Fescape = 0; | Fescape = 0; | |||
progress_reset(0); // 22.35 | ||||
zdialog_free(zd); | zdialog_free(zd); | |||
return 1; | return 1; | |||
filerror: | filerror: | |||
zmessageACK(Mwin,"file error: %s",strerror(errno)); | zmessageACK(Mwin,"file error: %s",strerror(errno)); | |||
zadd_locked(Ffuncbusy,-1); | zadd_locked(Ffuncbusy,-1); | |||
Fescape = 0; | Fescape = 0; | |||
progress_reset(0); // 22.35 | ||||
zdialog_free(zd); | zdialog_free(zd); | |||
return 1; | return 1; | |||
} | } | |||
// search images, thread process | // search images, thread process | |||
// arg is xxrec[*] index of image to test for selection or exclusion | ||||
void * searchimages_thread(void *arg) | void * searchimages_thread(void *arg) | |||
{ | { | |||
int searchimages_select(xxrec_t *xxrec); | int searchimages_select(xxrec_t *xxrec); | |||
int ii, match = 0; | int ii, match = 0; | |||
xxrec_t *xxrec; | xxrec_t *xxrec; | |||
char *file; | char *file; | |||
ii = *((int *) arg); // test xxrec_tab[ii] | ii = *((int *) arg); // test xxrec_tab[ii] | |||
skipping to change at line 6599 | skipping to change at line 6610 | |||
if (fkey >= fval) goto ret1; // found match | if (fkey >= fval) goto ret1; // found match | |||
} | } | |||
else if (matchtype == '<') { // numeric key <= one value | else if (matchtype == '<') { // numeric key <= one value | |||
fkey = atofz(keyval); | fkey = atofz(keyval); | |||
fval = atofz(pps); | fval = atofz(pps); | |||
if (fkey <= fval) goto ret1; // found match | if (fkey <= fval) goto ret1; // found match | |||
} | } | |||
else { | else { | |||
Plog(1,"searchmeta invalid matchtype %c \n",matchtype); | Plog(0,"searchmeta invalid matchtype %c \n",matchtype); | |||
zfree(pps); | zfree(pps); | |||
return 0; | return 0; | |||
} | } | |||
} | } | |||
ret1: | ret1: | |||
zfree(pps); | zfree(pps); | |||
return 1; | return 1; | |||
} | } | |||
skipping to change at line 7198 | skipping to change at line 7209 | |||
if (catoverflow) goto cattoobig; | if (catoverflow) goto cattoobig; | |||
// parse all the tags in each category and sort in ascending order | // parse all the tags in each category and sort in ascending order | |||
for (ii = 0; ii < ncats; ii++) | for (ii = 0; ii < ncats; ii++) | |||
{ | { | |||
pp1 = tags_deftags[ii]; | pp1 = tags_deftags[ii]; | |||
pp2 = strchr(pp1,':'); | pp2 = strchr(pp1,':'); | |||
if (! pp2) { | if (! pp2) { | |||
Plog(1,"defined tags file format error: %s \n",pp1); | Plog(0,"defined tags file format error: %s \n",pp1); | |||
continue; | continue; | |||
} | } | |||
cc = pp2 - pp1 + 1; | cc = pp2 - pp1 + 1; | |||
strncpy0(catg,pp1,cc); | strncpy0(catg,pp1,cc); | |||
pp1 = pp2 + 1; | pp1 = pp2 + 1; | |||
while (*pp1 == ' ') pp1++; | while (*pp1 == ' ') pp1++; | |||
tcc = 0; | tcc = 0; | |||
for (jj = 0; jj < maxtags; jj++) | for (jj = 0; jj < maxtags; jj++) | |||
{ | { | |||
skipping to change at line 7879 | skipping to change at line 7890 | |||
if (! xmeta_keys[ii]) break; | if (! xmeta_keys[ii]) break; | |||
if (strlen(xmeta_keys[ii]) + strlen(xmeta_data[ii]) > 100) continue; // impractical for image search | if (strlen(xmeta_keys[ii]) + strlen(xmeta_data[ii]) > 100) continue; // impractical for image search | |||
strcpy(xmetarec+xcc,xmeta_keys[ii]); // construct series | strcpy(xmetarec+xcc,xmeta_keys[ii]); // construct series | |||
xcc += strlen(xmeta_keys[ii]); // "keyname=keydata^ " | xcc += strlen(xmeta_keys[ii]); // "keyname=keydata^ " | |||
xmetarec[xcc++] = '='; | xmetarec[xcc++] = '='; | |||
strcpy(xmetarec+xcc,xmeta_data[ii]); | strcpy(xmetarec+xcc,xmeta_data[ii]); | |||
xcc += strlen(xmeta_data[ii]); | xcc += strlen(xmeta_data[ii]); | |||
strcpy(xmetarec+xcc,"^ "); | strcpy(xmetarec+xcc,"^ "); | |||
xcc += 2; | xcc += 2; | |||
if (xcc > 895) { | if (xcc > 895) { | |||
Plog(1,"file metadata exceeds record size: %s \n",file); | Plog(0,"file metadata exceeds record size: %s \n",file); | |||
break; | break; | |||
} | } | |||
} | } | |||
if (xcc > 0) xxrec.xmeta = xmetarec; | if (xcc > 0) xxrec.xmeta = xmetarec; | |||
else xxrec.xmeta = (char *) "null"; // put_xxrec() uses zstrdup() | else xxrec.xmeta = (char *) "null"; // put_xxrec() uses zstrdup() | |||
put_xxrec(&xxrec,file); // update image index | put_xxrec(&xxrec,file); // update image index | |||
gallery(file,"update",0); // update gallery record | gallery(file,"update",0); // update gallery record | |||
skipping to change at line 7937 | skipping to change at line 7948 | |||
zdialog_fetch(zd,"location",location,100); // get zdialog inputs | zdialog_fetch(zd,"location",location,100); // get zdialog inputs | |||
zdialog_fetch(zd,"country",country,100); | zdialog_fetch(zd,"country",country,100); | |||
if (*location <= ' ' || *country <= ' ') return badinputs; | if (*location <= ' ' || *country <= ' ') return badinputs; | |||
*location = toupper(*location); // capitalize | *location = toupper(*location); // capitalize | |||
*country = toupper(*country); | *country = toupper(*country); | |||
snprintf(outfile,100,"%s/web-data",temp_folder); | snprintf(outfile,100,"%s/web-data",temp_folder); | |||
snprintf(URI,299,"\"%s&location=%s,%s\"",query,location,country); | snprintf(URI,299,"\"%s&location=%s,%s\"",query,location,country); | |||
err = zshell(0,"wget -T 10 -o /dev/null -O %s %s",outfile,URI); | err = zshell("log ack","wget -T 10 -o /dev/null -O %s %s",outfile,URI); | |||
if (err) return strerror(err); | if (err) return strerror(err); | |||
fid = fopen(outfile,"r"); // get response | fid = fopen(outfile,"r"); // get response | |||
if (! fid) return notfound; | if (! fid) return notfound; | |||
pp1 = fgets(buffer,200,fid); | pp1 = fgets(buffer,200,fid); | |||
pp1 = fgets(buffer,200,fid); | pp1 = fgets(buffer,200,fid); | |||
fclose(fid); | fclose(fid); | |||
if (! pp1) return notfound; | if (! pp1) return notfound; | |||
Plog(1,"web geocode: %s \n",buffer); | Plog(1,"web geocode: %s \n",buffer); | |||
skipping to change at line 8547 | skipping to change at line 8558 | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// download collection of Fotoxx file maps (replaces fotoxx-maps package) | // download collection of Fotoxx file maps (replaces fotoxx-maps package) | |||
void m_download_maps(GtkWidget *, cchar *menu) // 22.30 | void m_download_maps(GtkWidget *, cchar *menu) // 22.30 | |||
{ | { | |||
int err, nn; | int err, nn; | |||
zdialog *zd; | zdialog *zd; | |||
char mapindex[200]; | char mapindex[200]; | |||
cchar *message = "Download Fotoxx map files? \n" | cchar *message = "Download Fotoxx map files? \n" | |||
"(130 MB - may need some time)"; | "(200 MB - may need some time)"; | |||
cchar *wget_command = "wget -q -O %s/fotoxx-maps.zip " | cchar *wget_command = "wget -q -O %s/fotoxx-maps.zip " | |||
"https://kornelix.net/downloads/downloads/fotoxx-maps.zip"; | "https://kornelix.net/downloads/downloads/fotoxx-maps.zip"; | |||
F1_help_topic = "download maps"; | F1_help_topic = "download maps"; | |||
Plog(1,"m_download_maps \n"); | Plog(1,"m_download_maps \n"); | |||
nn = zmessageYN(Mwin,message); | nn = zmessageYN(Mwin,message); | |||
if (! nn) return; | if (! nn) return; | |||
zd = zmessage_post_bold(0,"mouse",0,"download in progress"); | zd = zmessage_post_bold(0,"mouse",0,"download in progress"); | |||
err = zshell_gtk("log",wget_command, file_maps_folder); | err = zshell_gtk("log ack",wget_command, file_maps_folder); | |||
zdialog_free(zd); | zdialog_free(zd); | |||
if (err) return; | ||||
if (err) { | err = zshell("log ack","unzip -o %s/fotoxx-maps.zip -d %s", | |||
zmessageACK(Mwin,"download failed - check log file"); | ||||
return; | ||||
} | ||||
err = zshell("log","unzip -o %s/fotoxx-maps.zip -d %s", | ||||
file_maps_folder, file_maps_folder); | file_maps_folder, file_maps_folder); | |||
if (err) { | if (err) return; | |||
zmessageACK(Mwin,"unzip failed - check log file"); | ||||
return; | ||||
} | ||||
err = zshell("log","rm %s/fotoxx-maps.zip",file_maps_folder); | err = zshell(0,"rm %s/fotoxx-maps.zip",file_maps_folder); | |||
zmessageACK(Mwin,"download completed"); | zmessageACK(Mwin,"download completed"); | |||
snprintf(mapindex,200,"%s/maps_index",file_maps_folder); // look for map index file | snprintf(mapindex,200,"%s/maps_index",file_maps_folder); // look for map index file | |||
if (! regfile(mapindex)) | if (! regfile(mapindex)) | |||
zmessageACK(Mwin,"maps_index file not found"); | zmessageACK(Mwin,"maps_index file not found"); | |||
return; | return; | |||
} | } | |||
skipping to change at line 8653 | skipping to change at line 8657 | |||
pp = fgets_trim(buff,200,fid,1); // get map file names | pp = fgets_trim(buff,200,fid,1); // get map file names | |||
if (! pp) break; | if (! pp) break; | |||
pp = substring(pp,",",1); | pp = substring(pp,",",1); | |||
if (! pp) continue; | if (! pp) continue; | |||
maplist[Nmaps] = zstrdup(pp,"load_filemap"); | maplist[Nmaps] = zstrdup(pp,"load_filemap"); | |||
Nmaps++; | Nmaps++; | |||
} | } | |||
fclose(fid); | fclose(fid); | |||
pp = (char *) zdialog_picklist("Choose File Map",Mwin,maplist,Nmaps); | pp = (char *) popup_picklist(Mwin,(cchar **) maplist,0,Nmaps); // 22.35 | |||
if (! pp) return; | if (! pp) return; | |||
err = load_filemap(pp); | err = load_filemap(pp); | |||
for (ii = 0; ii < Nmaps; ii++) | for (ii = 0; ii < Nmaps; ii++) | |||
zfree(maplist[ii]); | zfree(maplist[ii]); | |||
return; | return; | |||
nomapsinstalled: | nomapsinstalled: | |||
zmessageACK(Mwin,"fotoxx file maps are not installed \n" | zmessageACK(Mwin,"fotoxx file maps are not installed \n" | |||
"please use the menu Download Maps"); | "please use the menu Download Maps"); | |||
skipping to change at line 9785 | skipping to change at line 9789 | |||
pp1 = substring(buff,'|',4); | pp1 = substring(buff,'|',4); | |||
if (! pp1) goto baddata; | if (! pp1) goto baddata; | |||
loczoom = atoi(pp1); | loczoom = atoi(pp1); | |||
if (loczoom < 1 || loczoom > 20) goto baddata; | if (loczoom < 1 || loczoom > 20) goto baddata; | |||
netmap_zoomto(loclati,loclongi,loczoom); // set this map location | netmap_zoomto(loclati,loclongi,loczoom); // set this map location | |||
return; | return; | |||
notfound: | notfound: | |||
Plog(1,"net map location not found: %s \n",locname); | Plog(0,"net map location not found: %s \n",locname); | |||
return; | return; | |||
baddata: | baddata: | |||
Plog(1,"net map location invalid: %s %.4f %.4f %d \n", | Plog(0,"net map location invalid: %s %.4f %.4f %d \n", | |||
locname,loclati,loclongi,loczoom); | locname,loclati,loclongi,loczoom); | |||
return; | return; | |||
} | } | |||
/******************************************************************************* * | /******************************************************************************* * | |||
Functions to read and write exif/iptc or other metadata | Functions to read and write exif/iptc or other metadata | |||
******************************************************************************** */ | ******************************************************************************** */ | |||
// get EXIF/IPTC metadata for given image file and EXIF/IPTC key(s) | // get EXIF/IPTC metadata for given image file and EXIF/IPTC key(s) | |||
// returns array of pointers to corresponding key values | // returns array of pointers to corresponding key values | |||
skipping to change at line 9829 | skipping to change at line 9833 | |||
inputs[1] = (char *) "-s2"; | inputs[1] = (char *) "-s2"; | |||
inputs[2] = (char *) "-n"; | inputs[2] = (char *) "-n"; | |||
inputs[3] = (char *) "-fast"; // -fast2 loses maker notes | inputs[3] = (char *) "-fast"; // -fast2 loses maker notes | |||
jj = NP = 4; | jj = NP = 4; | |||
for (ii = 0; ii < nkeys; ii++) // build exiftool inputs | for (ii = 0; ii < nkeys; ii++) // build exiftool inputs | |||
{ | { | |||
cc = strlen(keys[ii]); // -keyname | cc = strlen(keys[ii]); // -keyname | |||
if (! cc) { | if (! cc) { | |||
Plog(1,"exif_get() null key \n"); | Plog(0,"exif_get() null key \n"); | |||
return 1; | return 1; | |||
} | } | |||
inputs[jj] = (char *) zmalloc(cc+2,"exif-get"); | inputs[jj] = (char *) zmalloc(cc+2,"exif-get"); | |||
inputs[jj][0] = '-'; | inputs[jj][0] = '-'; | |||
strcpy(inputs[jj]+1,keys[ii]); | strcpy(inputs[jj]+1,keys[ii]); | |||
jj++; | jj++; | |||
} | } | |||
inputs[jj] = zstrdup(file,"exif-get"); // filename last | inputs[jj] = zstrdup(file,"exif-get"); // filename last | |||
jj++; | jj++; | |||
skipping to change at line 9859 | skipping to change at line 9863 | |||
pp = outputs[ii]; // keyname: keyvalue | pp = outputs[ii]; // keyname: keyvalue | |||
if (! pp) break; // | | | if (! pp) break; // | | | |||
cc = strlen(pp); // pp pp2 | cc = strlen(pp); // pp pp2 | |||
if (cc < 4) { | if (cc < 4) { | |||
zfree(pp); | zfree(pp); | |||
continue; | continue; | |||
} | } | |||
if (utf8_check(pp)) { // detect invalid UTF-8 string | if (utf8_check(pp)) { // detect invalid UTF-8 string | |||
if (strlen(pp) > 80) pp[80] = 0; | if (strlen(pp) > 80) pp[80] = 0; | |||
Plog(1,"invalid UTF-8 metadata: %s \n %s \n",pp,file); | Plog(0,"invalid UTF-8 metadata: %s \n %s \n",pp,file); | |||
zfree(pp); | zfree(pp); | |||
continue; | continue; | |||
} | } | |||
pp2 = strchr(pp,':'); // check ':' delimiter | pp2 = strchr(pp,':'); // check ':' delimiter | |||
if (! pp2 || strlen(pp2) < 2 || strmatchN(pp2,": null",6)) { // check not keyname: null | if (! pp2 || strlen(pp2) < 2 || strmatchN(pp2,": null",6)) { // check not keyname: null | |||
zfree(pp); | zfree(pp); | |||
continue; | continue; | |||
} | } | |||
skipping to change at line 9922 | skipping to change at line 9926 | |||
int exif_put(cchar *file, cchar **keys, cchar **kdata, int nkeys) | int exif_put(cchar *file, cchar **keys, cchar **kdata, int nkeys) | |||
{ | { | |||
int ii, jj, cc, err, NP; | int ii, jj, cc, err, NP; | |||
char *inputs[40]; | char *inputs[40]; | |||
cchar *key1, *kdata1; | cchar *key1, *kdata1; | |||
if (nkeys < 1 || nkeys > 30) zappcrash("exif_put nkeys: %d",nkeys); // higher limit | if (nkeys < 1 || nkeys > 30) zappcrash("exif_put nkeys: %d",nkeys); // higher limit | |||
err = access(file,W_OK); // test file can be written by me | err = access(file,W_OK); // test file can be written by me | |||
if (err) { | if (err) { | |||
Plog(1,"%s: %s \n","no write permission",file); | Plog(0,"%s: %s \n","no write permission",file); | |||
return 1; | return 1; | |||
} | } | |||
inputs[0] = (char *) "-m"; // exiftool options | inputs[0] = (char *) "-m"; // exiftool options | |||
inputs[1] = (char *) "-overwrite_original"; // -P preserve date removed | inputs[1] = (char *) "-overwrite_original"; // -P preserve date removed | |||
jj = NP = 2; | jj = NP = 2; | |||
for (ii = 0; ii < nkeys; ii++) // build exiftool inputs | for (ii = 0; ii < nkeys; ii++) // build exiftool inputs | |||
{ | { | |||
skipping to change at line 9997 | skipping to change at line 10001 | |||
// Replace one call (copy and add data) with two separate calls. | // Replace one call (copy and add data) with two separate calls. | |||
// The one call method did not always work. | // The one call method did not always work. | |||
int exif_copy(cchar *file1, cchar *file2, cchar **keys, cchar **kdata, int nkeys ) | int exif_copy(cchar *file1, cchar *file2, cchar **keys, cchar **kdata, int nkeys ) | |||
{ | { | |||
char *inputs[10]; | char *inputs[10]; | |||
int err; | int err; | |||
err = access(file2,W_OK); // test file can be written by me | err = access(file2,W_OK); // test file can be written by me | |||
if (err) { | if (err) { | |||
Plog(1,"%s: %s \n","no write permission",file2); | Plog(0,"%s: %s \n","no write permission",file2); | |||
return 1; | return 1; | |||
} | } | |||
inputs[0] = (char *) "-m"; // -m (suppress warnings) | inputs[0] = (char *) "-m"; // -m (suppress warnings) | |||
inputs[1] = (char *) "-tagsfromfile"; // -tagsfromfile | inputs[1] = (char *) "-tagsfromfile"; // -tagsfromfile | |||
inputs[2] = zstrdup(file1,"exif-copy"); // file1 | inputs[2] = zstrdup(file1,"exif-copy"); // file1 | |||
inputs[3] = (char *) "-all"; // -all | inputs[3] = (char *) "-all"; // -all | |||
inputs[4] = (char *) "-xmp"; // -xmp | inputs[4] = (char *) "-xmp"; // -xmp | |||
inputs[5] = (char *) "-iptc"; // -iptc | inputs[5] = (char *) "-iptc"; // -iptc | |||
inputs[6] = (char *) "-icc_profile"; // -icc_profile | inputs[6] = (char *) "-icc_profile"; // -icc_profile | |||
skipping to change at line 10066 | skipping to change at line 10070 | |||
gigabytes if Fotoxx image index function processes 100K files or more. | gigabytes if Fotoxx image index function processes 100K files or more. | |||
Solution: exit perl process after 1000 calls and start over with next call. | Solution: exit perl process after 1000 calls and start over with next call. | |||
******************************************************************************** */ | ******************************************************************************** */ | |||
#include <sys/prctl.h> | #include <sys/prctl.h> | |||
namespace exif_server_names | namespace exif_server_names | |||
{ | { | |||
char Nfile[maxNST][200]; // maxNST = compile time limit | char Nfile[maxNST][200]; // maxNST = compile time limit | |||
int fcf1 = 1, fcf2[maxNST], busy[maxNST]; // NST = actual server count | int fcf1 = 1, fcf2[maxNST], busy[maxNST]; // NST = actual metadata server count | |||
FILE *fid1[maxNST], *fid2[maxNST]; | FILE *fid1[maxNST], *fid2[maxNST]; | |||
} | } | |||
int exif_server(int Nrecs, char **inputs, char **outputs) | int exif_server(int Nrecs, char **inputs, char **outputs) | |||
{ | { | |||
using namespace exif_server_names; | using namespace exif_server_names; | |||
int exif_serverN(int ns, int Nrecs, char **inputs, char **outputs); // parallel server processes | int exif_serverN(int ns, int Nrecs, char **inputs, char **outputs); // parallel server processes | |||
double time0, time1; | double time0, time1; | |||
skipping to change at line 10093 | skipping to change at line 10097 | |||
exif_serverN(ii,0,0,0); | exif_serverN(ii,0,0,0); | |||
return 0; | return 0; | |||
} | } | |||
spinlock(1); | spinlock(1); | |||
if (fcf1) // first call | if (fcf1) // first call | |||
{ | { | |||
fcf1 = 0; | fcf1 = 0; | |||
for (ii = 0; ii < NST; ii++) { // exiftool input file per server | for (ii = 0; ii < maxNST; ii++) { // exiftool input file per server 22.35 | |||
snprintf(Nfile[ii],200,"%s/exiftool_input_%d",temp_folder,ii); | snprintf(Nfile[ii],200,"%s/exiftool_input_%d",temp_folder,ii); | |||
busy[ii] = 0; | busy[ii] = 0; | |||
fcf2[ii] = 1; | fcf2[ii] = 1; | |||
fid1[ii] = fid2[ii] = 0; | fid1[ii] = fid2[ii] = 0; | |||
} | } | |||
} | } | |||
spinlock(0); | spinlock(0); | |||
time0 = get_seconds(); | time0 = get_seconds(); | |||
End of changes. 37 change blocks. | ||||
44 lines changed or deleted | 49 lines changed or added |