f.meta.cc (fotoxx-22.41) | : | f.meta.cc (fotoxx-22.50) | ||
---|---|---|---|---|
skipping to change at line 113 | skipping to change at line 113 | |||
netmap_mousefunc respond to clicks on net map | netmap_mousefunc respond to clicks on net map | |||
find_netmap_images find images | find_netmap_images find images | |||
m_netmap_locs save and recall net map locs (center, zoom level) | m_netmap_locs save and recall net map locs (center, zoom level) | |||
EXIF store and retrieve | EXIF store and retrieve | |||
----------------------- | ----------------------- | |||
exif_get get image metadata from list of keys | exif_get get image metadata from list of keys | |||
exif_put update image metadata from list of keys and data | exif_put update image metadata from list of keys and data | |||
exif_copy copy metadata from file to file, with revisions | exif_copy copy metadata from file to file, with revisions | |||
exif_server start exiftool server process, send data requests | exif_server start exiftool server process, send data requests | |||
exif_tagdate yyyy:mm:dd hh:mm:ss to yyyymmddhhmmss | exif_tagdate yyyy-mm-dd hh:mm:ss to yyyymmddhhmmss | |||
tag_exifdate yyyymmddhhmmss to yyyy:mm:dd hh:mm:ss | tag_exifdate yyyymmddhhmmss to yyyy-mm-dd hh:mm:ss | |||
Image index functions | Image index functions | |||
--------------------- | --------------------- | |||
get_xxrec get image index record for image file | get_xxrec get image index record for image file | |||
put_xxrec add or update index record for an image file | put_xxrec add or update index record for an image file | |||
read_xxrec_seq read all index records sequentially, one per call | read_xxrec_seq read all index records sequentially, one per call | |||
write_xxrec_seq write all index records sequentially | write_xxrec_seq write all index records sequentially | |||
******************************************************************************** */ | ******************************************************************************** */ | |||
skipping to change at line 461 | skipping to change at line 461 | |||
if (FGWM != 'F' && FGWM != 'G') return; | if (FGWM != 'F' && FGWM != 'G') return; | |||
if (clicked_file) { // use clicked file if present | if (clicked_file) { // use clicked file if present | |||
file = clicked_file; | file = clicked_file; | |||
clicked_file = 0; | clicked_file = 0; | |||
} | } | |||
else if (curr_file) file = zstrdup(curr_file,"meta-view"); | else if (curr_file) file = zstrdup(curr_file,"meta-view"); | |||
else return; | else return; | |||
if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint | // if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint remove 22.50 | |||
if (metadata_report_type != 1) { | if (metadata_report_type != 1) { | |||
if (zd_metaview) zdialog_free(zd_metaview); | if (zd_metaview) zdialog_free(zd_metaview); | |||
zd_metaview = 0; | zd_metaview = 0; | |||
metadata_report_type = 1; | metadata_report_type = 1; | |||
} | } | |||
if (! zd_metaview) // popup dialog if not already | if (! zd_metaview) // popup dialog if not already | |||
{ | { | |||
zd_metaview = zdialog_new("View Metadata",Mwin,"Extras","Cancel",null); | zd_metaview = zdialog_new("View Metadata",Mwin,"Extras","Cancel",null); | |||
skipping to change at line 498 | skipping to change at line 498 | |||
if (filen) filen++; | if (filen) filen++; | |||
else filen = file; | else filen = file; | |||
fsize = 0; | fsize = 0; | |||
if (keyval[1]) fsize = atoi(keyval[1]); // get file size in B/KB/MB units | if (keyval[1]) fsize = atoi(keyval[1]); // get file size in B/KB/MB units | |||
chsize = formatKBMB(fsize,3); | chsize = formatKBMB(fsize,3); | |||
if (keyval[2] && strlen(keyval[2]) > 19) keyval[2][19] = 0; // truncate dates to yyyy-mm-dd hh:mm:ss | if (keyval[2] && strlen(keyval[2]) > 19) keyval[2][19] = 0; // truncate dates to yyyy-mm-dd hh:mm:ss | |||
if (keyval[3] && strlen(keyval[3]) > 19) keyval[3][19] = 0; | if (keyval[3] && strlen(keyval[3]) > 19) keyval[3][19] = 0; | |||
pp = keyval[2]; | ||||
if (pp && strlen(pp) > 4 && pp[4] == ':') pp[4] = '-'; | ||||
// change yyyy:mm:dd to yyyy-mm-dd | ||||
if (pp && strlen(pp) > 7 && pp[7] == ':') pp[7] = '-'; | ||||
pp = keyval[3]; | ||||
if (pp && strlen(pp) > 4 && pp[4] == ':') pp[4] = '-'; | ||||
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 make: %s model: %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 | |||
skipping to change at line 625 | skipping to change at line 618 | |||
// menu function - metadata long report | // menu function - metadata long report | |||
void m_meta_view_long(GtkWidget *, cchar *menu) | void m_meta_view_long(GtkWidget *, cchar *menu) | |||
{ | { | |||
int meta_view_dialog_event(zdialog *zd, cchar *event); | int meta_view_dialog_event(zdialog *zd, cchar *event); | |||
FILE *fid; | FILE *fid; | |||
char *file, *pp, buff[1000]; | char *file, *pp, buff[1000]; | |||
GtkWidget *widget; | GtkWidget *widget; | |||
cchar *tooloptions = "-s -e "; | cchar *tooloptions = "-s -e -d \"%Y-%m-%d %H:%M:%S\""; // 22.50 | |||
F1_help_topic = "view meta"; | F1_help_topic = "view meta"; | |||
Plog(1,"m_meta_view_long \n"); | Plog(1,"m_meta_view_long \n"); | |||
if (FGWM != 'F' && FGWM != 'G') return; | if (FGWM != 'F' && FGWM != 'G') return; | |||
if (clicked_file) { // use clicked file if present | if (clicked_file) { // use clicked file if present | |||
file = clicked_file; | file = clicked_file; | |||
clicked_file = 0; | clicked_file = 0; | |||
} | } | |||
else if (curr_file) file = zstrdup(curr_file,"meta-view"); | else if (curr_file) file = zstrdup(curr_file,"meta-view"); | |||
else return; | else return; | |||
if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint | // if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint remove 22.50 | |||
if (metadata_report_type != 2) { | if (metadata_report_type != 2) { | |||
if (zd_metaview) zdialog_free(zd_metaview); | if (zd_metaview) zdialog_free(zd_metaview); | |||
zd_metaview = 0; | zd_metaview = 0; | |||
metadata_report_type = 2; | metadata_report_type = 2; | |||
} | } | |||
if (! zd_metaview) // popup dialog if not already | if (! zd_metaview) // popup dialog if not already | |||
{ | { | |||
zd_metaview = zdialog_new("View All Metadata",Mwin,"OK",null); | zd_metaview = zdialog_new("View All Metadata",Mwin,"OK",null); | |||
skipping to change at line 750 | skipping to change at line 743 | |||
} | } | |||
err = access(curr_file,W_OK); // test file can be written by me | err = access(curr_file,W_OK); // test file can be written by me | |||
if (err) { | if (err) { | |||
zmessageACK(Mwin,"%s: %s","no write permission",curr_file); | zmessageACK(Mwin,"%s: %s","no write permission",curr_file); | |||
return; | return; | |||
} | } | |||
init_geolocs(); // initialize geotags | init_geolocs(); // initialize geotags | |||
if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint | // if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint remove 22.50 | |||
/*** | /*** | |||
___________________________________________________________ | ___________________________________________________________ | |||
| Edit Metadata | | | Edit Metadata | | |||
| | | | | | |||
| File: filename.jpg | | | File: filename.jpg | | |||
| Title [________________________________________________] | | | Title [________________________________________________] | | |||
| Description [__________________________________________] | | | Description [__________________________________________] | | |||
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | |||
| Image Date: [__________] Time: [________] [prev] | | | Image Date: [__________] Time: [________] [prev] | | |||
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | |||
| Rating (stars): ⦿ 0 ⦿ 1 ⦿ 2 ⦿ 3 ⦿ 4 ⦿ 5 | | | Rating (stars): ⦿ 0 ⦿ 1 ⦿ 2 ⦿ 3 ⦿ 4 ⦿ 5 | | |||
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | |||
| location [_______________] country [______________] | | | location [_______________] country [______________] | | |||
| latitude [__________] longitude [__________] | | | latitude [__________] longitude [__________] | | |||
| [Find] [Web] [Prev] [Clear] Geocoding by MapQuest | | | [Find] [Web] [Prev] [Clear] Geocoding by MapQuest | | |||
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | |||
| Image Tags [___________________________________________] | | | Image Tags [___________________________________________] | | |||
| Recent Tags [__________________________________________] | | | Recent Tags [__________________________________________] | | |||
| Enter Tag [______________] [Add] | | | Enter Tag [______________] [Add] | | |||
| Matching Tags [________________________________________] | | | Matching Tags [________________________________________] | | |||
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | |||
skipping to change at line 1399 | skipping to change at line 1392 | |||
zd_editanymeta = 0; | zd_editanymeta = 0; | |||
return; | return; | |||
} | } | |||
err = access(curr_file,W_OK); // test file can be written by me | err = access(curr_file,W_OK); // test file can be written by me | |||
if (err) { | if (err) { | |||
zmessageACK(Mwin,"%s: %s","no write permission",curr_file); | zmessageACK(Mwin,"%s: %s","no write permission",curr_file); | |||
return; | return; | |||
} | } | |||
if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint | // if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint remove 22.50 | |||
/*** | /*** | |||
____________________________________________________________________ | ____________________________________________________________________ | |||
| Click to Select | File: filename.jpg | | | Click to Select | File: filename.jpg | | |||
|------------------------------| | | |------------------------------| | | |||
| (metadata list) | key name [________________________] | | | (metadata list) | key name [________________________] | | |||
| | key value [_______________________] | | | | key value [_______________________] | | |||
| | | | | | | | |||
| | [fetch] [update] [delete] | | | | [fetch] [update] [delete] | | |||
| | | | | | | | |||
skipping to change at line 1659 | skipping to change at line 1652 | |||
} | } | |||
if (! curr_file) return; | if (! curr_file) return; | |||
err = access(curr_file,W_OK); // test file can be written by me | err = access(curr_file,W_OK); // test file can be written by me | |||
if (err) { | if (err) { | |||
zmessageACK(Mwin,"%s: %s","no write permission",curr_file); | zmessageACK(Mwin,"%s: %s","no write permission",curr_file); | |||
return; | return; | |||
} | } | |||
if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint | // if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint remove 22.50 | |||
/*** | /*** | |||
_________________________________________ | _________________________________________ | |||
| Delete Metadata | | | Delete Metadata | | |||
| | | | | | |||
| File: [______________________________] | | | File: [______________________________] | | |||
| | | | | | |||
| (o) ALL (o) One Key: [______________] | | | (o) ALL (o) One Key: [______________] | | |||
| | | | | | |||
| [apply] [cancel] | | | [apply] [cancel] | | |||
skipping to change at line 2301 | skipping to change at line 2294 | |||
zmessageACK(Mwin,"%s \n too many tags",file); | zmessageACK(Mwin,"%s \n too many tags",file); | |||
break; | break; | |||
} | } | |||
} | } | |||
save_filemeta(file); // save tag changes | save_filemeta(file); // save tag changes | |||
} | } | |||
popup_report_write2(zd2,0," *** %s \n","COMPLETED"); | popup_report_write2(zd2,0," *** %s \n","COMPLETED"); | |||
if (FGWM == 'G') gallery(0,"paint",-1); // refresh gallery | // if (FGWM == 'G') gallery(0,"paint",-1); // refresh gallery remove 22.50 | |||
load_deftags(1); // update defined tags list | load_deftags(1); // update defined tags list | |||
Fblock("batch_tags",0); | Fblock("batch_tags",0); | |||
return; | return; | |||
} | } | |||
// mouse click functions for widgets holding tags | // mouse click functions for widgets holding tags | |||
void batch_addtags_clickfunc(GtkWidget *widget, int line, int pos, int kbkey) // a tag in the add list was clicked | void batch_addtags_clickfunc(GtkWidget *widget, int line, int pos, int kbkey) // a tag in the add list was clicked | |||
skipping to change at line 2790 | skipping to change at line 2783 | |||
for (ii = 0; ii < Ntags; ii++) { | for (ii = 0; ii < Ntags; ii++) { | |||
zfree(oldtags[ii]); | zfree(oldtags[ii]); | |||
zfree(newtags[ii]); | zfree(newtags[ii]); | |||
} | } | |||
for (ii = 0; ii < Nfiles; ii++) | for (ii = 0; ii < Nfiles; ii++) | |||
zfree(filelist[ii]); | zfree(filelist[ii]); | |||
if (filelist) zfree(filelist); | if (filelist) zfree(filelist); | |||
if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint | // if (FGWM == 'G') gallery(0,"paint",-1); // if gallery view, repaint remove 22.50 | |||
return; | return; | |||
} | } | |||
// a defined tag was clicked | // a defined tag was clicked | |||
void batchrenametags_deftags_clickfunc(GtkWidget *widget, int line, int pos, int kbkey) | void batchrenametags_deftags_clickfunc(GtkWidget *widget, int line, int pos, int kbkey) | |||
{ | { | |||
using namespace batchrenametags; | using namespace batchrenametags; | |||
skipping to change at line 2903 | skipping to change at line 2896 | |||
// batch change or shift photo date/time | // batch change or shift photo date/time | |||
void m_batch_photo_date_time(GtkWidget *, cchar *menu) | void m_batch_photo_date_time(GtkWidget *, cchar *menu) | |||
{ | { | |||
int batch_photo_time_dialog_event(zdialog *zd, cchar *event); | int batch_photo_time_dialog_event(zdialog *zd, cchar *event); | |||
cchar *keyname[1] = { "DateTimeOriginal" }; | cchar *keyname[1] = { "DateTimeOriginal" }; | |||
char *keyvalue[1]; | char *keyvalue[1]; | |||
char text[100]; | char text[100]; | |||
char *file, olddatetime[24], newdatetime[24]; // exif format "yyyy:mm:dd hh:mm:ss" | char *file, olddatetime[24], newdatetime[24]; // exif format "yyyy-mm-dd hh:mm:ss" | |||
int ii, nn, cc, err, zstat; | int ii, nn, cc, err, zstat; | |||
int Fyearonly, Fdateonly; | int Fyearonly, Fdateonly; | |||
int Fsetnew, Fshift, Ftest; // check boxes | int Fsetnew, Fshift, Ftest; // check boxes | |||
time_t timep; | time_t timep; | |||
struct tm DTold, DTnew; // old and new date/time | struct tm DTold, DTnew; // old and new date/time | |||
int s_years, s_mons, s_mdays, s_hours, s_mins, s_secs; // shift amounts | int s_years, s_mons, s_mdays, s_hours, s_mins, s_secs; // shift amounts | |||
zdialog *zd, *zd2; | zdialog *zd, *zd2; | |||
F1_help_topic = "batch photo date"; | F1_help_topic = "batch photo date"; | |||
skipping to change at line 3023 | skipping to change at line 3016 | |||
Fyearonly = Fdateonly = 0; | Fyearonly = Fdateonly = 0; | |||
if (Fsetnew) // input is new date/time | if (Fsetnew) // input is new date/time | |||
{ | { | |||
zdialog_fetch(zd,"newdatetime",newdatetime,24); | zdialog_fetch(zd,"newdatetime",newdatetime,24); | |||
strTrim2(newdatetime); // strip leading and trailing blanks | strTrim2(newdatetime); // strip leading and trailing blanks | |||
cc = strlen(newdatetime); | cc = strlen(newdatetime); | |||
if (cc == 4) { // have only "yyyy" | if (cc == 4) { // have only "yyyy" | |||
strcat(newdatetime,"-01-01 00:00:00"); // append "-01-01 00:00:00" | strcat(newdatetime,"-01-01 00:00:00"); // append "-01-01 00:00:00" 22.50 | |||
Fyearonly = 1; | Fyearonly = 1; | |||
cc = 19; | cc = 19; | |||
} | } | |||
if (cc == 10) { // have only "yyyy-mm-dd" | if (cc == 10) { // have only "yyyy-mm-dd" | |||
strcat(newdatetime," 00:00:00"); // append " 00:00:00" | strcat(newdatetime," 00:00:00"); // append " 00:00:00" | |||
Fdateonly = 1; // flag, change date only | Fdateonly = 1; // flag, change date only | |||
cc = 19; | cc = 19; | |||
} | } | |||
if (cc == 16) { // have only "yyyy-mm-dd hh:mm" | if (cc == 16) { // have only "yyyy-mm-dd hh:mm" | |||
strcat(newdatetime,":00"); // append ":00" | strcat(newdatetime,":00"); // append ":00" | |||
cc = 19; | cc = 19; | |||
} | } | |||
if (cc != 19) { // must have yyyy-mm-dd hh:mm:ss | if (cc != 19) { // must have yyyy-mm-dd hh:mm:ss | |||
zmessageACK(Mwin,"invalid date/time format"); | zmessageACK(Mwin,"invalid date/time format"); | |||
goto retry; | goto retry; | |||
} | } | |||
nn = sscanf(newdatetime,"%d-%d-%d %d:%d:%d", // yyyy-mm-dd hh:mm:ss >> DTnew | nn = sscanf(newdatetime,"%d-%d-%d %d:%d:%d", // yyyy-mm-dd hh:mm:ss >> DTnew 22.50 | |||
&DTnew.tm_year, &DTnew.tm_mon, &DTnew.tm_mday, | &DTnew.tm_year, &DTnew.tm_mon, &DTnew.tm_mday, | |||
&DTnew.tm_hour, &DTnew.tm_min, &DTnew.tm_sec); | &DTnew.tm_hour, &DTnew.tm_min, &DTnew.tm_sec); | |||
DTnew.tm_mon -= 1; // mktime month is 0-11 | DTnew.tm_mon -= 1; // mktime month is 0-11 | |||
if (nn != 6) { // check input format | if (nn != 6) { // check input format | |||
zmessageACK(Mwin,"invalid date/time format"); | zmessageACK(Mwin,"invalid date/time format"); | |||
goto retry; | goto retry; | |||
} | } | |||
timep = mktime(&DTnew); // DTnew >> timep | timep = mktime(&DTnew); // DTnew >> timep | |||
skipping to change at line 3098 | skipping to change at line 3091 | |||
popup_report_write2(zd2,0,"\n"); // report progress | popup_report_write2(zd2,0,"\n"); // report progress | |||
popup_report_write2(zd2,0,"%s \n",file); | popup_report_write2(zd2,0,"%s \n",file); | |||
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) { | |||
popup_report_write2(zd2,0,"%s \n","no write permission"); | popup_report_write2(zd2,0,"%s \n","no write permission"); | |||
continue; | continue; | |||
} | } | |||
exif_get(curr_file,keyname,(char **) keyvalue,1); // metadata >> yyyy:mm:dd hh:mm:ss | exif_get(curr_file,keyname,(char **) keyvalue,1); // metadata >> yyyy-mm-dd hh:mm:ss | |||
if (! keyvalue[0] && Fshift) { // ignore if Fsetnew | if (! keyvalue[0] && Fshift) { // ignore if Fsetnew | |||
popup_report_write2(zd2,0," *** no date/time available \n"); | popup_report_write2(zd2,0," *** no date/time available \n"); | |||
continue; | continue; | |||
} | } | |||
if (keyvalue[0]) { | if (keyvalue[0]) { | |||
strncpy0(olddatetime,keyvalue[0],20); // yyyy:mm:dd hh:mm:ss | strncpy0(olddatetime,keyvalue[0],20); // yyyy-mm-dd hh:mm:ss | |||
zfree(keyvalue[0]); | zfree(keyvalue[0]); | |||
} | } | |||
else strcpy(olddatetime,"0000:01:01 00:00:00"); // missing old date/time | else strcpy(olddatetime,"0000-01-01 00:00:00"); // missing old date/time | |||
nn = sscanf(olddatetime,"%d:%d:%d %d:%d:%d", // yyyy-mm-dd hh:mm:ss >> DTnew | nn = sscanf(olddatetime,"%d-%d-%d %d:%d:%d", // yyyy-mm-dd hh:mm:ss >> DTnew | |||
&DTold.tm_year, &DTold.tm_mon, &DTold.tm_mday, | &DTold.tm_year, &DTold.tm_mon, &DTold.tm_mday, | |||
&DTold.tm_hour, &DTold.tm_min, &DTold.tm_sec); | &DTold.tm_hour, &DTold.tm_min, &DTold.tm_sec); | |||
DTold.tm_mon -= 1; // mktime month is 0-11 | DTold.tm_mon -= 1; // mktime month is 0-11 | |||
if (nn != 6 && Fshift) { | if (nn != 6 && Fshift) { | |||
popup_report_write2(zd2,0," *** EXIF date/time invalid \n"); | popup_report_write2(zd2,0," *** EXIF date/time invalid \n"); | |||
continue; | continue; | |||
} | } | |||
if (nn != 6) strcpy(olddatetime,"0000:01:01 00:00:00"); // missing old date/time | if (nn != 6) strcpy(olddatetime,"0000-01-01 00:00:00"); // missing old date/time | |||
if (Fsetnew) // set new date/time | if (Fsetnew) // set new date/time | |||
{ | { | |||
if (Fyearonly) // change year only, leave rest | if (Fyearonly) // change year only, leave rest | |||
{ | { | |||
DTnew.tm_mon = DTold.tm_mon; // >> revised DTnew | DTnew.tm_mon = DTold.tm_mon; // >> revised DTnew | |||
DTnew.tm_mday = DTold.tm_mday; // set month/day/hour/min/sec only | DTnew.tm_mday = DTold.tm_mday; // set month/day/hour/min/sec only | |||
DTnew.tm_hour = DTold.tm_hour; // year remains fixed | DTnew.tm_hour = DTold.tm_hour; // year remains fixed | |||
DTnew.tm_min = DTold.tm_min; | DTnew.tm_min = DTold.tm_min; | |||
DTnew.tm_sec = DTold.tm_sec; | DTnew.tm_sec = DTold.tm_sec; | |||
skipping to change at line 3159 | skipping to change at line 3152 | |||
} | } | |||
timep = mktime(&DTnew); | timep = mktime(&DTnew); | |||
if (timep < 0) { | if (timep < 0) { | |||
popup_report_write2(zd2,0," %s *** date/time conversion failed \n",old datetime); | popup_report_write2(zd2,0," %s *** date/time conversion failed \n",old datetime); | |||
continue; | continue; | |||
} | } | |||
DTnew = *localtime(&timep); | DTnew = *localtime(&timep); | |||
snprintf(newdatetime,20,"%04d:%02d:%02d %02d:%02d:%02d", // DTnew >> yyyy:mm:dd hh:mm:ss | snprintf(newdatetime,20,"%04d-%02d-%02d %02d:%02d:%02d", // DTnew >> yyyy-mm-dd hh:mm:ss | |||
DTnew.tm_year, DTnew.tm_mon+1, DTnew.tm_mday, // (tm_mon 0-11 >> 1-12) | DTnew.tm_year, DTnew.tm_mon+1, DTnew.tm_mday, // (tm_mon 0-11 >> 1-12) | |||
DTnew.tm_hour, DTnew.tm_min, DTnew.tm_sec); | DTnew.tm_hour, DTnew.tm_min, DTnew.tm_sec); | |||
olddatetime[4] = olddatetime[7] = newdatetime[4] = newdatetime[7] = '-'; // format: yyyy-mm-dd | olddatetime[4] = olddatetime[7] = newdatetime[4] = newdatetime[7] = '-'; // format: yyyy-mm-dd 22.50 | |||
popup_report_write2(zd2,0," %s %s \n",olddatetime,newdatetime); | popup_report_write2(zd2,0," %s %s \n",olddatetime,newdatetime); | |||
if (Ftest) continue; // test only, no file updates | if (Ftest) continue; // test only, no file updates | |||
newdatetime[4] = newdatetime[7] = ':'; // format: yyyy:mm:dd for EXIF | newdatetime[4] = newdatetime[7] = '-'; // format: yyyy-mm-dd for EXIF | |||
keyvalue[0] = (char *) &newdatetime; | keyvalue[0] = (char *) &newdatetime; | |||
err = exif_put(curr_file,keyname,(cchar **) keyvalue,1); // yyyy:mm:dd hh:mm:ss >> metadata | err = exif_put(curr_file,keyname,(cchar **) keyvalue,1); // yyyy-mm-dd hh:mm:ss >> metadata | |||
load_filemeta(curr_file); // get all indexed data for file | load_filemeta(curr_file); // get all indexed data for file | |||
snprintf(meta_pdate,16,"%04d%02d%02d%02d%02d%02d", // update photo date, yyyymmddhhmmss | snprintf(meta_pdate,16,"%04d%02d%02d%02d%02d%02d", // update photo date, yyyymmddhhmmss | |||
DTnew.tm_year, DTnew.tm_mon+1, DTnew.tm_mday, // (tm_mon 0-11 >> 1-12) | DTnew.tm_year, DTnew.tm_mon+1, DTnew.tm_mday, // (tm_mon 0-11 >> 1-12) | |||
DTnew.tm_hour, DTnew.tm_min, DTnew.tm_sec); | DTnew.tm_hour, DTnew.tm_min, DTnew.tm_sec); | |||
update_image_index(curr_file); // update image index rec. | update_image_index(curr_file); // update image index rec. | |||
} | } | |||
popup_report_write2(zd2,0," *** %s \n","COMPLETED"); | popup_report_write2(zd2,0," *** %s \n","COMPLETED"); | |||
Fblock("batch_photo_DT",0); | Fblock("batch_photo_DT",0); | |||
if (FGWM == 'G') gallery(0,"paint",-1); | // if (FGWM == 'G') gallery(0,"paint",-1); // remove 22.50 | |||
m_batch_photo_date_time(0,0); // repeat | m_batch_photo_date_time(0,0); // repeat | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int batch_photo_time_dialog_event(zdialog *zd, cchar *event) | int batch_photo_time_dialog_event(zdialog *zd, cchar *event) | |||
{ | { | |||
char countmess[80]; | char countmess[80]; | |||
skipping to change at line 3420 | skipping to change at line 3413 | |||
zd = 0; | zd = 0; | |||
for (ii = 0; ii < nkeys; ii++) { // free memory | for (ii = 0; ii < nkeys; ii++) { // free memory | |||
zfree((char *) pp1[ii]); | zfree((char *) pp1[ii]); | |||
zfree((char *) pp2[ii]); | zfree((char *) pp2[ii]); | |||
} | } | |||
nkeys = 0; | nkeys = 0; | |||
Fblock("batch_change_meta",0); | Fblock("batch_change_meta",0); | |||
if (FGWM == 'G') gallery(0,"paint",-1); // refresh gallery | // if (FGWM == 'G') gallery(0,"paint",-1); // refresh gallery remove 22.50 | |||
return; | return; | |||
} | } | |||
// dialog event and completion callback function | // dialog event and completion callback function | |||
int batch_change_meta_dialog_event(zdialog *zd, cchar *event) | int batch_change_meta_dialog_event(zdialog *zd, cchar *event) | |||
{ | { | |||
using namespace batchchangemeta; | using namespace batchchangemeta; | |||
char countmess[80]; | char countmess[80]; | |||
skipping to change at line 4015 | skipping to change at line 4008 | |||
} | } | |||
popup_report_write2(zd2,0," *** %s \n","COMPLETED"); | popup_report_write2(zd2,0," *** %s \n","COMPLETED"); | |||
cleanup: | cleanup: | |||
Fblock("batch_geotags",0); | Fblock("batch_geotags",0); | |||
if (zd) zdialog_free(zd); | if (zd) zdialog_free(zd); | |||
zd_mapgeotags = 0; | zd_mapgeotags = 0; | |||
if (FGWM == 'G') gallery(0,"paint",-1); // refresh gallery | // if (FGWM == 'G') gallery(0,"paint",-1); // refresh gallery remove 22.50 | |||
return; | return; | |||
} | } | |||
// batch_geotags dialog event function | // batch_geotags dialog event function | |||
int batch_geotags_dialog_event(zdialog *zd, cchar *event) | int batch_geotags_dialog_event(zdialog *zd, cchar *event) | |||
{ | { | |||
int yn, zstat, err; | int yn, zstat, err; | |||
char countmess[80]; | char countmess[80]; | |||
char location[100], country[100]; | char location[100], country[100]; | |||
skipping to change at line 4387 | skipping to change at line 4380 | |||
for (iig = 0; iig < Ngrec; iig++) | for (iig = 0; iig < Ngrec; iig++) | |||
{ | { | |||
utf8substring(country,grec[iig].country,0,26); // get graphic cc for UTF-8 names | utf8substring(country,grec[iig].country,0,26); // get graphic cc for UTF-8 names | |||
cc1 = 26 + strlen(country) - utf8len(country); | cc1 = 26 + strlen(country) - utf8len(country); | |||
utf8substring(location,grec[iig].location,0,26); | utf8substring(location,grec[iig].location,0,26); | |||
cc2 = 26 + strlen(location) - utf8len(location); | cc2 = 26 + strlen(location) - utf8len(location); | |||
strncpy0(pdate,grec[iig].pdate,9); // date, yyyymmdd | strncpy0(pdate,grec[iig].pdate,9); // date, yyyymmdd | |||
if (! strmatch(pdate,"null")) { | if (! strmatch(pdate,"null")) { | |||
memmove(pdate+8,pdate+6,2); // convert to yyyy-mm-dd | memmove(pdate+8,pdate+6,2); // convert to yyyy-mm-dd 22.50 | |||
memmove(pdate+5,pdate+4,2); | memmove(pdate+5,pdate+4,2); | |||
pdate[4] = pdate[7] = '-'; | pdate[4] = pdate[7] = '-'; | |||
pdate[10] = 0; | pdate[10] = 0; | |||
} | } | |||
popup_report_write2(zd2,0,"%-*s %-*s %-10s %6d \n", | popup_report_write2(zd2,0,"%-*s %-*s %-10s %6d \n", | |||
cc1,country,cc2,location,pdate,grec[iig].count); | cc1,country,cc2,location,pdate,grec[iig].count); | |||
} | } | |||
} | } | |||
skipping to change at line 4414 | skipping to change at line 4407 | |||
for (iig = 0; iig < Ngrec; iig++) | for (iig = 0; iig < Ngrec; iig++) | |||
{ | { | |||
utf8substring(country,grec[iig].country,0,26); // get graphic cc for UTF-8 names | utf8substring(country,grec[iig].country,0,26); // get graphic cc for UTF-8 names | |||
cc1 = 26 + strlen(country) - utf8len(country); | cc1 = 26 + strlen(country) - utf8len(country); | |||
utf8substring(location,grec[iig].location,0,26); | utf8substring(location,grec[iig].location,0,26); | |||
cc2 = 26 + strlen(location) - utf8len(location); | cc2 = 26 + strlen(location) - utf8len(location); | |||
strncpy0(pdate,grec[iig].pdate,9); // date, yyyymmdd | strncpy0(pdate,grec[iig].pdate,9); // date, yyyymmdd | |||
if (! strmatch(pdate,"null")) { | if (! strmatch(pdate,"null")) { | |||
memmove(pdate+8,pdate+6,2); // convert to yyyy-mm-dd | memmove(pdate+8,pdate+6,2); // convert to yyyy-mm-dd 22.50 | |||
memmove(pdate+5,pdate+4,2); | memmove(pdate+5,pdate+4,2); | |||
pdate[4] = pdate[7] = '-'; | pdate[4] = pdate[7] = '-'; | |||
pdate[10] = 0; | pdate[10] = 0; | |||
} | } | |||
popup_report_write2(zd2,0,"%-10s %-*s %-*s %6d \n", | popup_report_write2(zd2,0,"%-10s %-*s %-*s %6d \n", | |||
pdate,cc1,country,cc2,location,grec[iig].count); | pdate,cc1,country,cc2,location,grec[iig].count); | |||
} | } | |||
} | } | |||
skipping to change at line 4810 | skipping to change at line 4803 | |||
using namespace timeline_names; | using namespace timeline_names; | |||
int ii, jj, cc; | int ii, jj, cc; | |||
int Fnull = 0, Finvalid = 0; | int Fnull = 0, Finvalid = 0; | |||
int yy, mm; | int yy, mm; | |||
static int pline, ppos; | static int pline, ppos; | |||
char *txline, pdate[8], *pp, end; | char *txline, pdate[8], *pp, end; | |||
char albumfile[200]; | char albumfile[200]; | |||
FILE *fid; | FILE *fid; | |||
xxrec_t *xxrec; | xxrec_t *xxrec; | |||
static int busy = 0; | ||||
if (busy) return; | ||||
// stop re-entry 22.50 | ||||
busy++; | ||||
if (kbkey == GDK_KEY_F1) { // key F1 pressed, show help | if (kbkey == GDK_KEY_F1) { // key F1 pressed, show help | |||
showz_docfile(Mwin,"userguide",F1_help_topic); | showz_docfile(Mwin,"userguide",F1_help_topic); | |||
return; | goto retx; | |||
} | } | |||
if (line == -1) // arrow key navigation | if (line == -1) // arrow key navigation | |||
{ | { | |||
for (ii = 0; ii < 14; ii++) // current report column | for (ii = 0; ii < 14; ii++) // current report column | |||
if (ppos == colpos[ii]) break; | if (ppos == colpos[ii]) break; | |||
if (kbkey == GDK_KEY_Left) { // prior month | if (kbkey == GDK_KEY_Left) { // prior month | |||
if (ii > 2) ppos = colpos[ii-1]; | if (ii > 2) ppos = colpos[ii-1]; | |||
else { | else { | |||
skipping to change at line 4861 | skipping to change at line 4858 | |||
textwidget_scroll(widget,line); // keep line on screen | textwidget_scroll(widget,line); // keep line on screen | |||
pline = line; // remember chosen line, position | pline = line; // remember chosen line, position | |||
ppos = pos; | ppos = pos; | |||
pp = textwidget_word(widget,line,pos," ",end); // hilite clicked word | pp = textwidget_word(widget,line,pos," ",end); // hilite clicked word | |||
if (pp) textwidget_highlight_word(widget,line,pos,strlen(pp)); | if (pp) textwidget_highlight_word(widget,line,pos,strlen(pp)); | |||
txline = textwidget_line(widget,line,1); // get clicked line | txline = textwidget_line(widget,line,1); // get clicked line | |||
if (! txline || ! *txline) return; | if (! txline || ! *txline) goto retx; | |||
cc = 0; | cc = 0; | |||
if (strmatchN(txline,"null",4)) Fnull = 1; // find images with null date | if (strmatchN(txline,"null",4)) Fnull = 1; // find images with null date | |||
else if (strmatchN(txline,"invalid",7)) Finvalid = 1; // find images with invalid date | else if (strmatchN(txline,"invalid",7)) Finvalid = 1; // find images with invalid date | |||
else if (pos < 13) { // clicked on year or year count | else if (pos < 13) { // clicked on year or year count | |||
strncpy0(pdate,txline,5); // have "yyyy" | strncpy0(pdate,txline,5); // have "yyyy" | |||
cc = 4; | cc = 4; | |||
} | } | |||
else // month was clicked | else // month was clicked | |||
{ | { | |||
mm = (pos - 13) / 5 + 1; // month, 1-12 | mm = (pos - 13) / 5 + 1; // month, 1-12 | |||
if (mm < 1 || mm > 12) return; | if (mm < 1 || mm > 12) goto retx; | |||
strncpy(pdate,txline,4); // "yyyy" | strncpy(pdate,txline,4); // "yyyy" | |||
pdate[4] = '0' + mm/10; | pdate[4] = '0' + mm/10; | |||
pdate[5] = '0' + mm % 10; // have "yyyymm" | pdate[5] = '0' + mm % 10; // have "yyyymm" | |||
pdate[6] = 0; | pdate[6] = 0; | |||
cc = 6; | cc = 6; | |||
} | } | |||
snprintf(albumfile,200,"%s/timeline",albums_folder); | snprintf(albumfile,200,"%s/timeline",albums_folder); | |||
fid = fopen(albumfile,"w"); // open output file | fid = fopen(albumfile,"w"); // open output file | |||
if (! fid) { | if (! fid) { | |||
zmessageACK(Mwin,"file error: %s",strerror(errno)); | zmessageACK(Mwin,"file error: %s",strerror(errno)); | |||
return; | goto retx; | |||
} | } | |||
if (Fblock("timeline","block edits")) return; | ||||
// check pending, block | ||||
if (Fusesearch) // include prior search results | if (Fusesearch) // include prior search results | |||
{ | { | |||
for (ii = 0; ii < Nsearch; ii++) | for (ii = 0; ii < Nsearch; ii++) | |||
{ | { | |||
zmainloop(100); // keep GTK alive | zmainloop(100); // keep GTK alive | |||
xxrec = get_xxrec(zlist_get(filelist,ii)); | xxrec = get_xxrec(zlist_get(filelist,ii)); | |||
if (! xxrec) continue; | if (! xxrec) continue; | |||
if (Fnull) { // search for missing dates | if (Fnull) { // search for missing dates | |||
skipping to change at line 4975 | skipping to change at line 4970 | |||
yy = jj / 100; // 0 to 2099 | yy = jj / 100; // 0 to 2099 | |||
mm = jj - yy * 100; // 1 to 12 | mm = jj - yy * 100; // 1 to 12 | |||
if (yy < 0 || yy >= Nyears || mm < 1 || mm > 12) continue; // invalid, reject | if (yy < 0 || yy >= Nyears || mm < 1 || mm > 12) continue; // invalid, reject | |||
fprintf(fid,"%s\n",xxrec->file); // output matching file | fprintf(fid,"%s\n",xxrec->file); // output matching file | |||
} | } | |||
} | } | |||
} | } | |||
fclose(fid); | fclose(fid); | |||
Fblock("timeline",0); | ||||
navi::gallerytype = SEARCH; // search results | navi::gallerytype = SEARCH; // search results | |||
gallery(albumfile,"initF",0); // generate gallery of matching files | gallery(albumfile,"initF",0); // generate gallery of matching files | |||
gallery(0,"paint",0); | gallery(0,"paint",0); | |||
m_viewmode(0,"G"); | m_viewmode(0,"G"); | |||
retx: | ||||
busy = 0; | ||||
return; | return; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// Search image tags, geotags, dates, ratings, titles, descriptions | // Search image tags, geotags, dates, ratings, titles, descriptions | |||
// to find matching images. This is fast using the image index. | // to find matching images. This is fast using the image index. | |||
// Search also any other metadata, but relatively slow. | // Search also any other metadata, but relatively slow. | |||
namespace search_images | namespace search_images | |||
skipping to change at line 5371 | skipping to change at line 5368 | |||
// search images dialog event and completion callback function | // search images dialog event and completion callback function | |||
int searchimages_dialog_event(zdialog *zd, cchar *event) | int searchimages_dialog_event(zdialog *zd, cchar *event) | |||
{ | { | |||
int datetimeOK(char *datetime); | int datetimeOK(char *datetime); | |||
int searchimages_metadata_dialog(zdialog *zd); | int searchimages_metadata_dialog(zdialog *zd); | |||
int searchimages_metadata_report(void); | int searchimages_metadata_report(void); | |||
void *searchimages_thread(void *); | void *searchimages_thread(void *); | |||
cchar dateLoDefault[20] = "0000-01-01 00:00:00"; // start of time | cchar dateLoDefault[20] = "0000-01-01 00:00:00"; // start of time 22.50 | |||
cchar dateHiDefault[20] = "2099-12-31 23:59:59"; // end of time | cchar dateHiDefault[20] = "2099-12-31 23:59:59"; // end of time | |||
char *file, *file2, **vlist; | char *file, *file2, **vlist; | |||
char **flist, *pp, buffer[XFCC]; | char **flist, *pp, buffer[XFCC]; | |||
char mm[4] = "mm"; | char mm[4] = "mm"; | |||
int ii, jj, kk, err, cc; | int ii, jj, kk, err, cc; | |||
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]; | |||
skipping to change at line 5598 | skipping to change at line 5595 | |||
Fnulldate = 1; // (user input "null") | Fnulldate = 1; // (user input "null") | |||
Fdates = Ffiledate = Fphotodate = 0; | Fdates = Ffiledate = Fphotodate = 0; | |||
zdialog_stuff(zd,"photodate",1); | zdialog_stuff(zd,"photodate",1); | |||
zdialog_stuff(zd,"filedate",0); | zdialog_stuff(zd,"filedate",0); | |||
} | } | |||
if (Fdates) // complete partial date/time data | if (Fdates) // complete partial date/time data | |||
{ | { | |||
cc = strlen(searchDateFrom); | cc = strlen(searchDateFrom); | |||
for (ii = cc; ii < 20; ii++) // default date from: | for (ii = cc; ii < 20; ii++) // default date from: | |||
searchDateFrom[ii] = dateLoDefault[ii]; // 0000-01-01 00:00:00 | searchDateFrom[ii] = dateLoDefault[ii]; // 0000-01-01 00:00:00 22.50 | |||
cc = strlen(searchDateTo); | cc = strlen(searchDateTo); | |||
for (ii = cc; ii < 20; ii++) // default date to: | for (ii = cc; ii < 20; ii++) // default date to: | |||
searchDateTo[ii] = dateHiDefault[ii]; // 2099-12-31 23:59:59 | searchDateTo[ii] = dateHiDefault[ii]; // 2099-12-31 23:59:59 22.50 | |||
if (cc == 7) { // input was yyyy-mm | if (cc == 7) { // input was yyyy-mm | |||
strncpy(mm,searchDateTo+5,2); // get mm = "01" .. "12" | strncpy(mm,searchDateTo+5,2); // get mm = "01" .. "12" | |||
if (strstr("04 06 09 11",mm)) memmove(searchDateTo+8,"30",2); // set dd = 30 for these months | if (strstr("04 06 09 11",mm)) memmove(searchDateTo+8,"30",2); // set dd = 30 for these months | |||
if (strmatch(mm,"02")) { | if (strmatch(mm,"02")) { | |||
memmove(searchDateTo+8,"28",2); // set dd = 28 for month 02 | memmove(searchDateTo+8,"28",2); // set dd = 28 for month 02 | |||
ii = atoi(searchDateTo); | ii = atoi(searchDateTo); | |||
if (ii == (ii/4)*4) memmove(searchDateTo+8,"29",2); // set dd = 29 if leap year | if (ii == (ii/4)*4) memmove(searchDateTo+8,"29",2); // set dd = 29 if leap year | |||
} | } | |||
} | } | |||
skipping to change at line 6867 | skipping to change at line 6864 | |||
// convert yyyy-mm-dd hh:mm[:ss] to yyyymmddhhmmss | // convert yyyy-mm-dd hh:mm[:ss] to yyyymmddhhmmss | |||
char * pdatetime_metadatetime(cchar *pdatetime) | char * pdatetime_metadatetime(cchar *pdatetime) | |||
{ | { | |||
char pdate[12], ptime[12]; | char pdate[12], ptime[12]; | |||
static char metadatetime[20]; | static char metadatetime[20]; | |||
char *pp; | char *pp; | |||
int cc; | int cc; | |||
strncpy0(pdate,pdatetime,11); // yyyy-mm-dd | strncpy0(pdate,pdatetime,11); // yyyy:mm:dd | |||
strncpy0(ptime,pdatetime+11,9); // hh:mm[:ss] | strncpy0(ptime,pdatetime+11,9); // hh:mm[:ss] | |||
cc = strlen(ptime); | cc = strlen(ptime); | |||
if (cc == 5) strcat(ptime,":00"); // hh:mm >> hh:mm:00 | if (cc == 5) strcat(ptime,":00"); // hh:mm >> hh:mm:00 | |||
else if (cc != 8) return 0; | else if (cc != 8) return 0; | |||
pp = pdate_metadate(pdate); | pp = pdate_metadate(pdate); | |||
if (! pp) return 0; | if (! pp) return 0; | |||
strncpy0(metadatetime,pp,9); | strncpy0(metadatetime,pp,9); | |||
skipping to change at line 9856 | skipping to change at line 9853 | |||
// 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 | |||
// if a key is missing, corresponding pointer is null | // if a key is missing, corresponding pointer is null | |||
// returned strings belong to caller, are subject for zfree() | // returned strings belong to caller, are subject for zfree() | |||
// up to 100 keynames may be requested per call | // up to 100 keynames may be requested per call | |||
// returns: 0 = OK, +N = error | // returns: 0 = OK, +N = error | |||
int exif_get(cchar *file, cchar **keys, char **kdata, int nkeys) | int exif_get(cchar *file, cchar **keys, char **kdata, int nkeys) | |||
{ | { | |||
char *pp, *pp2, geostring[20]; | char *pp, *pp2, *pp3, geostring[20]; | |||
char *inputs[120], *outputs[100]; // higher limits | char *inputs[120], *outputs[100]; // higher limits | |||
int ii, jj, err, NP; | int ii, jj, err, NP; | |||
float geofloat; | float geofloat; | |||
uint cc, ucc; | uint cc, ucc; | |||
if (nkeys < 1 || nkeys > 99) zappcrash("exif_get nkeys: %d",nkeys); | if (nkeys < 1 || nkeys > 99) zappcrash("exif_get nkeys: %d",nkeys); | |||
cc = nkeys * sizeof(char *); // initz. outputs = null | cc = nkeys * sizeof(char *); // initz. outputs = null | |||
memset(kdata,0,cc); | memset(kdata,0,cc); | |||
inputs[0] = (char *) "-m"; | inputs[0] = (char *) "-m"; | |||
// options for exiftool | // ignore minor errors | |||
inputs[1] = (char *) "-s2"; | inputs[1] = (char *) "-s2"; | |||
inputs[2] = (char *) "-n"; | // get tag names not descriptions | |||
inputs[3] = (char *) "-fast"; | inputs[2] = (char *) "-n"; | |||
// -fast2 loses maker notes | // get native values not human-readable | |||
inputs[3] = (char *) "-fast"; | ||||
// speedup (-fast2 loses maker notes) | ||||
///inputs[6] = (char *) "-q"; | ||||
// -quiet causes exiftool hangup 22.50 | ||||
///inputs[4] = (char *) "-d"; | ||||
// date format DOES NOT WORK 22.50 | ||||
///inputs[5] = (char *) "%Y-%m-%d %H:%M:%S"; | ||||
// yyyy-mm-dd hh:mm:ss 22.50 | ||||
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(0,"exif_get() null key \n"); | Plog(0,"exif_get() null key \n"); | |||
return 1; | return 1; | |||
} | } | |||
skipping to change at line 9921 | skipping to change at line 9921 | |||
} | } | |||
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; | |||
} | } | |||
pp2 += 2; // key value | pp2 += 2; // key value | |||
if (strstr(pp,"Date")) { | ||||
// if Date or Date-Time value 22.50 | ||||
pp3 = strchr(pp2,':'); | ||||
// fix yyyy:mm:dd --> yyyy-mm-dd | ||||
if (pp3 && *pp3 == ':' && strlen(pp3) > 2 && *(pp3+3) == ':') | ||||
// ...Date... yyyy:mm:dd | ||||
*pp3 = *(pp3+3) = '-'; | ||||
// | | | ||||
} | ||||
// pp3 +3 | ||||
for (jj = 0; jj < nkeys; jj++) // loop exif_server inputs | for (jj = 0; jj < nkeys; jj++) // loop exif_server inputs | |||
{ | { | |||
if (strmatchN(keys[jj],"GPSLatitude",11)) { // round to 5 decimal places | if (strmatchN(keys[jj],"GPSLatitude",11)) { // round to 5 decimal places | |||
if (! strmatchN(pp,"GPSLatitude",11)) continue; | if (! strmatchN(pp,"GPSLatitude",11)) continue; | |||
err = convSF(pp2,geofloat); | err = convSF(pp2,geofloat); | |||
if (err > 1) continue; | if (err > 1) continue; | |||
snprintf(geostring,20,"%.5f",geofloat); | snprintf(geostring,20,"%.5f",geofloat); | |||
kdata[jj] = zstrdup(geostring,"exif-get"); // return key data | kdata[jj] = zstrdup(geostring,"exif-get"); // return key data | |||
} | } | |||
else if (strmatchN(keys[jj],"GPSLongitude",12)) { // round to 5 decimal places | else if (strmatchN(keys[jj],"GPSLongitude",12)) { // round to 5 decimal places | |||
skipping to change at line 10247 | skipping to change at line 10253 | |||
if (outputs && ii < Nrecs) | if (outputs && ii < Nrecs) | |||
outputs[ii] = zstrdup(outrec,"exif-server"); // add to returned records | outputs[ii] = zstrdup(outrec,"exif-server"); // add to returned records | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
/******************************************************************************* */ | /******************************************************************************* */ | |||
// convert between EXIF and fotoxx tag date formats | // convert between EXIF and fotoxx tag date formats | |||
// EXIF date: yyyy:mm:dd hh:mm:ss 20 chars. | // EXIF date: yyyy-mm-dd hh:mm:ss 20 chars. | |||
// tag date: yyyymmddhhmmss 16 chars. | // tag date: yyyymmddhhmmss 16 chars. | |||
// | // | |||
void exif_tagdate(cchar *exifdate, char *tagdate) | void exif_tagdate(cchar *exifdate, char *tagdate) | |||
{ | { | |||
int cc; | int cc; | |||
memset(tagdate,0,15); | memset(tagdate,0,15); | |||
cc = strlen(exifdate); | cc = strlen(exifdate); | |||
skipping to change at line 10275 | skipping to change at line 10281 | |||
return; | return; | |||
} | } | |||
void tag_exifdate(cchar *tagdate, char *exifdate) | void tag_exifdate(cchar *tagdate, char *exifdate) | |||
{ | { | |||
int cc; | int cc; | |||
memset(exifdate,0,20); | memset(exifdate,0,20); | |||
cc = strlen(tagdate); | cc = strlen(tagdate); | |||
strcpy(exifdate,"1900:01:01 00:00:00"); | strcpy(exifdate,"1900-01-01 00:00:00"); | |||
if (cc > 3) strncpy(exifdate+0,tagdate+0,4); | if (cc > 3) strncpy(exifdate+0,tagdate+0,4); | |||
if (cc > 5) strncpy(exifdate+5,tagdate+4,2); | if (cc > 5) strncpy(exifdate+5,tagdate+4,2); | |||
if (cc > 7) strncpy(exifdate+8,tagdate+6,2); | if (cc > 7) strncpy(exifdate+8,tagdate+6,2); | |||
if (cc > 9) strncpy(exifdate+11,tagdate+8,2); | if (cc > 9) strncpy(exifdate+11,tagdate+8,2); | |||
if (cc > 11) strncpy(exifdate+14,tagdate+10,2); | if (cc > 11) strncpy(exifdate+14,tagdate+10,2); | |||
if (cc > 13) strncpy(exifdate+17,tagdate+12,2); | if (cc > 13) strncpy(exifdate+17,tagdate+12,2); | |||
exifdate[19] = 0; | exifdate[19] = 0; | |||
return; | return; | |||
} | } | |||
End of changes. 45 change blocks. | ||||
57 lines changed or deleted | 72 lines changed or added |