"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "jhead.c" between
jhead-3.03.tar.gz and jhead-3.04.tar.gz

About: jhead is an Exif Jpeg header and thumbnail manipulation tool.

jhead.c  (jhead-3.03):jhead.c  (jhead-3.04)
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Program to pull the information out of various types of EXIF digital // Program to pull the information out of various types of EXIF digital
// camera files and show it in a reasonably consistent way // camera files and show it in a reasonably consistent way
// //
// Version 3.03 // Version 3.04
// //
// Compiling under Windows: // Compiling under Windows:
// Make sure you have Microsoft's compiler on the path, then run make.bat // Make sure you have Microsoft's compiler on the path, then run make.bat
// //
// Dec 1999 - Dec 2018 // Dec 1999 - Nov 2019
// //
// by Matthias Wandel www.sentex.net/~mwandel // by Matthias Wandel www.sentex.net/~mwandel
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
#ifdef _WIN32 #ifdef _WIN32
#include <io.h> #include <io.h>
#endif #endif
#include "jhead.h" #include "jhead.h"
#include <sys/stat.h> #include <sys/stat.h>
#define JHEAD_VERSION "3.03" #define JHEAD_VERSION "3.04"
// This #define turns on features that are too very specific to // This #define turns on features that are too very specific to
// how I organize my photos. Best to ignore everything inside #ifdef MATTHIAS // how I organize my photos. Best to ignore everything inside #ifdef MATTHIAS
//#define MATTHIAS //#define MATTHIAS
// Bitmasks for DoModify: // Bitmasks for DoModify:
#define MODIFY_ANY 1 #define MODIFY_ANY 1
#define READ_ANY 2 #define READ_ANY 2
#define JPEGS_ONLY 4 #define JPEGS_ONLY 4
#define MODIFY_JPEG 5 #define MODIFY_JPEG 5
skipping to change at line 86 skipping to change at line 86
static char * ThumbInsertName = NULL; // If not NULL, use this string to make up static char * ThumbInsertName = NULL; // If not NULL, use this string to make up
// the filename to retrieve the thumbnail fr om. // the filename to retrieve the thumbnail fr om.
static int RegenThumbnail = FALSE; static int RegenThumbnail = FALSE;
static char * ExifXferScrFile = NULL;// Extract Exif header from this file, and static char * ExifXferScrFile = NULL;// Extract Exif header from this file, and
// put it into the Jpegs processed. // put it into the Jpegs processed.
static int EditComment = FALSE; // Invoke an editor for editing the comment static int EditComment = FALSE; // Invoke an editor for editing the comment
static int SupressNonFatalErrors = FALSE; // Wether or not to pint warnings on r ecoverable errors static int SuppressNonFatalErrors = FALSE; // Wether or not to pint warnings on recoverable errors
static char * CommentSavefileName = NULL; // Save comment to this file. static char * CommentSavefileName = NULL; // Save comment to this file.
static char * CommentInsertfileName = NULL; // Insert comment from this file. static char * CommentInsertfileName = NULL; // Insert comment from this file.
static char * CommentInsertLiteral = NULL; // Insert this comment (from command line) static char * CommentInsertLiteral = NULL; // Insert this comment (from command line)
static int AutoRotate = FALSE; static int AutoRotate = FALSE;
static int ZeroRotateTagOnly = FALSE; static int ZeroRotateTagOnly = FALSE;
static int ShowFileInfo = TRUE; // Indicates to show standard file info static int ShowFileInfo = TRUE; // Indicates to show standard file info
// (file name, file size, file date) // (file name, file size, file date)
skipping to change at line 124 skipping to change at line 124
if (CurrentFile) fprintf(stderr,"in file '%s'\n",CurrentFile); if (CurrentFile) fprintf(stderr,"in file '%s'\n",CurrentFile);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Report non fatal errors. Now that microsoft.net modifies exif headers, // Report non fatal errors. Now that microsoft.net modifies exif headers,
// there's corrupted ones, and there could be more in the future. // there's corrupted ones, and there could be more in the future.
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
void ErrNonfatal(const char * msg, int a1, int a2) void ErrNonfatal(const char * msg, int a1, int a2)
{ {
if (SupressNonFatalErrors) return; if (SuppressNonFatalErrors) return;
fprintf(stderr,"\nNonfatal Error : "); fprintf(stderr,"\nNonfatal Error : ");
if (CurrentFile) fprintf(stderr,"'%s' ",CurrentFile); if (CurrentFile) fprintf(stderr,"'%s' ",CurrentFile);
fprintf(stderr, msg, a1, a2); fprintf(stderr, msg, a1, a2);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Invoke an editor for editing a string. // Invoke an editor for editing a string.
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
skipping to change at line 668 skipping to change at line 668
if (AddLetter){ if (AddLetter){
NameExtra[0] = (char)('a'-1+a); // Try a,b,c,d... for suffix if it ends in a number. NameExtra[0] = (char)('a'-1+a); // Try a,b,c,d... for suffix if it ends in a number.
}else{ }else{
NameExtra[0] = (char)('0'-1+a); // Try 0,1,2,3... for suffix if it ends in a latter. NameExtra[0] = (char)('0'-1+a); // Try 0,1,2,3... for suffix if it ends in a latter.
} }
NameExtra[1] = 0; NameExtra[1] = 0;
}else{ }else{
NameExtra[0] = 0; NameExtra[0] = 0;
} }
sprintf(NewName, "%s%s.jpg", NewBaseName, NameExtra); snprintf(NewName, sizeof(NewName), "%s%s.jpg", NewBaseName, NameExtra);
if (!strcmp(FileName, NewName)) break; // Skip if its already this name. if (!strcmp(FileName, NewName)) break; // Skip if its already this name.
if (!EnsurePathExists(NewBaseName)){ if (!EnsurePathExists(NewBaseName)){
break; break;
} }
if (stat(NewName, &dummy)){ if (stat(NewName, &dummy)){
// This name does not pre-exist. // This name does not pre-exist.
if (rename(FileName, NewName) == 0){ if (rename(FileName, NewName) == 0){
skipping to change at line 763 skipping to change at line 763
// Regenerate the thumbnail using mogrify // Regenerate the thumbnail using mogrify
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
static int RegenerateThumbnail(const char * FileName) static int RegenerateThumbnail(const char * FileName)
{ {
char ThumbnailGenCommand[PATH_MAX*2+50]; char ThumbnailGenCommand[PATH_MAX*2+50];
if (ImageInfo.ThumbnailOffset == 0 || ImageInfo.ThumbnailAtEnd == FALSE){ if (ImageInfo.ThumbnailOffset == 0 || ImageInfo.ThumbnailAtEnd == FALSE){
// There is no thumbnail, or the thumbnail is not at the end. // There is no thumbnail, or the thumbnail is not at the end.
return FALSE; return FALSE;
} }
sprintf(ThumbnailGenCommand, "mogrify -thumbnail %dx%d \"%s\"", sprintf(ThumbnailGenCommand, "mogrify -thumbnail %dx%d -quality 80 \"%s\"",
RegenThumbnail, RegenThumbnail, FileName); RegenThumbnail, RegenThumbnail, FileName);
if (system(ThumbnailGenCommand) == 0){ if (system(ThumbnailGenCommand) == 0){
// Put the thumbnail back in the header // Put the thumbnail back in the header
return ReplaceThumbnail(FileName); return ReplaceThumbnail(FileName);
}else{ }else{
ErrFatal("Unable to run 'mogrify' command"); ErrFatal("Unable to run 'mogrify' command");
return FALSE; return FALSE;
} }
} }
skipping to change at line 1244 skipping to change at line 1244
printf("Error: Time '%s': cannot convert to Unix time\n",ImageInfo.DateTime) ; printf("Error: Time '%s': cannot convert to Unix time\n",ImageInfo.DateTime) ;
DiscardData(); DiscardData();
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// complain about bad state of the command line. // complain about bad state of the command line.
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
static void Usage (void) static void Usage (void)
{ {
printf("Jhead is a program for manipulating settings and thumbnails in Exif jpeg headers\n" printf("Jhead is a program for manipulating settings and thumbnails in Exif jpeg headers\n"
"used by most Digital Cameras. v"JHEAD_VERSION" Matthias Wandel, Dec 31 2018.\n" "used by most Digital Cameras. v"JHEAD_VERSION" Matthias Wandel, Nov 22 2019.\n"
"http://www.sentex.net/~mwandel/jhead\n" "http://www.sentex.net/~mwandel/jhead\n"
"\n"); "\n");
printf("Usage: %s [options] files\n", progname); printf("Usage: %s [options] files\n", progname);
printf("Where:\n" printf("Where:\n"
" files path/filenames with or without wildcards\n" " files path/filenames with or without wildcards\n"
"[options] are:\n" "[options] are:\n"
"\nGENERAL METADATA:\n" "\nGENERAL METADATA:\n"
" -te <name> Transfer exif header from another image file <name>\n" " -te <name> Transfer exif header from another image file <name>\n"
skipping to change at line 1289 skipping to change at line 1289
" is passed to the 'strftime' function for formatting\n" " is passed to the 'strftime' function for formatting\n"
" %%d Day of month %%H Hour (24-hour)\n" " %%d Day of month %%H Hour (24-hour)\n"
" %%m Month number %%M Minute %%S Second\n" " %%m Month number %%M Minute %%S Second\n"
" %%y Year (2 digit 00 - 99) %%Y Year (4 digit 198 0-2036)\n" " %%y Year (2 digit 00 - 99) %%Y Year (4 digit 198 0-2036)\n"
" For more arguments, look up the 'strftime' function.\n" " For more arguments, look up the 'strftime' function.\n"
" In addition to strftime format codes:\n" " In addition to strftime format codes:\n"
" '%%f' as part of the string will include the original f ile name\n" " '%%f' as part of the string will include the original f ile name\n"
" '%%i' will include a sequence number, starting from 1. You can\n" " '%%i' will include a sequence number, starting from 1. You can\n"
" You can specify '%%03i' for example to get leading zero s.\n" " You can specify '%%03i' for example to get leading zero s.\n"
" This feature is useful for ordering files from multiple digicams to\n" " This feature is useful for ordering files from multiple digicams to\n"
" sequence of taking. Only renames files whose names are " sequence of taking.\n"
mostly\n"
" numerical (as assigned by digicam)\n"
" The '.jpg' is automatically added to the end of the nam e. If the\n" " The '.jpg' is automatically added to the end of the nam e. If the\n"
" destination name already exists, a letter or digit is a dded to \n" " destination name already exists, a letter or digit is a dded to \n"
" the end of the name to make it unique.\n" " the end of the name to make it unique.\n"
" The new name may include a path as part of the name. I f this path\n" " The new name may include a path as part of the name. I f this path\n"
" does not exist, it will be created\n" " does not exist, it will be created\n"
" -a (Windows only) Rename files with same name but differen t extension\n" " -a (Windows only) Rename files with same name but differen t extension\n"
" Use together with -n to rename .AVI files from exif in .THM files\n" " Use together with -n to rename .AVI files from exif in .THM files\n"
" for example\n" " for example\n"
" -ta<+|->h[:mm[:ss]]\n" " -ta<+|->h[:mm[:ss]]\n"
" Adjust time by h:mm forwards or backwards. Useful when having\n" " Adjust time by h:mm forwards or backwards. Useful when having\n"
skipping to change at line 1349 skipping to change at line 1348
" -norot Zero out the rotation tag. This to avoid some browsers from\n" " -norot Zero out the rotation tag. This to avoid some browsers from\n"
" rotating the image again after you rotated it but negle cted to\n" " rotating the image again after you rotated it but negle cted to\n"
" clear the rotation tag\n" " clear the rotation tag\n"
"\nOUTPUT VERBOSITY CONTROL:\n" "\nOUTPUT VERBOSITY CONTROL:\n"
" -h help (this text)\n" " -h help (this text)\n"
" -v even more verbose output\n" " -v even more verbose output\n"
" -q Quiet (no messages on success, like Unix)\n" " -q Quiet (no messages on success, like Unix)\n"
" -V Show jhead version\n" " -V Show jhead version\n"
" -exifmap Dump header bytes, annotate. Pipe thru sort for better viewing\n" " -exifmap Dump header bytes, annotate. Pipe thru sort for better viewing\n"
" -se Supress error messages relating to corrupt exif header structure\n" " -se Suppress error messages relating to corrupt exif header structure\n"
" -c concise output\n" " -c concise output\n"
" -nofinfo Don't show file info (name/size/date)\n" " -nofinfo Don't show file info (name/size/date)\n"
"\nFILE MATCHING AND SELECTION:\n" "\nFILE MATCHING AND SELECTION:\n"
" -model model\n" " -model model\n"
" Only process files from digicam containing model substr ing in\n" " Only process files from digicam containing model substr ing in\n"
" camera model description\n" " camera model description\n"
" -exonly Skip all files that don't have an exif header (skip all jpegs that\n" " -exonly Skip all files that don't have an exif header (skip all jpegs that\n"
" were not created by digicam)\n" " were not created by digicam)\n"
" -quality x Only work on images with JPEG quality factor x o r higher\n" " -quality x Only work on images with JPEG quality factor x o r higher\n"
skipping to change at line 1494 skipping to change at line 1493
CreateExifSection = TRUE; CreateExifSection = TRUE;
DoModify |= MODIFY_JPEG; DoModify |= MODIFY_JPEG;
// Output verbosity control // Output verbosity control
}else if (!strcmp(arg,"-h")){ }else if (!strcmp(arg,"-h")){
Usage(); Usage();
}else if (!strcmp(arg,"-v")){ }else if (!strcmp(arg,"-v")){
ShowTags = TRUE; ShowTags = TRUE;
}else if (!strcmp(arg,"-q")){ }else if (!strcmp(arg,"-q")){
Quiet = TRUE; Quiet = TRUE;
}else if (!strcmp(arg,"-V")){ }else if (!strcmp(arg,"-V")){
printf("Jhead version: "JHEAD_VERSION" Compiled: "__DATE__"\n"); printf("Jhead version: "JHEAD_VERSION"\n");
exit(0); exit(0);
}else if (!strcmp(arg,"-exifmap")){ }else if (!strcmp(arg,"-exifmap")){
DumpExifMap = TRUE; DumpExifMap = TRUE;
}else if (!strcmp(arg,"-se")){ }else if (!strcmp(arg,"-se")){
SupressNonFatalErrors = TRUE; SuppressNonFatalErrors = TRUE;
}else if (!strcmp(arg,"-c")){ }else if (!strcmp(arg,"-c")){
ShowConcise = TRUE; ShowConcise = TRUE;
}else if (!strcmp(arg,"-nofinfo")){ }else if (!strcmp(arg,"-nofinfo")){
ShowFileInfo = 0; ShowFileInfo = 0;
// Thumbnail manipulation options // Thumbnail manipulation options
}else if (!strcmp(arg,"-dt")){ }else if (!strcmp(arg,"-dt")){
TrimExif = TRUE; TrimExif = TRUE;
DoModify |= MODIFY_JPEG; DoModify |= MODIFY_JPEG;
}else if (!strcmp(arg,"-st")){ }else if (!strcmp(arg,"-st")){
skipping to change at line 1583 skipping to change at line 1582
DoModify |= MODIFY_JPEG; DoModify |= MODIFY_JPEG;
}else if (!memcmp(arg,"-da",3)){ }else if (!memcmp(arg,"-da",3)){
// Date adjust feature (large time adjustments) // Date adjust feature (large time adjustments)
time_t NewDate, OldDate = 0; time_t NewDate, OldDate = 0;
char * pOldDate; char * pOldDate;
NewDate = ParseCmdDate(arg+3); NewDate = ParseCmdDate(arg+3);
pOldDate = strstr(arg+1, "-"); pOldDate = strstr(arg+1, "-");
if (pOldDate){ if (pOldDate){
OldDate = ParseCmdDate(pOldDate+1); OldDate = ParseCmdDate(pOldDate+1);
}else{ }else{
ErrFatal("Must specifiy second date for -da option"); ErrFatal("Must specify second date for -da option");
} }
if (ExifTimeAdjust) ErrFatal("Can only use one of -da or -ta options at once"); if (ExifTimeAdjust) ErrFatal("Can only use one of -da or -ta options at once");
ExifTimeAdjust = NewDate-OldDate; ExifTimeAdjust = NewDate-OldDate;
DoModify |= MODIFY_JPEG; DoModify |= MODIFY_JPEG;
}else if (!memcmp(arg,"-dsft",5)){ }else if (!memcmp(arg,"-dsft",5)){
// Set exif time to the timestamp of the file. // Set exif time to the timestamp of the file.
FileTimeToExif = TRUE; FileTimeToExif = TRUE;
DoModify |= MODIFY_JPEG; DoModify |= MODIFY_JPEG;
}else if (!memcmp(arg,"-ds",3)){ }else if (!memcmp(arg,"-ds",3)){
// Set date feature // Set date feature
skipping to change at line 1697 skipping to change at line 1696
// used up an extr argument. // used up an extr argument.
ErrFatal("Extra argument required"); ErrFatal("Extra argument required");
} }
} }
if (argn == argc){ if (argn == argc){
ErrFatal("No files to process. Use -h for help"); ErrFatal("No files to process. Use -h for help");
} }
if (ThumbSaveName != NULL && strcmp(ThumbSaveName, "&i") == 0){ if (ThumbSaveName != NULL && strcmp(ThumbSaveName, "&i") == 0){
printf("Error: By specifying \"&i\" for the thumbail name, your original file\n" printf("Error: By specifying \"&i\" for the thumbail name, your original file\n"
" will be overwitten. If this is what you really want,\n" " will be overwritten. If this is what you really want,\n"
" specify -st \"./&i\" to override this check\n"); " specify -st \"./&i\" to override this check\n");
exit(0); exit(0);
} }
if (RegenThumbnail){ if (RegenThumbnail){
if (ThumbSaveName || ThumbInsertName){ if (ThumbSaveName || ThumbInsertName){
printf("Error: Cannot regen and save or insert thumbnail in same run \n"); printf("Error: Cannot regen and save or insert thumbnail in same run \n");
exit(0); exit(0);
} }
} }
 End of changes. 14 change blocks. 
16 lines changed or deleted 14 lines changed or added

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